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:
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:
---
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:
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:
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:
ansible-vault encrypt existing-secrets.yml
After providing a password, Ansible will encrypt the file in place.
Decrypting Files
To permanently decrypt a file:
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:
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:
---
- 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:
echo "your_vault_password" > vault_pass.txt
chmod 600 vault_pass.txt # Restrict read/write permissions
Then use the password file when running playbooks:
ansible-playbook deploy.yml --vault-password-file=vault_pass.txt
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:
ansible-vault encrypt_string 'supersecretpassword123' --name 'db_password'
This command will output something like:
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:
---
# 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:
ansible-vault encrypt --vault-id dev@prompt secrets_dev.yml
ansible-vault encrypt --vault-id prod@prompt secrets_prod.yml
When running playbooks:
ansible-playbook site.yml --vault-id dev@prompt --vault-id prod@prompt
Or with password files:
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:
ansible-vault create production_secrets.yml
Add the following content:
---
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:
---
- 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
:
{
"api_endpoint": "https://api.example.com/v1",
"api_key": "{{ api_key }}",
"timeout": 30
}
Run the playbook with:
ansible-playbook deploy.yml --ask-vault-pass
Best Practices
To make the most of Ansible Vault, follow these best practices:
- Use different vault passwords for different environments (development, staging, production)
- Store vault passwords securely - consider using a password manager or secret management system
- Limit access to vault passwords based on roles and responsibilities
- Include vault files in version control but never include the vault passwords
- Encrypt only what needs to be encrypted - using individual encrypted values can make files more manageable
- Rotate vault passwords regularly for enhanced security
- Use vault IDs to clearly identify the purpose of different encrypted files
- 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:
- Restore from a backup
- 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:
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:
- Official Ansible Vault Documentation
- Ansible Vault Integration with External Key Management Systems
- Ansible Galaxy Collections with Vault Examples
Practice Exercises
- Create an encrypted file containing database credentials for a development environment.
- Write a playbook that uses the encrypted credentials to configure a database connection.
- Modify an existing variable file to encrypt only the sensitive values.
- Set up a system with multiple vault passwords for different environments.
- 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! :)