Introduction
Ansible Vault provides built-in encryption for protecting sensitive data in your automation workflows — passwords, API keys, certificates, and any secret that shouldn't exist in plaintext. Unlike external secrets managers, Vault is included with Ansible and requires zero additional infrastructure.
This guide covers all Vault operations from basic file encryption to advanced multi-vault setups and CI/CD integration.
Quick Start
Encrypt a File
ansible-vault encrypt vars/secrets.yml
You'll be prompted for a vault password. The file is encrypted in-place using AES-256.
Decrypt a File
ansible-vault decrypt vars/secrets.yml
View Encrypted File
ansible-vault view vars/secrets.yml
Edit Encrypted File
ansible-vault edit vars/secrets.yml
Opens the decrypted file in your $EDITOR, then re-encrypts on save.
Creating Vault-Encrypted Files
New Encrypted File
ansible-vault create vars/vault.yml
This opens your editor with an empty file. Add your secrets:
# vars/vault.yml (will be encrypted on save)
db_password: "SuperSecretP@ss123"
api_key: "sk-abc123def456"
ssl_private_key: |
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC7...
-----END PRIVATE KEY-----
Encrypt Individual Strings
Use encrypt_string to encrypt a single value inline:
ansible-vault encrypt_string 'SuperSecretP@ss123' --name 'db_password'
Output:
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
61626364656667686970...
Paste this directly into your variables file — only this value is encrypted, making the file partially readable:
# vars/main.yml
db_name: myapp_production
db_user: myapp
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
61626364656667686970...
db_port: 5432
Using Vault in Playbooks
Password Prompt
ansible-playbook site.yml --ask-vault-pass
Password File
ansible-playbook site.yml --vault-password-file ~/.vault_pass
The password file is a plain text file containing just the password:
echo "MyVaultPassword123" > ~/.vault_pass
chmod 600 ~/.vault_pass
Password from Script
The password file can be an executable script:
#!/bin/bash
# ~/.vault_pass.sh
# Fetch from password manager
pass show ansible/vault-password
chmod +x ~/.vault_pass.sh
ansible-playbook site.yml --vault-password-file ~/.vault_pass.sh
Set Default in ansible.cfg
[defaults]
vault_password_file = ~/.vault_pass
Multiple Vault IDs
For environments with different security levels, use multiple vault passwords:
# Encrypt with a vault ID
ansible-vault encrypt --vault-id dev@prompt vars/dev-secrets.yml
ansible-vault encrypt --vault-id prod@~/.vault_pass_prod vars/prod-secrets.yml
Run playbooks with multiple vault IDs:
ansible-playbook site.yml \
--vault-id dev@prompt \
--vault-id prod@~/.vault_pass_prod
Vault ID in Encrypted Strings
ansible-vault encrypt_string --vault-id prod@prompt 'secret' --name 'api_key'
Output includes the vault ID:
api_key: !vault |
$ANSIBLE_VAULT;1.2;AES256;prod
31323334353637383930...
Best Practices
File Organization
Separate encrypted and unencrypted variables:
group_vars/
production/
vars.yml # Non-sensitive defaults
vault.yml # Encrypted secrets
staging/
vars.yml
vault.yml
Reference vault variables with a vault_ prefix:
# group_vars/production/vault.yml (encrypted)
vault_db_password: "SuperSecret123"
vault_api_key: "sk-abc123"
# group_vars/production/vars.yml (plaintext)
db_password: "{{ vault_db_password }}"
api_key: "{{ vault_api_key }}"
This makes it clear which variables come from the vault.
Always Use no_log
Even with Vault, task output can expose decrypted values:
- name: Configure database
ansible.builtin.template:
src: db.conf.j2
dest: /etc/myapp/db.conf
no_log: true
Rotate Vault Passwords
ansible-vault rekey vars/vault.yml
# Enter old password, then new password
Or with files:
ansible-vault rekey --vault-password-file old_pass --new-vault-password-file new_pass vars/vault.yml
Git Integration
Add to .gitignore:
# Never commit vault passwords
.vault_pass*
*.vault_pass
Use a pre-commit hook to prevent unencrypted secrets:
#!/bin/bash
# .git/hooks/pre-commit
for file in $(git diff --cached --name-only | grep vault); do
if ! head -1 "$file" | grep -q '^\$ANSIBLE_VAULT'; then
echo "ERROR: $file is not encrypted!"
exit 1
fi
done
CI/CD Integration
GitHub Actions
- name: Run Ansible Playbook
env:
ANSIBLE_VAULT_PASSWORD: ${{ secrets.VAULT_PASSWORD }}
run: |
echo "$ANSIBLE_VAULT_PASSWORD" > /tmp/.vault_pass
ansible-playbook site.yml --vault-password-file /tmp/.vault_pass
rm /tmp/.vault_pass
GitLab CI
deploy:
script:
- echo "$VAULT_PASSWORD" > /tmp/.vault_pass
- ansible-playbook site.yml --vault-password-file /tmp/.vault_pass
- rm /tmp/.vault_pass
variables:
VAULT_PASSWORD: $ANSIBLE_VAULT_PASSWORD
Jenkins
withCredentials([string(credentialsId: 'ansible-vault-pass', variable: 'VAULT_PASS')]) {
sh """
echo "\$VAULT_PASS" > /tmp/.vault_pass
ansible-playbook site.yml --vault-password-file /tmp/.vault_pass
rm /tmp/.vault_pass
"""
}
Common Errors and Solutions
"Attempting to decrypt but no vault secrets found"
ERROR! Attempting to decrypt but no vault secrets found
Fix: Provide the vault password:
ansible-playbook site.yml --ask-vault-pass
# or
ansible-playbook site.yml --vault-password-file ~/.vault_pass
"Decryption failed"
Wrong vault password. Verify with:
ansible-vault view vars/vault.yml --ask-vault-pass
"input is not vault encrypted data"
The file isn't encrypted or is corrupted. Check the file header:
head -1 vars/vault.yml
# Should show: $ANSIBLE_VAULT;1.1;AES256
Vault vs External Secrets Managers
| Feature | Ansible Vault | HashiCorp Vault | AWS Secrets Manager |
|---|---|---|---|
| Cost | Free | Free/Paid | Pay per secret |
| Setup | None | Server required | AWS account |
| Dynamic secrets | No | Yes | Yes (rotation) |
| Access control | File-level | Policy-based | IAM-based |
| Audit logging | No | Yes | Yes |
| Best for | Small/medium teams | Enterprise | AWS-native |
For most teams, Ansible Vault is sufficient. Consider external secrets managers when you need dynamic secret rotation, fine-grained access control, or centralized audit logging.
Ansible Vault Video Series
- What is an Ansible Vault?
- Use Ansible Vault in Playbooks
- Decrypt an Ansible Vault
- Troubleshooting: No Vault Secrets Found
Related Articles
- Ansible no_log: Hide Sensitive Output
- Securing Ansible: Managing Sudo Passwords
- Ansible Best Practices Guide
- Understanding ansible.cfg Configuration
- Ansible Error Handling Guide
- How to Install Ansible
- Ansible Roles Guide
Conclusion
Ansible Vault provides practical, zero-infrastructure encryption for automation secrets. The essential workflow is: encrypt sensitive files with ansible-vault create/encrypt, use encrypt_string for inline secrets, reference vault variables through a vault_ prefix pattern, and always add no_log: true to tasks handling sensitive data. For CI/CD, pass the vault password through environment variables or secrets managers — never commit it to version control.