Choosing Between Ansible Vault and HashiCorp Vault for Secret Management
Decide whether to encrypt secrets with Ansible Vault or fetch them at runtime from HashiCorp Vault, based on offline needs, rotation requirements, and pipeline constraints.
18 Sept 2025, 05:15 UTC

Decision and Constraints
You need to store sensitive variables such as passwords or API keys used in Ansible playbooks without committing plaintext to version control. The solution must add minimal runtime overhead and work with your existing CI/CD pipelines.
Options Comparison
| Option | How Secrets Are Stored | Retrieval Method | Typical Use‑Case |
|---|---|---|---|
| Ansible Vault | Symmetric encryption of a vars file (AES256) | Decrypted at playbook run time using a vault ID or password prompt | Simple, offline environments where you can manage a vault password securely |
| External Secret Manager (HashiCorp Vault) | Secrets live in a centralized Vault server | Fetched at runtime via a lookup plugin (e.g., community.hashi_vault.hashi_vault) | Environments that require rotation, audit logging, fine‑grained access control |
Trade‑offs
- Ansible Vault: simplest setup, no extra services, works offline; however, secret rotation requires re‑encrypting the file and distributing the new vault password.
- External Secret Manager: provides automated rotation, detailed access logs, and fine‑grained policies; introduces a network dependency, requires the lookup plugin and Vault server to be reachable from the control node and any delegated targets, and adds plugin maintenance overhead.
Implementation Example
Using Ansible Vault
- Create an encrypted vars file:
ansible-vault create vars/secrets.yml --vault-id my_vault@prompt - Add your secret, e.g.:
db_password: "s3cr3t" - Save and exit; the file is now ciphertext.
- Reference it in a playbook:
- hosts: app
vars_files:
- vars/secrets.yml
tasks:
- name: Show masked secret
debug:
msg: "DB password is {{ db_password | password_hash('sha256') }}" - Run the playbook providing the vault ID:
ansible-playbook site.yml --vault-id my_vault@prompt
Using HashiCorp Vault via Lookup Plugin
- Install the collection:
ansible-galaxy collection install community.hashi_vault - Ensure the Vault server is reachable and you have a token with read permission on the secret path, e.g.,
secret/myapp/data/db - In your playbook, fetch the secret with a lookup:
- name: Retrieve DB password
set_fact:
db_password: "{{ lookup('community.hashi_vault.hashi_vault', 'secret=myapp/data/db password') }}" - Use the variable as needed, making sure not to log it directly.
Validation and Checks
- For Vault‑encrypted files, run
ansible-vault view vars/secrets.yml --vault-id my_vault@promptto confirm you can decrypt the content. - Run
ansible-playbook site.yml --check --diff --vault-id my_vault@promptand verify the output shows no plaintext secret values. - When using the lookup plugin, add a debug task that masks the value, e.g.,
debug: msg: "Retrieved secret length: {{ db_password | length }}"and confirm the task executes without error. - Use
ansible-lintoransible-playbook --syntax-checkto ensure no plaintext secrets appear in any .yml files.
Limitations
Ansible Vault does not provide automatic rotation or audit trails; you must manage the vault password securely and rotate it manually. The HashiCorp Vault approach requires network connectivity from every machine that runs the playbook, and the lookup plugin version must match the Ansible collection you installed; a mismatch can cause lookup failures.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.