Secrets with Ansible Vault

Ansible · Practical · 8 min

Playbooks need passwords and keys; committing them in plain text is a breach waiting to happen.

Ansible Vault encrypts data with AES-256 using a password you supply at run time.

Two styles:

  • Encrypted files: ansible-vault create group_vars/prod/vault.yml or encrypt an existing file. The whole file is ciphertext in git; ansible-vault edit decrypts it into your editor temporarily, and view shows it.
  • Encrypted strings: ansible-vault encrypt_string 's3cr3t' --name db_password produces a !vault | block you paste into an otherwise readable vars file.

A widely used convention: in group_vars/prod/, keep vars.yml readable with db_password: "{{ vault_db_password }}", and vault.yml encrypted with vault_db_password: .... You can grep for every variable name while secrets stay encrypted.

Supplying the password: --ask-vault-pass, or --vault-password-file pointing to a file or to an executable script that fetches it from a secret manager (the usual choice in CI). Vault IDs (--vault-id prod@prompt) allow different passwords per environment.

Add no_log: true to tasks that handle secrets, so values don't appear in output or logs.

Vault protects data at rest in git; anyone with the vault password, or root on a target, still sees the secrets. For dynamic secrets, lookup plugins for HashiCorp Vault, AWS Secrets Manager and others fetch values at run time instead.

Example

ansible-vault create group_vars/prod/vault.yml      # opens $EDITOR, saves encrypted
ansible-vault encrypt_string 'S3cr3t!' --name vault_db_password
# vault_db_password: !vault |
#           $ANSIBLE_VAULT;1.1;AES256
#           6231363436643837...

cat group_vars/prod/vars.yml
# db_password: "{{ vault_db_password }}"     # readable indirection

ansible-playbook -i inventory.yml site.yml --vault-password-file ~/.vault-pass.sh
ansible-vault rekey group_vars/prod/vault.yml          # rotate the vault password

Remember

  • Encrypt whole files or single strings; edit with ansible-vault edit
  • vars.yml points to vault_ variables in vault.yml
  • no_log: true on tasks handling secrets

Watch out for

  • Printing secrets with debug or failing tasks without no_log, leaking them into CI logs.

Check yourself

  1. What is the benefit of keeping db_password: "{{ vault_db_password }}" in an unencrypted vars file?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.ansible.com/ansible/latest/vault_guide/index.html