How To Secure Information In Playbooks Using Ansible Vault

Dec 22, 2023 · 9 mins read
How To Secure Information In Playbooks Using Ansible Vault

In the video below, we show how to manage and use Ansible Vault to secure information in your Playbooks


Ansible is a great tool for automation but sometimes it needs access to sensitive information

For instance, maybe a task needs user credentials to access a computer, or it needs to upload a configuration file containing sensitive information

Either way, it’s not good to store details like this in plain view

Fortunately, Ansible allows you to create Ansible Vaults, basically encrypted files to store sensitive information in

So in this video we show how to create and manage Ansible Vaults and how can you configure Ansible to use them

Useful links:
https://docs.ansible.com/ansible/latest/cli/ansible-vault.html

Change Text Editor:
Now before we create a vault, the first thing we’re going to do is to change the default text editor

Everyone has their own preference when it comes to text editors and I prefer to use nano, especially when working on simple files

By default, however, the ansible-vault command, which is used to manage vault files, will use vi

To use nano instead, we need to edit our bash config file

nano ~/.bashrc

Then we’ll append this line at the end

export EDITOR=nano

Rather than exiting out and starting a new terminal session, we can update this in the existing session

. ~/.bashrc

Create a Vault:
In this example we’ll create a vault containing variables that will be used for managing Proxmox VE servers

But first we’ll create the parent folder to store variables in

 
mkdir group_vars

Because I’ve created a group in the inventory file called pvenodes and the playbook will access a server in that group, we’ll create a sub-folder with that group name

mkdir group_vars/pvenodes

In other words, when Ansible is looking for variabales for hosts in the pvenodes group, it will look in the folder group_vars/pvenodes

There are different ways that you can create a vault but what we’re going to do is to create and encrypt one in one step

To do that we’ll use the ansible-vault command and we’ll tell it to create a file called vault

ansible-vault create group_vars/pvenodes/vault

As soon as you hit return you’ll be prompted to create and confirm a password for this

Now in the nano text editor, we’ll copy and paste in the information we want to encrypt

api_user: ansible@pam
api_token_id: ansible-token
api_token_secret: 8f6b42d6-93ad-4d08-83c8-48bd6905f804

Now save and exit

These are user credentials to login to Proxmox VE, and we certainly don’t want these in plain sight

Now if we look at the file you’ll see that the contents are encrypted and that’s what we want

cat group_vars/pvenodes/vault

View Contents:
If you want to view the contents of a vault, you can use the ansible-vault command

ansible-vault view group_vars/pvenodes/vault

As long as you provide the right password the contents will be decrypted in the background and displayed in the terminal

NOTE: The file itself remains encrypted

cat group_vars/pvenodes/vault

Edit Vault:
At some later date in time you’ll probably want to edit the contents of the vault

And you can do that without having to decrypt the file, edit it, then encrypt it again

ansible-vault edit group_vars/pvenodes/vault

Again, you’ll need to provide the password, then you can edit the file in the text editor

Now save and exit

As before, we’ll check the file remains encrypted

cat group_vars/pvenodes/vault

Decrypt Vault:
If for some reason you ever want to decrypt the vault file, you can do that

ansible-vault decrypt group_vars/pvenodes/vault

Provide the password when prompted and you’ll be left with a plain text file

Now when we check, we see that the file is decrypted

cat group_vars/pvenodes/vault

Encrypt Vault:
Earlier we created a vault and encrypted it all in one command

But you can create a vault by encrypting an existing file, for example

ansible-vault encrypt group_vars/pvenodes/vault

You’ll be prompted to create and confirm a password for this vault

This time, we’ll check to make sure the file is encrypted

cat group_vars/pvenodes/vault

Change Vault Password:
There will be times when the password for a vault needs to be changed and it’s actually a good practice to regularly do this anyway

To change the password for a vault we can run this command

ansible-vault rekey group_vars/pvenodes/vault

First you’ll be prompted for the existing password, then you’ll be asked to provide the new one and to confirm it

As before, we’ll check the file remains encrypted

cat group_vars/pvenodes/vault

Using Vaults:
There are lots of places where Ansible will look for variable and vault files

For example, variables and vaults that apply to all hosts can be expected to be in group_vars/all

Ones for a particular group to be in group_vars/<group> hence why I created a group_vars/pvenodes folder

And when it comes to individual hosts, they can be expected to be found in host_vars

Of course if you create roles, these have their own defaults and vars folders for Ansible to search in

Since we’ve placed our vault in a folder where Ansible will be looking, we need to update the playbook to now use variables instead of the actual data

For example

nano pve_create_vm.yml

      api_user: '{{api_user}}'
      api_token_id: '{{api_token_id}}'
      api_token_secret: '{{api_token_secret}}'

Now save and exit

To allow access to the vault, we need to provide Ansible with the password and we can do that by asking to be prompted

For example

ansible-playbook pve_create_vm.yml -i inventory --user=ansible --private-key ~/.ssh/ansible-key --ask-vault-password

Now our playbook contains variables instead of actual values, there’s less risk of the credentials ending up in the wrong hands

Create a Password File:
A problem we now have is that every time we want to run a playbook, we have to answer a prompt to provide Ansible with the password for the vault

And that’s not going to be practical if we want to schedule playbooks using cron for instance

To deal with that, we can create a password file, basically a file that contains the password and then point Ansible to it

An example for creating a password file would be as follows

echo 'mysecret' > ~/.myvaultkey
chmod 600 ~/.myvaultkey

Here we create a text file called .myvaultkey in our home folder, i.e. it will be a hidden file, and it will contain the password we use for accessing vault files

NOTE: Do use a much better password than in this example

In addition, we’ve also restricted access to just the owner for extra measure

Now, if you will be using a Git repository for instance with Ansible, it makes sense to store your Ansible files in a different folder

This way the password file and Ansible files are separated

If you then setup Git within the Ansible folder, while the password file is in the home directory, it won’t upload the password file to the repository

Another thing to factor in is that Ansible itself needs access to the file

A simple way to handle that is to create a user account for Ansible on the computer and do all of your Ansible work logged in as that user

Do bear in mind, the contents of this file are in plain text because Ansible needs to be able to read them, so access to the computer and anywhere the files are uploaded to should be restricted

Also, whenever the password of a vault is changed, the password in the file needs updating

For extra safety, it would also make sense to keep a copy of this password in a password manager for instance

Using Password Files:
Rather than being prompted for a password when we run a playbook or use the ansible-vault command we can reference a password file

For example, to view the contents of the vault we can run this command

ansible-vault view group_vars/pvenodes/vault --vault-password-file ~/.myvaultkey

To run our playbook we can run this command

ansible-playbook pve_create_vm.yml -i inventory --user=ansible --private-key ~/.ssh/ansible-key --vault-password-file ~/.myvaultkey

Set Default Vault Key:
Ansible allows you to setup default settings in a file called ansible.cfg, including the location of a password file

Ansible will look for a file of that name in multiple locations, including the working folder and also in your home folder

Bear in mind, the file in the home folder must be hidden and so it needs to be called .ansible.cfg

The only problem is that Ansible isn’t sophisticated enough to pull information from multiple files

So if you create a file in your home folder, but also have one in the working folder, only information from the file in the working folder will be used

In this example we’ll edit the one in the local folder

nano ansible.cfg

[defaults]
...
vault_password_file=~/.myvaultkey

Now save and exit

With this default setting in place we don’t need to reference the password file

For example

ansible-playbook pve_create_vm.yml -i inventory --user=ansible --private-key ~/.ssh/ansible-key

One benefit of using a file in the home folder, is that those settings will apply to multiple Ansible projects which can save you admin work

If you need more specific settings in one project, for example it has a vault with a different password, you can override the default setting by adding the –vault-password-file parameter to to the command

In any case, we can now encrypt sensitive information in an Ansible Vault and still have Ansible run unattended, scheduled playbooks

Sharing is caring!