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.
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