Managing secrets with Ansible Vault
Secret management is an important aspect of any configuration management tool. Ansible comes with a tool called Ansible Vault which encrypts secrets (technically, it can encrypt any arbitrary file but we will focus on secrets) at rest with 256 bit AES encryption. These secrets can be used in tasks in various ways.
To understand this better, let us create a sample secret and use it in a task.
How to do it…
We will begin with a standard variable file, let us call it secret.yml
, in Ansible:
--- mysecret: secret-value
To use this in a playbook, we can include the file as a variable and call it in a task:
--- - hosts: localhost tasks: - name: include secret include_vars: secret.yml - name: get value debug: msg: "The value is: {{ mysecret }}"
Let us run our playbook to verify that everything is good:
$ ansible-playbook playbook.yml PLAY [localhost] *************************************************************** TASK [setup] ******************************************************************* ok: [localhost] TASK [include secret] ********************************************************** ok: [localhost] TASK [get value] *************************************************************** ok: [localhost] => { "msg": "The value is: secret-value" } PLAY RECAP ********************************************************************* localhost : ok=3 changed=0 unreachable=0 failed=0
Our goal is to protect the content of secret.yml
. So let us use ansible-vault
and encrypt it:
$ ansible-vault encrypt secret.yml Vault password: Encryption successful
Now the content of secret.yml
should look something like this:
$ANSIBLE_VAULT;1.1;AES256 64656138356263336432653663323966373961363637383035393631383963643363343162393764 6634663662333863373937373139326230326366643862390a643435663237333832366336323861 31666565333937343333373133353838396166356233316435643363356161366536356230396534 3038316565336630630a393938613764616530336565653866346130666466346130633563346564 33313230336265383532313033653237643662616437636263633039373065346537
Executing the playbook like before will fail because our variable file is encrypted. Ansible provides a way to read encrypted files on the fly without decrypting it on the disk. The flag, --ask-vault-pass
, will request the password from and execute the playbook normally when provided with the correct password:
$ ansible-playbook --ask-vault-pass playbook.yml Vault password: PLAY [localhost] *************************************************************** TASK [setup] ******************************************************************* ok: [localhost] TASK [include secret] ********************************************************** ok: [localhost] TASK [get value] *************************************************************** ok: [localhost] => { "msg": "The value is: secret-value" } PLAY RECAP ********************************************************************* localhost : ok=3 changed=0 unreachable=0 failed=0
We will be using Ansible Vault throughout this book to store secrets.
Note
Code Layout
We follow standard code layout to make it easy for everyone to understand the roles. Each chapter has a two playbooks and two roles. One playbook and role has code specific to managing our cloud resources. The other roles has code for deploying the phonebook application. Since there are secrets with each chapter, our final layout would look more or less like this:
└── chapter1
└── roles
├── <cloud provider>
│ ├── files
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ └── vars
│ ├── main.yml
│ └── secrets.yml
└── phonebook
├── files
│ └── phone-book.service
├── tasks
│ └── main.yml
├── templates
│ └── config.py
└── vars
└── secrets.yml