Hello everyone.
In this part of the Ansible guide, I want to introduce you to the Ansible Vault. We can use it to encrypt data in Ansible. Many tasks require credentials that we do not want to store in plain text as a variable.
The Ansible Vault is included with the installation of Ansible, so it does not need to be installed separately.
Creating a new vault
First we need to generate a password for the vault, I like to use the "pwgen" tool for this. I have the password written directly to a hidden file in my home directory.
sudo apt install pwgen
# 1 Passwort mit 12 Zeichen erstellen
pwgen 12 1 > ~/.vaultpw
Now we can create a vault as follows. In this example, we store the vault in host vars:
cd ~/ansible-guide
mkdir -p host_vars/ansible-guide-1
ansible-vault create host_vars/ansible-guide-1/vault.yml --vault-password-file ~/.vaultpw
With the above command, we have created a new file and encrypted it with the password we created earlier. An editor should open immediately after the command.
The contents of this file can be arbitrary; in the simplest example, we can simply define variables here. Let's say we want to create a new user on our host and store his password in the vault:
Save the file and you have successfully created your first Vault Secret :)
If we look at the contents of the file, it should look something like this:
$ANSIBLE_VAULT;1.1;AES256
32363637353431323335313831306531653461353135303736343138336238393861663962396139
6637636264613234326461316539636231353537666538370a663266346333643430313538646332
30663139653637313935646130366530363361646565313436633430363935613532313966323536
6632313462383464640a346538656131353038383338313337346365396131343336666466326566
38393836636437333939363330323033613535376661333330613934663066303639
As we can see, the contents of the vault are cryptic and unreadable. So we can load the file into a source manager, for example, without storing the credentials in plain text.
In this case, we can use the secret as a normal variable:
- hosts: ansible-guide-1
tasks:
- name: create user
ansible.builtin.user:
name: me
password: "{%raw%}{{ user_password }}{%endraw%}"
state: present
If we now try to run the playbook as usual, the result should look something like this:
PLAY [localhost] *********************************************************************************
ERROR! Attempting to decrypt but no vault secrets found
That's right! We need to enter the Vault password:
ansible-playbook --vault-password-file ~/.vaultpw playbook.yml
And it works. But how exactly? Ansible will search the variable directories (host_vars, group_vars) at startup as usual, find the encrypted vault, and decrypt it.
An Ansible vault does not have to be an encrypted YAML file of variables. In principle, we can use it to encrypt any file.
Example: Storing a certificate and key in a vault
Let's assume we want to deliver an SSL certificate including a key to a web server.
We put both files in a subfolder called "files":
Now, we don't want to have both files lying around in plain text. So we encrypt them using the Ansible Vault:
ansible-vault encrypt files/*.pem --vault-password-file ~/.vaultpw
Encryption successful
In our playbook, we can use the Copy module as usual to copy both files. Because Ansible recognizes that these are vaults, it decrypts both files.
Run the playbook:
ansible-playbook playbook.yml --vault-password-file ~/.vaultpw
Done! Both files should be on the server in decrypted form 😄
Encrypt single strings
Instead of encrypting entire files, we can simply encrypt variable values:
ansible-vault encrypt_string "hello world" --vault-password-file ~/.vaultpw
!vault |
$ANSIBLE_VAULT;1.1;AES256
64613036333366373032623562333639646565303830653335366361373533663835666135343861
3864316335646165633439656662666537653538623662320a346432353261636466353964633365
61636463306537313137373630323633376465663938633130633637623866326639613235323262
3665643535633739640a366162363664356337363062636535343463323263653934623434626664
3233
Encryption successful
Within Ansible, we can then define the string as a variable like this:
my_encrypted_var: !vault |
$ANSIBLE_VAULT;1.1;AES256
64613036333366373032623562333639646565303830653335366361373533663835666135343861
3864316335646165633439656662666537653538623662320a346432353261636466353964633365
61636463306537313137373630323633376465663938633130633637623866326639613235323262
3665643535633739640a366162363664356337363062636535343463323263653934623434626664
3233
This brings us to the end of the article. I hope I was able to teach some of you something new :)
As always, I would love to hear your feedback!
See you soon,
Mow