Ansible Vault Usage

Ansible Vault is a feature of ansible that allows you to keep sensitive data such as passwords in encrypted files, rather then as plaintext in playbooks.
A command line tool, ansible-vault, allows you to edit files. With command line flags you can pass in the ansible vault password or the password file. You can specify the location of the password file in the ansible.cfg file.

Ansbile Vault can encrypt andy structured data file used by Ansible. This includes group_vars or host_vars inventory variables. Any variables loaded by include_vars, vars_files or files passed in by the ansible-playbook command line (-e @myfile.yml).

Best practice is to start with the groups_vars subdirectory named after the group. Inside the subdirectory, create two files named vars and vault.  Inside vars file, define all variables needed, including the sensitive ones.  Copy all the sensitive variables over to the vault file and prefix these variables with vault_.  Adjust the variables in the vars file to point to the matching vault_ variables using jinja2 syntax, and enure the vault file is encrypted.

Directory setup

Notice the vars.yml and the vault.yml are under the directory of the web group.

└── install
├── ansible.cfg
├── ansible.log
├── group_vars
│   └── web
│       ├── vars.yml
│       └── vault.yml
├── host_vars
├── inventory
└── users.yml

Inventory file – install/inventory



Vars file – install/group_vars/web/vars.yml

The passwords are  stored in jinja2 format from the key variable  in the vault.yml file.

  - name: jdoe 
    password: '{{ vault_jdoe_password }}' 
  - name: jsmith
    password: '{{ vault_jsmith_password }}' 
  - name: ssmith
    password: '{{ vault_jsmith_password }}'

The playbook adds users and passwords to the server – install/users.yml

This will add the user and password to the servers in the web group. Only node1 will add the users.

- name: All software need by all servers
  hosts: all 
    - name: Users creation
        home: "/home/{{ }}"
        name: '{{ }}'
        password: "{{ item.password | password_hash('sha512') }}"
        state: present
      with_items: "{{ users }}"
      when: "'web' in group_names"

The Vault  file needs to be encrypted. To do this, I first make a vault password file that  will keep the  vault encryption password.  Make sure you protect the vault password file.  Set the permission on the file to 600 so only the ansible user can use it.

Vault yaml  file – install/group_vars/web/vault.yml

vault_jdoe_password: temp123 
vault_jsmith_password: temp456 
vault_ssmith_password: temp789



To encrypt the file

$ ansible-vault encrypt --vault-password-file=../../VAULT_PASSWD_FILE vault.yml
Encryption successful

$ cat vault.yml 

Now the vault.yml file  is encrypted.

We can now proceed with running the playbook to install the users on node1.  I use the ” –vault-password-file ” argument to pass in the vault file with the password.

$ ansible-playbook -i inventory --vault-password-file=VAULT_PASSWD_FILE users.yml

PLAY [All software need by all servers] ****************************************************

TASK [Gathering Facts] *********************************************************************
ok: [controller.example.local]
ok: [node1.example.local]

TASK [Users creation] **********************************************************************
skipping: [controller.example.local]
changed: [node1.example.local] => (item={u'password': u'temp123', u'name': u'jdoe'})
changed: [node1.example.local] => (item={u'password': u'temp456', u'name': u'jsmith'})
changed: [node1.example.local] => (item={u'password': u'temp456', u'name': u'ssmith'})

PLAY RECAP *********************************************************************************
controller.example.local : ok=1 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 
node1.example.local : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

Notice the users are only placed into the node1 server and not the controller. Also notice the plain text passwords are shown in the output.  This is because we stored them as plain passwords in the vault.yml file and  let the users.yml file encrypt them on the fly.  To prevent this, you can put the encrypted  password in the vault.yml file and  remove the ” | password_hash(‘sha512’) ” from the users.yml file.  The encrypted password will still be seen but not the plain text since it was never  stored.