I am a newbie to ansible and I am using a very simple playbook to issue sudo apt-get update
and sudo apt-get upgrade
on a couple of servers.
This is the playbook I am using:
--- - name: Update Servers hosts: my-servers become: yes become_user: root tasks: - name: update packages apt: update_cache=yes - name: upgrade packages apt: upgrade=dist
and this is an extract from my ~/.ansible/inventory/hosts
file:
[my-servers] san-francisco ansible_host=san-francisco ansible_ssh_user=user ansible_become_pass=<my_sudo_password_for_user_on_san-francisco> san-diego ansible_host=san-diego ansible_ssh_user=user ansible_become_pass=<my_sudo_password_for_user_on_san-diego>
This is what I get if I launch the playbook:
$ ansible-playbook update-servers-playbook.yml PLAY [Update Servers] ********************************************************** TASK [setup] ******************************************************************* ok: [san-francisco] ok: [san-diego] TASK [update packages] ********************************************************* ok: [san-francisco] ok: [san-diego] TASK [upgrade packages] ******************************************************** ok: [san-francisco] ok: [san-diego] PLAY RECAP ********************************************************************* san-francisco : ok=3 changed=0 unreachable=0 failed=0 san-diego : ok=3 changed=0 unreachable=0 failed=0
What is bothering me is the fact that I have the password for my user user
stored in plaintext in my ~/.ansible/inventory/hosts
file.
I have read about vaults, I have also read about the best practices for variables and vaults but I do not understand how to apply this to my very minimal use case.
I also tried to use lookups. While in general they also work in the inventory file, and I am able to do something like this:
[my-servers] san-francisco ansible_host=san-francisco ansible_ssh_user=user ansible_become_pass="{{ lookup('env', 'ANSIBLE_BECOME_PASSWORD_SAN_FRANCISCO') }}"
where this case the password would be stored in an environment variable called ANSIBLE_BECOME_PASSWORD_SAN_FRANCISCO
; there is no way to look up variables in vaults as far as I know.
So, how could I organize my file such that I would be able to lookup up my passwords from somewhere and have them safely stored?
You need to create some vaulted variable files and then either include them in your playbooks or on the command line.
If you change your inventory file to use a variable for the become pass this variable can be vaulted:
[my-servers] san-francisco ansible_host=san-francisco ansible_ssh_user=user ansible_become_pass='{{ sanfrancisco_become_pass }}' san-diego ansible_host=san-diego ansible_ssh_user=user ansible_become_pass='{{ sandiego_become_pass }}'
Then use ansible-vault create vaulted_vars.yml
to create a vaulted file with the following contents:
sanfrancisco_become_pass: <my_sudo_password_for_user_on_san-francisco> sandiego_become_pass : <my_sudo_password_for_user_on_san-diego>
Then either include the vaulted file as extra vars like this:
ansible-playbook -i ~/.ansible/inventory/hosts playbook.yml --ask-vault-pass -e@~/.ansible/inventory/vault_vars
Or include the vars file in your playbook with an include_vars task:
- name : include vaulted variables include_vars: ~/.ansible/inventory/vault_vars
The best way to solve this problem is to use host_vars. The easiest setup is to just put the ansible_become_pass
in Vault encrypted files in the corresponding host_vars directories like this:
myplaybook.yml host_vars/onehost.com/crypted host_vars/otherhost.com/crypted
In the crypted
files you place the assignment of the ansible_become_pass
variable:
ansible_become_pass: SuperSecre3t
Create the file with ansible-vault create
, edit it with ansible-vault edit
.
Following the advice in the Ansible docs you need to create an additional file per host that assigns the ansible_become_passwd
from the crypted variable that has a different name. That way it is possible to search for the ansible_become_passwd
in the project files.
myplaybook.yml host_vars/onehost.com/plain host_vars/onehost.com/crypted host_vars/otherhost.com/plain host_vars/otherhost.com/crypted
where a plain
file contains something like this:
ansible_become_pass: "{{ vaulted_become_pass }}"
and the crypted
file sets the vaulted_become_pass
like shown above.
All crypted
files must be encrypted with the same key and ansible-playbook
must be called with --ask-vault-pass
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With