Skip to main content

Ansible Vault Basics

Introduction

When working with Ansible to manage your infrastructure, you'll often need to handle sensitive information such as passwords, API tokens, or SSH keys. Storing these credentials in plain text within your playbooks or variable files poses a significant security risk. This is where Ansible Vault comes to the rescue.

Ansible Vault is a feature that allows you to encrypt and decrypt files containing sensitive data, ensuring that your secrets remain secure even if your playbooks are stored in version control systems or shared with other team members.

What is Ansible Vault?

Ansible Vault is a built-in encryption system that enables you to:

  • Encrypt entire YAML files
  • Encrypt individual values within YAML files
  • Securely store credentials and other sensitive information
  • Share your Ansible code without exposing secrets

Let's explore how to use Ansible Vault to keep your sensitive data secure while maintaining the automation benefits of Ansible.

Getting Started with Ansible Vault

Prerequisites

Before we begin, make sure you have:

  • Ansible installed (version 2.4 or later)
  • Basic understanding of Ansible playbooks and variable files

Creating an Encrypted File

The most straightforward way to use Ansible Vault is to create an encrypted file from scratch. Let's create a file to store database credentials:

bash
ansible-vault create secrets.yml

When you run this command, Ansible will prompt you to create a password. This password will be used for both encryption and decryption, so make sure to choose a strong one and store it securely.

After entering the password, your default text editor will open, allowing you to add content to the file. For example:

yaml
---
db_user: admin
db_password: supersecretpassword123
db_name: production_database
api_key: 1a2b3c4d5e6f7g8h9i0j

Save and close the file. The content is now encrypted and stored in secrets.yml.

Viewing Encrypted Files

To view the contents of an encrypted file without decrypting it permanently:

bash
ansible-vault view secrets.yml

You'll be prompted to enter the vault password, after which the decrypted content will be displayed.

Editing Encrypted Files

To modify an encrypted file:

bash
ansible-vault edit secrets.yml

After entering the password, the file will open in your default editor. Make your changes, save, and close the file. Ansible will automatically re-encrypt the file.

Encrypting Existing Files

If you already have a file with sensitive data that you want to encrypt:

bash
ansible-vault encrypt existing-secrets.yml

After providing a password, Ansible will encrypt the file in place.

Decrypting Files

To permanently decrypt a file:

bash
ansible-vault decrypt secrets.yml

Be cautious with this command as it will leave your sensitive data in plain text.

Using Encrypted Files in Playbooks

Now that we know how to create and manage encrypted files, let's see how to use them in playbooks.

Running Playbooks with Vault Files

When running a playbook that uses encrypted files, you need to provide the vault password:

bash
ansible-playbook deploy.yml --ask-vault-pass

Ansible will prompt you for the vault password before executing the playbook.

Here's a simple playbook that uses our encrypted variables:

yaml
---
- name: Deploy application with secure credentials
hosts: web_servers
vars_files:
- secrets.yml

tasks:
- name: Configure database connection
template:
src: db_config.j2
dest: /etc/app/database.conf
owner: app
group: app
mode: '0600'

Using Vault Password Files

Entering the password manually can be inconvenient for automated processes. You can store the vault password in a file:

bash
echo "your_vault_password" > vault_pass.txt
chmod 600 vault_pass.txt # Restrict read/write permissions

Then use the password file when running playbooks:

bash
ansible-playbook deploy.yml --vault-password-file=vault_pass.txt
warning

Never commit the vault password file to version control! Add it to your .gitignore file.

Encrypting Individual Values

Sometimes you may want to encrypt only specific values in a file rather than the entire file. Ansible Vault supports this with the encrypt_string command:

bash
ansible-vault encrypt_string 'supersecretpassword123' --name 'db_password'

This command will output something like:

yaml
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
62313365396662343061393464336163383764373764613633653634306231386433626436623361
6134333665353966363534333632666535333761666131620a316639323065373831636337336163
37613834646437623466623631633335366265643262363566386362323738373664363131316466
3837646266663835640a313164643535323637633365363532323433366235343830333964653438
6164

You can then copy this output into your variables file, keeping the rest of the file in plain text:

yaml
---
# Only db_password is encrypted
db_user: admin
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
62313365396662343061393464336163383764373764613633653634306231386433626436623361
6134333665353966363534333632666535333761666131620a316639323065373831636337336163
37613834646437623466623631633335366265643262363566386362323738373664363131316466
3837646266663835640a313164643535323637633365363532323433366235343830333964653438
6164
db_name: production_database

This approach allows you to version control your configuration files while only encrypting the sensitive values.

Using Multiple Vault Passwords

In larger teams, you might need different vault passwords for different environments or roles. Ansible supports using multiple vault passwords with vault IDs:

bash
ansible-vault encrypt --vault-id dev@prompt secrets_dev.yml
ansible-vault encrypt --vault-id prod@prompt secrets_prod.yml

When running playbooks:

bash
ansible-playbook site.yml --vault-id dev@prompt --vault-id prod@prompt

Or with password files:

bash
ansible-playbook site.yml --vault-id dev@dev_pass.txt --vault-id prod@prod_pass.txt

Real-world Example: Deploying a Web Application

Let's put everything together in a practical example. We'll create a playbook to deploy a web application that requires database credentials and API keys.

First, create an encrypted file for production credentials:

bash
ansible-vault create production_secrets.yml

Add the following content:

yaml
---
db_host: db.example.com
db_user: prod_user
db_password: extremely_secret_password
api_key: abcd1234efgh5678ijkl
ssl_key_passphrase: secure_passphrase

Now, create a playbook that uses these secrets:

yaml
---
- name: Deploy web application
hosts: production_servers
vars_files:
- production_secrets.yml

tasks:
- name: Install required packages
apt:
name:
- nginx
- python3-pip
- python3-psycopg2
state: present
become: true

- name: Configure database connection
template:
src: templates/database.conf.j2
dest: /var/www/myapp/database.conf
owner: www-data
group: www-data
mode: '0600'
become: true
notify: restart application

- name: Configure API credentials
template:
src: templates/api_config.j2
dest: /var/www/myapp/api_config.json
owner: www-data
group: www-data
mode: '0600'
become: true
notify: restart application

handlers:
- name: restart application
systemd:
name: myapp
state: restarted
become: true

Create the template files referenced in the playbook:

templates/database.conf.j2:

DB_HOST={{ db_host }}
DB_USER={{ db_user }}
DB_PASSWORD={{ db_password }}
DB_NAME=myapplication

templates/api_config.j2:

json
{
"api_endpoint": "https://api.example.com/v1",
"api_key": "{{ api_key }}",
"timeout": 30
}

Run the playbook with:

bash
ansible-playbook deploy.yml --ask-vault-pass

Best Practices

To make the most of Ansible Vault, follow these best practices:

  1. Use different vault passwords for different environments (development, staging, production)
  2. Store vault passwords securely - consider using a password manager or secret management system
  3. Limit access to vault passwords based on roles and responsibilities
  4. Include vault files in version control but never include the vault passwords
  5. Encrypt only what needs to be encrypted - using individual encrypted values can make files more manageable
  6. Rotate vault passwords regularly for enhanced security
  7. Use vault IDs to clearly identify the purpose of different encrypted files
  8. Consider integration with secret management systems like HashiCorp Vault or AWS KMS for production environments

Troubleshooting Common Issues

Forgotten Vault Password

If you forget your vault password, there's unfortunately no built-in recovery method. This is by design for security reasons. Your options are:

  1. Restore from a backup
  2. Recreate the encrypted file with a new password

Permission Denied When Using Password File

If you see a "permission denied" error when using a password file, check the file permissions:

bash
chmod 600 vault_pass.txt

Vault File Corruption

If your vault file becomes corrupted, you may see an error like "Decryption failed." Try to restore from a previous version in your version control system.

Summary

Ansible Vault is a powerful tool for keeping sensitive data secure in your automation workflows. In this guide, we've covered:

  • Creating and managing encrypted files
  • Encrypting individual values in files
  • Using encrypted files in playbooks
  • Working with multiple vault passwords
  • Best practices for using Ansible Vault effectively

By incorporating Ansible Vault into your infrastructure as code practices, you can maintain security while still benefiting from automation and version control.

Additional Resources

To continue learning about Ansible Vault:

Practice Exercises

  1. Create an encrypted file containing database credentials for a development environment.
  2. Write a playbook that uses the encrypted credentials to configure a database connection.
  3. Modify an existing variable file to encrypt only the sensitive values.
  4. Set up a system with multiple vault passwords for different environments.
  5. Create a bash script that wraps ansible-playbook commands to automatically use the correct vault password file based on the target environment.


If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)