Secure Ansible Secrets with Vault – A Practical Guide
Learn how to encrypt passwords, API keys, and configuration snippets in Ansible using Vault. Follow a step‑by‑step example, integrate non‑interactive decryption into CI, and avoid common pitfalls.
03 Jun 2026, 02:21 UTC

Why Ansible Vault?
Ansible Vault is a built‑in mechanism that protects sensitive data at rest. When you encrypt a file or a string with Vault, the resulting ciphertext can be stored in source control or shared with teammates without exposing the plain‑text secret. During playbook execution, Ansible automatically decrypts the data on the controller node, ensuring that target hosts never see the raw secret.
How Vault Works
Vault uses a symmetric encryption algorithm (AES‑256 in CBC mode) and derives the encryption key from a password or a key file. The key material is never written to disk; it is kept in memory only while the playbook runs. Because the key is supplied at runtime, you can keep the encrypted files in a public repository and still protect the secrets.
Encrypting a Secret String
When you need to embed a single secret directly in a playbook, use ansible-vault encrypt_string. This command outputs a string that can be pasted into a variable definition.
# Create a one‑time password (or use a stored password file)
export VAULT_PASS=SuperSecretPassword123
# Encrypt a literal value
ansible-vault encrypt_string "db_password=SuperSecret123" \
--vault-password-file $HOME/.vault_pass.txt \
--name db_creds
The command prints:
db_creds: !vault |
$ANSIBLE_VAULT;1.1;AES256
613562313233... (ciphertext)
Paste the entire block into your playbook or a vars file. During execution, Ansible will decrypt db_creds automatically.
Encrypting an Entire File
For larger secrets files (e.g., a JSON key file), encrypt the whole file:
# Encrypt the file
ansible-vault encrypt secrets.json \
--vault-password-file $HOME/.vault_pass.txt
# Verify encryption (the file will now be unreadable)
cat secrets.json
The file will contain a header like $ANSIBLE_VAULT;1.1;AES256 followed by the ciphertext. To restore, run:
ansible-vault decrypt secrets.json \
--vault-password-file $HOME/.vault_pass.txt
Using Vault in a Playbook
Reference the encrypted variable or file in your tasks. Example playbook:
- hosts: webservers
vars_files:
- secrets.json
tasks:
- name: Install application
apt:
name: myapp
state: present
- name: Configure application
template:
src: app.conf.j2
dest: /etc/myapp/config.conf
vars:
db_password: {{ db_creds.db_password }}
When you run the playbook, supply the vault password interactively or via a file:
ansible-playbook site.yml \
--ask-vault-pass
# or
ansible-playbook site.yml \
--vault-password-file $HOME/.vault_pass.txt
In both cases, Ansible will decrypt db_creds and secrets.json before the tasks execute.
Non‑Interactive Decryption for CI
Continuous‑integration pipelines should avoid interactive prompts. Store the vault password in a protected file that the CI runner can read, but keep it out of the repository. Example GitHub Actions step:
- name: Run playbook
run: |
ansible-playbook site.yml \
--vault-password-file ${{ secrets.VAULT_PASS_FILE }}
Here ${{ secrets.VAULT_PASS_FILE }} is a GitHub secret pointing to a file in the runner’s environment. This keeps the key out of the code base while allowing automated runs.
Common Mistakes and Limits
- Storing the vault password in source control. The password file should never be committed. Use environment variables or secret management tooling to inject it at runtime.
- Assuming Vault protects data on the target host. The encryption protects only at rest on the controller. If the controller’s filesystem is compromised, the ciphertext can be read, but the plaintext remains safe until decryption.
- Using the same password for all vaults. For higher security, rotate passwords and use separate vaults for different teams or environments.
- Relying on Vault for system hardening. It does not replace OS‑level encryption or network hardening; it only secures Ansible data.
Verifying Vault Integration
After encrypting, run a quick test to ensure decryption works:
# Decrypt manually to confirm
ansible-vault decrypt secrets.json \
--vault-password-file $HOME/.vault_pass.txt
# Run the playbook and watch the output of a debug task
ansible-playbook site.yml \
--vault-password-file $HOME/.vault_pass.txt \
--tags debug
The debug task should print the decrypted value without raising an error. If decryption fails, Ansible will abort with a ERROR! Ansible failed to decrypt vault data. message.
Practical Checklist
| Step | Action | Check |
|---|---|---|
| 1 | Encrypt secrets with a robust password or key file. | File shows $ANSIBLE_VAULT header. |
| 2 | Store encrypted files in version control. | No plaintext visible. |
| 3 | Keep the vault password out of the repository. | Use environment variable or CI secret. |
| 4 | Reference encrypted data in playbooks. | Playbook runs without decryption errors. |
| 5 | Test decryption manually. | Plaintext restored correctly. |
By following this workflow, you can confidently store and use sensitive data in Ansible while keeping the secrets protected at rest and during execution.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.