1

I have an Ansible encrypted variable. Now I'd like to be able to run my playbook even when I don't unlock the variable (with --ask-vault-pass) and just skip the tasks that depend on it. Ideally with a warning saying that the task was skipped.

Now when I run my playbook without --ask-vault-pass, it fails with an error:

fatal: [...]: FAILED! => {"changed": false, "msg": "AnsibleError: An unhandled exception occurred while templating '{{ (samba_passwords | string | from_yaml)[samba_username] }}'. Error was a <class 'ansible.parsing.vault.AnsibleVaultError'>, original message: Attempting to decrypt bu t no vault secrets found"}

Is there a way how to check in the when: clause that an encrypted variable is not decrypted and thus inaccessible?

Petr
  • 62,528
  • 13
  • 153
  • 317
  • a competing theory to gary lopez's approach is to ensure that all ansible-vault variables are decrypted _at play start_, so it fails fast; [the fine manual](https://docs.ansible.com/ansible/2.10/user_guide/playbooks_best_practices.html#tip-for-variables-and-vaults) even says as much – mdaniel Oct 24 '20 at 18:54

2 Answers2

3

Q: "Check if an encrypted variable is decrypted. Skip the tasks that depend on it. Ideally with a warning saying that the task was skipped."

A: For example, given the file with the variable

shell> cat vars-test.yml
test_var1: test var1

Encrypt the file

shell> ansible-vault encrypt vars-test.yml
New Vault password: 
Confirm New Vault password: 
Encryption successful

shell> cat vars-test.yml
$ANSIBLE_VAULT;1.1;AES256
61373230346437306135303463393166323063656561623863306333313837666561653466393835
3738666532303836376139613766343930346263633032330a323336643061373039613330653237
30666364376266396633613162626536383161306262613062373239343232663935376364383431
6335623366613834360a336531656537626662376166323766376433653232633139383636613963
64356632633863353534323636313231633866613635343962383463636565303032

Then the playbook

shell> cat pb.yml
- hosts: test_01
  tasks:
    - include_vars: vars-test.yml
      ignore_errors: true
    - set_fact:
        test_var1: "{{ test_var1|default('default') }}"
    - name: Execute tasks if test_var1 was decrypted
      block:
        - debug:
            msg: Execute task1
        - debug:
            msg: Execute task2
      when: test_var1 != 'default'

gives (abridged)

shell> ansible-playbook pb.yml --ask-vault-pass

TASK [include_vars] ****
ok: [test_01]

TASK [set_fact] ****
ok: [test_01]

TASK [debug] ****
ok: [test_01] => 
  msg: Execute task1

TASK [debug] ****
ok: [test_01] => 
  msg: Execute task2

If you don't provide the command with the password the playbook gives (abridged)

shell> ansible-playbook pb.yml

PLAY [test_01] ****

TASK [include_vars] ****
fatal: [test_01]: FAILED! => changed=false 
  ansible_facts: {}
  ansible_included_var_files: []
  message: Attempting to decrypt but no vault secrets found
...ignoring

TASK [set_fact] ****
ok: [test_01]

TASK [debug] ****
skipping: [test_01]

TASK [debug] ****
skipping: [test_01]
Vladimir Botka
  • 58,131
  • 4
  • 32
  • 63
1

I've researched but I haven't found anything to do that. The easy way to solve this case would be used ignore_errors: yes in the task.

gary lopez
  • 1,823
  • 7
  • 15