ASAs and Ansible: Secure secrets with Ansible Vault

The Ansible scripts I have written so far to update Pingdom IPs and update Palo Alto GPCS IPs have worked fine, certainly as intended, but would fall foul of a PCI auditor. So it is time to hide away the secrets in a vault.

Ansible Vault setup

To set up our secrets file in Ansible vault, I start by making a back up of it (just in case), then we use the ansible-vault command:

cp secrets.yml vault_secrets.yml 
ansible-vault encrypt vault_secrets.yml

We have to enter a password twice.

As the scripts will probably be run automatically, I don’t want to have to put my password in all the time, so we create a .vault-pass file containing the password, which we then chmod to 600, so it’s only readable by the account being used.

echo "my_password_goes_here" > .vault_pass
chmod 600 .vault_pass

Finally, if we are running GIT on the box, we want to exclude this file from being versioned.

echo ‘.vault_pass’ >> .gitignore

Remember to delete the original secrets.yml file!

If we look at the contents of the vault_secrets.yml file, we can see that it is encrypted:

ansible@ansible ~/playbooks$ cat vault_secrets.yml 
ansible@ansible ~/playbooks$ 

Here is what it looks like, step by step:

Ansible Vault secrets
To use the vault_pass file, we need to pass it in the playbook command, using the option of “–vault-password-file=”, and specifying the filename:

ansible-playbook test-asa.yml -i hosts  --vault-password-file=.vault_pass

In the playbook, we use the “include_vars” command to call up the vault_secrets.yml file.

 cat test-asa.yml
- hosts: Cisco_ASAs
  connection: local

   - name: GET CREDS
     include_vars: vault_secrets.yml
           authorize: yes
           host: "{{ inventory_hostname }}"
           username: "{{ creds['username'] }}"
           password: "{{ creds['password'] }}"
           auth_pass: "{{ creds['auth_pass'] }}"
           timeout: 30
   - name: GET VERSION
        provider: "{{ connection }}"
          - show version
     register: result

   - debug: var=result

If we try to run the same playbook, without specifying vault password file, then we get an error:

ansible@ansible ~$ ansible-playbook test-asa.yml -i hosts
PLAY [Cisco_ASAs] *****************************************************************************************************************************************************

TASK [Gathering Facts] ************************************************************************************************************************************************
ok: []

TASK [GET CREDS] ******************************************************************************************************************************************************
fatal: []: FAILED! => {"ansible_facts": {}, "ansible_included_var_files": [], "changed": false, "message": "Attempting to decrypt but no vault secrets found"}
        to retry, use: --limit @/home/ansible/test-asa.retry

PLAY RECAP ************************************************************************************************************************************************************              : ok=1    changed=0    unreachable=0    failed=1

ansible@ansible ~$

Now that our passwords are nicely secured away in the vault, the auditors will be happy and the environment much safer!

The cool thing about ansible-vault is that you can cherry-pick what you want to encrypt, so you can have encrypted and non-encrypted string in the same file.

You can read more here and here.


  1. Peter July 8, 2018