Securing Ansible Playbooks with Vault: Encryption, Best Practices, and Trade‑offs
Learn how to encrypt secrets in Ansible playbooks with Vault, manage multiple vault files, and avoid common pitfalls in CI/CD pipelines.
08 Aug 2025, 23:35 UTC

The Problem: Secrets in Plain Text
When you write a playbook that deploys a database or a cloud service, you often need to embed credentials, API keys, or other sensitive data. Storing those values directly in a YAML file means anyone with repository access can read them. Even if you lock down the repo, the secrets are still exposed in the playbook history and can be accidentally leaked in logs or comments.
Ansible Vault Basics
Ansible Vault is the built‑in tool for encrypting files and variables. It uses AES‑256 (Advanced Encryption Standard with a 256‑bit key) to protect the content. The encrypted data is still stored in the file, but the bytes look like random noise. Only a password or a key file can decrypt it.
Key concepts:
- Vault file – a YAML file whose entire contents are encrypted.
- Vault password – a string or a key file that decrypts the vault.
- --ask-vault-pass – prompts you for a password when running a playbook.
- vault password file – a file that contains the password; used in CI/CD to avoid interactive prompts.
- --vault-id – allows you to associate a file with a specific vault password or key file.
- --vault-cryptkey – specifies a custom key file for encryption (available since Ansible 2.10).
Managing Vault Files
Typical workflow:
- Create a vault file:
ansible-vault create secrets.yml– you’ll be prompted for a password. - Edit it later:
ansible-vault edit secrets.yml. - View the encrypted blob (without decrypting):
ansible-vault view secrets.yml. - Decrypt for debugging (only in local dev):
ansible-vault decrypt secrets.yml.
When you run a playbook that references secrets.yml, you can supply the password on the command line:
ansible-playbook -i inventory deploy.yml --ask-vault-pass
In production CI/CD pipelines, you typically keep the password outside the repo, e.g., in a secret store or a password manager, and reference it with --vault-password-file:
ansible-playbook -i inventory deploy.yml --vault-password-file /secure/path/.vault_pass
Using Multiple Vault Passwords
Large teams often have secrets that belong to different environments or services. Ansible lets you assign separate passwords to different vault files using --vault-id.
Example:
# secrets-prod.yml encrypted with prod key file
ansible-vault encrypt --vault-id prod@prod_keyfile secrets-prod.yml
# secrets-dev.yml encrypted with dev key file
ansible-vault encrypt --vault-id dev@dev_keyfile secrets-dev.yml
When running the playbook, provide the list of vault IDs in the same order the playbook references them:
ansible-playbook -i inventory deploy.yml --vault-id prod@prod_keyfile --vault-id dev@dev_keyfile
Beware: if you swap the order or forget one, Ansible will throw a decryption error that can be hard to trace.
Practical Example
Let’s walk through a minimal scenario:
- Create a vault file with a database password:
- Reference it in a playbook:
- Run with password prompt:
ansible-vault create db_secrets.yml
# Add line: db_password: "SuperSecret123"
---
- hosts: db_servers
vars_files:
- db_secrets.yml
tasks:
- name: Create database user
community.mysql.mysql_user:
name: app_user
password: "{{ db_password }}"
state: present
ansible-playbook -i inventory create_db.yml --ask-vault-pass
During execution, Ansible reads db_secrets.yml, decrypts the content in memory, and substitutes {{ db_password }} into the task. The decrypted value never touches the disk or the playbook repository.
Trade‑offs & Limitations
| Aspect | Benefit | Risk / Caveat |
|---|---|---|
| Encryption Strength | 256‑bit AES is industry standard. | Key management becomes critical; losing the password locks all data. |
| Runtime Overhead | Minimal for small files. | Large vault files can slow playbook start‑up; split into smaller files if needed. |
| Multiple Vaults | Granular control per environment. | Ordering of --vault-id flags matters; misconfiguration causes silent failures. |
| Version Control | Encrypted files can be committed safely. | Repository access still grants visibility of encrypted blobs; keep repo access restricted. |
Another subtle point: Ansible Vault encrypts only the file contents. If you store the file in a public repo, the encrypted data is visible but not useful without the password. However, if your CI/CD system pulls the repo, it must also have the vault password; otherwise the pipeline will abort.
Actionable Takeaways
- Keep
.vault_passout of source control. Store it in a password manager or CI secret store. - Separate secrets by environment:
secrets-dev.yml,secrets-prod.yml, each with its own password. - Use
--vault-idto map files to passwords; document the order in the playbook README. - When rotating a vault password, re‑encrypt all files:
ansible-vault rekey --new-vault-password-file new_passfile(note: this command is available in newer Ansible releases). - Regularly audit your vault files: run
ansible-vault viewto ensure they are still encrypted and that the password works.
By following these patterns, you can keep your secrets safe, avoid accidental leaks, and maintain a clear separation between code and data.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.