Ansible Vault Encryption
Introduction
When working with Ansible playbooks and roles, you'll often need to handle sensitive information such as passwords, API keys, or certificates. Storing this sensitive data in plain text within your playbooks or variable files poses a significant security risk, especially when your Ansible code is stored in version control systems like Git.
Ansible Vault solves this problem by providing built-in encryption capabilities that allow you to securely store and manage sensitive data within your Ansible projects. Ansible Vault uses AES256 encryption to protect your data while making it seamlessly available to your playbooks during execution.
Understanding Ansible Vault
Ansible Vault is a feature that encrypts YAML files so you can protect sensitive content. It allows you to:
- Create new encrypted files
- Encrypt existing files
- View encrypted files
- Edit encrypted files
- Use encrypted files in playbooks
Getting Started with Ansible Vault
Let's explore how to use Ansible Vault to secure your sensitive data.
Creating Encrypted Files
To create a new encrypted file, use the ansible-vault create
command:
ansible-vault create secret_vars.yml
This command will:
- Prompt you to enter and confirm a password
- Open your default text editor
- Allow you to add content to the file
- Automatically encrypt the file when you save and exit
Example:
Input:
$ ansible-vault create secret_vars.yml
New Vault password:
Confirm New Vault password:
After entering your password, your editor opens. You might add content like:
# Database credentials
db_user: admin
db_password: supersecretpassword
db_name: production_db
# API credentials
api_key: abcd1234efgh5678ijkl
api_secret: verysecretapikey123!
Once saved, the file content will be encrypted and look similar to this:
$ANSIBLE_VAULT;1.1;AES256
34623639666666383339363732666263363830663666313466613830653266333566326564373066
33353330663932353330643336363062363661633537663661313563636565323866383034613534
66616266386138316432386166623764303661323764346436373736643737326664356664323837
3831643531303837650a313339623862666664343338303762333232326638323962323631353437
34376463356532626166656532366662316661646565306565626366363532353330363933643238
3931626661396538620a663135313739626334643962343664356332383537383637613965376664
62353338613732313639323266323732653163653939376663636164396265313437643635616263
31323064323337396536
Encrypting Existing Files
If you already have files with sensitive data, you can encrypt them using the ansible-vault encrypt
command:
ansible-vault encrypt existing_vars.yml
Example:
Let's say you have an existing file database_credentials.yml
with:
mysql_user: dbadmin
mysql_password: p@ssw0rd
mysql_host: db.example.com
mysql_port: 3306
To encrypt it:
$ ansible-vault encrypt database_credentials.yml
New Vault password:
Confirm New Vault password:
Encryption successful
Viewing Encrypted Files
To view the contents of an encrypted file without editing it:
ansible-vault view secret_vars.yml
You'll be prompted for the password, and then the decrypted content will be displayed in your terminal.
Editing Encrypted Files
To edit an already encrypted file:
ansible-vault edit secret_vars.yml
This will:
- Ask for your vault password
- Decrypt the file temporarily
- Open it in your editor
- Re-encrypt it when you save and exit
Decrypting Files
If you need to permanently decrypt a file:
ansible-vault decrypt secret_vars.yml
Warning: This removes encryption protection, so be careful!
Using Encrypted Files in Playbooks
Ansible automatically detects encrypted files and attempts to decrypt them when running playbooks. You need to provide the vault password when executing your playbook.
Basic Usage
ansible-playbook deploy.yml --ask-vault-pass
This will prompt you for the vault password before running the playbook.
Using a Password File
For automation, you can store your vault password in a file (which should be properly secured and not committed to version control):
echo "my_vault_password" > ~/.vault_pass.txt
chmod 600 ~/.vault_pass.txt
Then reference it when running playbooks:
ansible-playbook deploy.yml --vault-password-file=~/.vault_pass.txt
You can also configure this in your ansible.cfg
file:
[defaults]
vault_password_file = ~/.vault_pass.txt
Real-World Example: Deploying a Web Application
Let's see a complete example of using Ansible Vault in a real-world scenario where we're deploying a web application that requires database credentials.
Step 1: Create an encrypted variable file
ansible-vault create group_vars/production/vault.yml
Add the following sensitive variables:
# Database credentials
db_user: webapp_user
db_password: super_secret_production_pw
db_name: webapp_production
# SSL Certificate Password
ssl_key_password: certificate_key_passphrase
Step 2: Create a regular variables file that references encrypted variables
In group_vars/production/vars.yml
:
# Application settings
app_name: MyWebApp
app_environment: production
app_port: 8080
# Database connection string (using encrypted variables)
database_url: "postgresql://{{ db_user }}:{{ db_password }}@db.example.com:5432/{{ db_name }}"
# Deployment paths
app_path: /var/www/mywebapp
config_path: "{{ app_path }}/config"
Step 3: Create the deployment playbook
In deploy_webapp.yml
:
---
- name: Deploy Web Application
hosts: web_servers
become: true
tasks:
- name: Install required packages
apt:
name:
- nginx
- postgresql-client
- python3-psycopg2
state: present
update_cache: yes
- name: Create application directory
file:
path: "{{ app_path }}"
state: directory
owner: www-data
group: www-data
mode: '0755'
- name: Generate application configuration
template:
src: templates/config.j2
dest: "{{ config_path }}/config.json"
owner: www-data
group: www-data
mode: '0640'
notify: restart application
- name: Configure SSL certificate
copy:
content: |
#!/bin/bash
echo "{{ ssl_key_password }}" | openssl pkcs12 -in /etc/ssl/private/cert.p12 -nocerts -out /etc/ssl/private/key.pem
dest: /usr/local/bin/extract_ssl_key.sh
mode: '0700'
notify: extract ssl key
handlers:
- name: restart application
systemd:
name: mywebapp
state: restarted
- name: extract ssl key
command: /usr/local/bin/extract_ssl_key.sh
notify: restart nginx
- name: restart nginx
systemd:
name: nginx
state: restarted
Step 4: Create the config template
In templates/config.j2
:
{
"appName": "{{ app_name }}",
"environment": "{{ app_environment }}",
"port": {{ app_port }},
"database": {
"connectionString": "{{ database_url }}"
},
"logging": {
"level": "info",
"path": "/var/log/{{ app_name }}"
}
}
Step 5: Run the playbook with vault password
ansible-playbook deploy_webapp.yml --ask-vault-pass
This example demonstrates how Ansible Vault keeps sensitive data secure while still making it available during playbook execution.
Multiple Vault Passwords
For more complex environments, you might need different vault passwords for different roles or environments.
Using Vault IDs
Ansible supports vault IDs to work with multiple vault passwords:
# Create a production vault
ansible-vault create --vault-id=prod@prompt group_vars/production/vault.yml
# Create a development vault with different password
ansible-vault create --vault-id=dev@prompt group_vars/development/vault.yml
When running your playbook, you can specify which vault IDs to use:
ansible-playbook site.yml --vault-id prod@prompt --vault-id dev@prompt
You can also use password files with IDs:
ansible-playbook site.yml --vault-id prod@~/.vault_pass_prod --vault-id dev@~/.vault_pass_dev
Best Practices
- Never commit vault passwords to version control
- Use different vault passwords for different environments
- Encrypt only what needs to be encrypted - don't encrypt your entire playbook or all variables
- Rotate vault passwords periodically
- Consider using a secrets management tool like HashiCorp Vault or AWS Secrets Manager for larger deployments
- Store vault password files outside of your project directory
- Set restrictive permissions on password files (
chmod 600
) - Use vault IDs to organize multiple passwords
Troubleshooting
Common Issues and Solutions
-
"Decryption failed"
- Ensure you're using the correct password
- Check if the file was encrypted with a different vault ID
-
"ERROR! Vault password file not found"
- Verify the path to your password file
- Check permissions on the password file
-
"ERROR! The vault password must be specified"
- You need to provide
--ask-vault-pass
or--vault-password-file
- Or configure
vault_password_file
in ansible.cfg
- You need to provide
-
Playbook runs but variables are missing
- Ensure variables are properly referenced
- Check that encrypted files are being loaded correctly
Summary
Ansible Vault provides a straightforward way to encrypt sensitive data within your Ansible projects:
- Create encrypted files with
ansible-vault create
- Encrypt existing files with
ansible-vault encrypt
- View files with
ansible-vault view
- Edit files with
ansible-vault edit
- Run playbooks with
--ask-vault-pass
or--vault-password-file
By properly implementing Ansible Vault, you can maintain security best practices while still enjoying the automation benefits of Ansible. Sensitive information like passwords, API keys, and certificates can be securely stored alongside your code without exposing them to unauthorized users.
Additional Resources
Exercises
- Create an encrypted file containing database credentials and use it in a playbook that sets up a database connection.
- Experiment with vault IDs by creating multiple encrypted files for different environments (dev, staging, production).
- Set up a CI/CD pipeline that uses a vault password file to decrypt secrets during deployment.
- Create a playbook that rotates passwords stored in vault files.
- Implement a solution where different team members have access to different vault-encrypted files.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)