Ansible Vault¶
Ansible Vault encrypts variables and files so secrets can live alongside playbooks without being stored in plaintext. The willhallonline/ansible image includes Ansible Vault commands.
Never bake Vault secrets into images
Mount Vault password files or inject them at runtime. Do not copy Vault passwords into Dockerfiles, derived images, or committed files.
Create an encrypted file¶
docker run --rm -it \
-v $(pwd):/ansible \
--workdir=/ansible \
willhallonline/ansible:latest \
ansible-vault create group_vars/production/vault.yml
Set an editor if needed:
docker run --rm -it \
-v $(pwd):/ansible \
--workdir=/ansible \
-e EDITOR=vi \
willhallonline/ansible:latest \
ansible-vault create group_vars/production/vault.yml
Edit an encrypted file¶
docker run --rm -it \
-v $(pwd):/ansible \
--workdir=/ansible \
-e EDITOR=vi \
willhallonline/ansible:latest \
ansible-vault edit group_vars/production/vault.yml
View an encrypted file¶
docker run --rm -it \
-v $(pwd):/ansible \
--workdir=/ansible \
willhallonline/ansible:latest \
ansible-vault view group_vars/production/vault.yml
Encrypt an existing file¶
docker run --rm -it \
-v $(pwd):/ansible \
--workdir=/ansible \
willhallonline/ansible:latest \
ansible-vault encrypt group_vars/production/secrets.yml
Decrypt temporarily¶
docker run --rm -it \
-v $(pwd):/ansible \
--workdir=/ansible \
willhallonline/ansible:latest \
ansible-vault decrypt group_vars/production/secrets.yml
Re-encrypt after editing:
docker run --rm -it \
-v $(pwd):/ansible \
--workdir=/ansible \
willhallonline/ansible:latest \
ansible-vault encrypt group_vars/production/secrets.yml
Tip
Prefer ansible-vault edit to decrypting files to disk. It reduces the chance of leaving plaintext secrets behind.
Run with an interactive Vault prompt¶
docker run --rm -it \
-v $(pwd):/ansible \
-v ~/.ssh/id_rsa:/home/ansible/.ssh/id_rsa:ro \
--workdir=/ansible \
willhallonline/ansible:latest \
ansible-playbook -i inventory.ini site.yml --ask-vault-pass
The prompt requires -it. In non-interactive CI, use a mounted password file or injected secret.
Use a Vault password file¶
Create the file outside the repository:
mkdir -p ~/.ansible
chmod 700 ~/.ansible
printf '%s
' 'replace-with-your-vault-password' > ~/.ansible/vault-pass.txt
chmod 600 ~/.ansible/vault-pass.txt
Mount it read-only:
docker run --rm -it \
-v $(pwd):/ansible \
-v ~/.ansible/vault-pass.txt:/run/secrets/vault-pass.txt:ro \
--workdir=/ansible \
willhallonline/ansible:latest \
ansible-playbook -i inventory.ini site.yml \
--vault-password-file /run/secrets/vault-pass.txt
Use the same pattern for Vault commands:
docker run --rm -it \
-v $(pwd):/ansible \
-v ~/.ansible/vault-pass.txt:/run/secrets/vault-pass.txt:ro \
--workdir=/ansible \
willhallonline/ansible:latest \
ansible-vault view group_vars/production/vault.yml \
--vault-password-file /run/secrets/vault-pass.txt
Use ANSIBLE_VAULT_PASSWORD_FILE¶
docker run --rm -it \
-v $(pwd):/ansible \
-v ~/.ansible/vault-pass.txt:/run/secrets/vault-pass.txt:ro \
--workdir=/ansible \
-e ANSIBLE_VAULT_PASSWORD_FILE=/run/secrets/vault-pass.txt \
willhallonline/ansible:latest \
ansible-playbook -i inventory.ini site.yml
You can also configure it in ansible.cfg when every environment uses the same path:
Multiple Vault IDs¶
Use Vault IDs to separate environments:
docker run --rm -it \
-v $(pwd):/ansible \
-v ~/.ansible/dev-pass.txt:/run/secrets/dev-pass.txt:ro \
-v ~/.ansible/prod-pass.txt:/run/secrets/prod-pass.txt:ro \
--workdir=/ansible \
willhallonline/ansible:latest \
ansible-playbook -i inventory.ini site.yml \
--vault-id dev@/run/secrets/dev-pass.txt \
--vault-id prod@/run/secrets/prod-pass.txt
Create a file for one Vault ID:
docker run --rm -it \
-v $(pwd):/ansible \
-v ~/.ansible/prod-pass.txt:/run/secrets/prod-pass.txt:ro \
--workdir=/ansible \
willhallonline/ansible:latest \
ansible-vault create group_vars/production/vault.yml \
--vault-id prod@/run/secrets/prod-pass.txt
CI considerations¶
Inject Vault passwords from CI secrets, write them to a short-lived file, mount that file, and prevent it from becoming an artifact:
script:
- mkdir -p .secrets
- printf '%s' "$ANSIBLE_VAULT_PASSWORD" > .secrets/vault-pass.txt
- chmod 600 .secrets/vault-pass.txt
- |
docker run --rm \
-v "$PWD:/ansible" \
-v "$PWD/.secrets/vault-pass.txt:/run/secrets/vault-pass.txt:ro" \
--workdir=/ansible \
willhallonline/ansible:latest \
ansible-playbook -i inventory.ini site.yml \
--vault-password-file /run/secrets/vault-pass.txt
Do not print Vault passwords in logs. Clean up secret files if your CI runner reuses workspaces.