When we automate configurations we cannot avoid providing secrets to Ansible. The last thing we want is our secret data running around in plain text files on our control node. Luckily Ansible has a tool for this.
Ansible Vault is an integrated encryption tool in Ansible to manage sensitive data like passwords, keys and certificates. As with most parts of Ansible, we can start simple, and complexity can come later on.

Creating an encrypted variables file is easy using the ansible-vault
command. Let’s follow the simple directory layout suggested by the Ansible team.
We have the host_vars
and group_vars
directories in our Ansible project root. If they don’t exist, let’s create them!
$ mkdir {host_vars,group_vars}
Now we can create a directory under our host_vars
and call it as we call our Ansible control node in the inventory. My control node is called ansible-control
, so I create a directory for it.
$ mkdir host_vars/ansible-control
Our directory structure is ready and Ansible will find the variables and secrets with it.
Let’s create an encrypted file and set up a strong Vault password on it!
$ ansible-vault create host_vars/ansible-control/vault.yml
New Vault password:
Confirm New Vault password:
After setting the password ansible-vault
will open the file in our default editor. We can edit this file as an ordinary YAML variable file for Ansible.
Let’s create a test variable and save the file!
# host_vars/ansible-control/vault.yml
---
var1: secret
After closing the file we can see that it is encrypted with AES256 encryption.
$ cat host_vars/ansible-control/vault.yml
$ANSIBLE_VAULT;1.1;AES256
38306134643266623862643864666330306339613066373531383032616463333333313235626434
3064663733343439303630373263386536346436353430630a656530646237313533663436326561
31363565333939663263306262633564383461363966343439646335666339626633303264333637
3832303763323536320a613763306565346534373738393735393461313261356134663935343833
66663631613239373862343665313334636562363266306363316139653138663038
When we want to edit it we have to use the ansible-vault edit
command giving it the file as a parameter. Then the command asks for the Vault password.
$ ansible-vault edit host_vars/ansible-control/vault.yml
Vault password:
Now we can use these variables in a playbook or role. When we want to use the variables encrypted by Vault we have to pass the --ask-vault-pass
option to our ansible-playbook
command to be able to decrypt them during the Ansible run.
Let’s create a test playbook and check it in action!
---
- name: Test playbook for playing with Ansible
hosts: all
tasks:
- name: Write out our secrets
ansible.builtin.debug:
msg: "{{ var1 }}"
We can run it now.
$ ansible-playbook -i inventory play-test.yml --limit ansible-control --ask-vault-pass
Note the --ask-vault-pass
option! The output will be something like the following.
TASK [Write out our secrets] ***********************************************************************************************************************************
ok: [ansible-control] => {
"msg": "secret"
}
We can see that encrypting whole files is easy. The drawback is that when we store these encrypted files in source control management the whole file will change after changing a single variable. The solution will be the individual variable encryption that we will investigate later.
Another issue with secret variables that they are only encrypted in rest. When Ansible uses the secrets it may reveal them in its output or logs.
There is a solution for this! We can use the no_log: true
option for a task that uses secrets to do NOT write the output to the screen or to the logs.
---
- name: Test playbook for playing with Ansible
hosts: all
tasks:
- name: Write out our secrets
ansible.builtin.debug:
msg: "{{ var1 }}"
no_log: true
Let’s see it in action!
$ ansible-playbook -i inventory play-test.yml --limit ansible-control --ask-vault-pass
Vault password:
PLAY [Test playbook for playing with Ansible] ******************************************************************************************************************
TASK [Gathering Facts] *****************************************************************************************************************************************
ok: [ansible-control]
TASK [Write out our secrets] ***********************************************************************************************************************************
ok: [ansible-control]
PLAY RECAP *****************************************************************************************************************************************************
ansible-control : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
As we can see the output does not contain the secret value anymore.
Now we can create real playbooks and roles using sensitive data without leaking it to unauthorized eyes.
If you have anything to share then please visit my Tom’s IT Cafe Discord Server!