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.ymlorencryptan existing file. The whole file is ciphertext in git;ansible-vault editdecrypts it into your editor temporarily, andviewshows it. - Encrypted strings:
ansible-vault encrypt_string 's3cr3t' --name db_passwordproduces 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 passwordRemember
- 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.