Ansible Vault & secrets

Encrypt secrets in your repo.

Advanced14 min · lesson 9 of 12

Playbooks and variables often need secrets — a database password, an API token, a private key — and those cannot sit in plaintext in a Git repo. Ansible Vault encrypts variables or whole files with a password, so the ciphertext is safe to commit; at run time you supply the Vault password and Ansible decrypts in memory. It is Ansible’s built-in answer to “how do I keep secrets in version control.”

terminal
$ ansible-vault create group_vars/prod/vault.yml # opens an editor, saves encrypted
$ ansible-vault encrypt_string 'S3cr3t!' --name db_password
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
66386439653... # safe to commit
$ ansible-playbook site.yml --ask-vault-pass # or --vault-password-file

Patterns that scale

Two habits make Vault work on a team. Encrypt individual strings (encrypt_string) so a vars file stays readable with only the secret values encrypted, rather than an opaque encrypted blob. And supply the password non-interactively in automation via a vault-password-file or a script that fetches it from a real secret store — so CI can decrypt without a human typing, while the password itself never lands in the repo.

terminal
# CI: fetch the vault password from a secret store into a file, then run
$ ansible-playbook site.yml --vault-password-file ./.vault-pass.sh
# .vault-pass.sh prints the password (pulled from Vault/CI secret) to stdout
Vault protects data at rest, not the password
Ansible Vault is only as strong as the password guarding it — a weak or shared Vault password, or one committed alongside the data, defeats the whole thing. Store the Vault password in a real secret manager (or your CI’s secret store), never in the repo; rotate it if it leaks; and remember decrypted values can still show in verbose output, so use no_log: true on tasks that handle them.