Encrypting Login Credentials in Ansible Vault

One of Ansible‘s benefits over Puppet and Chef is its server-less/agent-less architecture. Rather than having agents on client machines continuously checking in to a server for configuration changes (pull model), Ansible operates via a “push model” over SSH. One of the complications of the push model over SSH, however, is that the “pusher” needs to have login credentials to all of the target machines. Given that the set of these credentials are the collective keys to your kingdom, how can one store these credentials securely?

Ideally one would use SSH public/private key pairs for authentication. This assumes some of prerequisites though: 1) That the machine(s) you’ll be pushing from with the private key(s) are sufficiently locked-down such that the private key(s) will never be accessible to normal users; and 2) That each of your target hosts is configured with the corresponding public key as an authorized login key.

Suppose that you’re not yet able to fully implement public/private key pairs for authentication across your entire infrastructure. How should you proceed? Ansible’s docs on Inventory management indicate that one can put the login credentials in their inventory file. Ex:

other1.example.com    ansible_connection=ssh    ansible_ssh_user=mpdehaan   ansible_ssh_pass=foobar
other2.example.com    ansible_connection=ssh    ansible_ssh_user=mdehaan    ansible_ssh_pass=foobar123

Unfortunately, here’s a dirty little secret about Ansible & Ansible Vault: The inventory file itself is not encrypt-able with Ansible Vault. If you proceed down the path of putting your login credentials into the plain-text Ansible inventory file in source control, anyone with access to your source control repo will have the login creds for all of the machines in your inventory. Ouch!

Luckily there is a solution for this: Buried deep within a page in Ansible’s documentation that describes Ansible’s support for Microsoft Windows, there is an example which provides a path forward for securely storing login credentials for machines managed by Ansible. The solution mentioned on that page is to use Ansible’s concept of “group_vars” and “host_vars” to store variables like “ansible_ssh_user” and “ansible_ssh_pass” on a per group/host basis, and then encrypt those variables with Ansible Vault.

Some examples:

# group_vars/webservers:
ansible_ssh_user: deployment
ansible_ssh_pass: my deployment password

# host_vars/db1.mycompany.com
ansible_ssh_user: ansible
ansible_ssh_pass: my other deployment password

From there one can encrypt those group/host variable files with “ansible-vault encrypt …”, and deploy with “ansible-playbook –ask-vault-pass …”.

For more information on Ansible Vault see their official docs, or my two-part blog post on using Ansible Vault:


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s