Ansible Vault encrypts sensitive data (passwords, API keys, certificates) using AES-256 encryption so secrets can be safely committed to version control. This lab covers vault create/edit/encrypt/decrypt, vault password files, encrypt_string for inline secrets, vault IDs for multi-vault setups, and CI/CD best practices.
💡 Tip: NEVER commit plain-text vault password files to git. Add *.vault_pass, .vault_pass, and vault_password to your .gitignore. Store vault passwords in a password manager, secrets manager (HashiCorp Vault, AWS Secrets Manager), or CI/CD environment variables.
Step 2: Decrypt, View, and Edit Vault Files
📸 Verified Output:
💡 Tip:ansible-vault view decrypts to stdout without modifying the file — use this for safe inspection. ansible-vault edit opens the file in $EDITOR, decrypts in memory, and re-encrypts on save. ansible-vault rekey is essential for regular password rotation.
💡 Tip:encrypt_string is the preferred approach for most use cases — it lets you keep non-sensitive variables as plain text in the same file, only encrypting the secrets. This makes code reviews easier since reviewers can see variable names and structure without exposing values.
Step 4: Vault Password Files and --ask-vault-pass
📸 Verified Output:
💡 Tip: For CI/CD pipelines: store the vault password as a CI secret (GitHub Secret, GitLab CI Variable, Jenkins Credential), inject it as VAULT_PASSWORD env var, and use a small Python script to print it. Never hardcode vault passwords in pipeline YAML files.
Step 5: Vault IDs — Multiple Vault Passwords
📸 Verified Output:
💡 Tip: Notice the vault header changes from $ANSIBLE_VAULT;1.1;AES256 to $ANSIBLE_VAULT;1.2;AES256;dev when using vault IDs. This allows Ansible to automatically select the correct password from the provided list without trial and error.
Step 6: Encrypting group_vars for Production
📸 Verified Output:
💡 Tip: The vault_ prefix convention is a best practice. It makes code reviews clean (reviewers see db_password: "{{ vault_db_password }}" and know a secret is involved) while keeping the encrypted data separate. Search for vault_ to audit all secrets in a project instantly.
Step 7: CI/CD Integration Patterns
📸 Verified Output:
💡 Tip: The audit commands are essential for security reviews. Run grep -rl '$ANSIBLE_VAULT' . to confirm all secret files are encrypted. Run the unencrypted check as a pre-commit hook to prevent accidental secret commits. Tools like detect-secrets and git-secrets provide more comprehensive scanning.
Step 8: Capstone — Full Secrets Workflow for Multi-Environment Deployment
Scenario: You're setting up a multi-environment deployment (dev/prod) with Ansible Vault. Different teams manage different environments with separate vault passwords. Implement the complete secrets workflow including encryption, playbook integration, and verification.
📸 Verified Output:
💡 Tip: In production, never decrypt vault files permanently. Use ansible-vault view for inspection. Rotate vault passwords quarterly using ansible-vault rekey. Implement vault password rotation as part of your incident response plan — if a vault password is compromised, you can rekey all encrypted files without changing the actual secrets.
=== Project structure ===
/tmp/project/ansible.cfg
/tmp/project/group_vars/all/main.yml
/tmp/project/group_vars/all/vault.yml
=== Methods to provide vault password ===
1. --vault-password-file /path/.vault_pass
2. --ask-vault-pass (interactive prompt)
3. ANSIBLE_VAULT_PASSWORD_FILE env var
4. vault_password_file in ansible.cfg
=== ansible.cfg vault integration ===
[defaults]
vault_password_file = ~/.vault_pass
=== Using env var (CI/CD pattern) ===
export ANSIBLE_VAULT_PASSWORD_FILE=/tmp/.vault_pass
ansible-playbook site.yml # No password flags needed
=== Script-based password provider ===
Script vault provider created
Usage: ansible-playbook site.yml --vault-password-file /tmp/vault_pass_script.py
docker run --rm ubuntu:22.04 bash -c "
apt-get update -qq 2>/dev/null && apt-get install -y -qq python3-pip python3 2>/dev/null
pip3 install ansible --quiet 2>/dev/null
echo '=== Create vault passwords for different environments ==='
echo 'DevVaultPassword' > /tmp/.vault_pass_dev
echo 'ProdVaultPassword' > /tmp/.vault_pass_prod
chmod 600 /tmp/.vault_pass_dev /tmp/.vault_pass_prod
echo '=== Encrypt with vault ID ==='
ansible-vault encrypt_string 'DevDBPass123' \
--name 'db_password' \
--vault-id dev@/tmp/.vault_pass_dev
echo ''
ansible-vault encrypt_string 'ProdDBPass!@#' \
--name 'db_password' \
--vault-id prod@/tmp/.vault_pass_prod
echo ''
echo '=== Vault ID format: label@password_source ==='
echo 'Examples:'
echo ' dev@/path/.vault_pass_dev'
echo ' prod@/path/.vault_pass_prod'
echo ' dev@prompt (interactive)'
echo ' prod@/scripts/get_vault_pass.py'
echo ''
echo '=== Decrypt with multiple vault IDs ==='
echo 'ansible-playbook site.yml \'
echo ' --vault-id dev@/tmp/.vault_pass_dev \'
echo ' --vault-id prod@/tmp/.vault_pass_prod'
echo ''
echo '=== ANSIBLE_VAULT_IDENTITY_LIST env var ==='
echo 'export ANSIBLE_VAULT_IDENTITY_LIST=\"dev@/tmp/.vault_pass_dev,prod@/tmp/.vault_pass_prod\"'
echo ''
echo '=== When to use vault IDs ==='
cat << 'EOF'
Use Cases for Multiple Vault IDs:
1. Different encryption keys per environment (dev/staging/prod)
2. Different teams have different vault passwords (infra vs app team)
3. Rotating vault passwords without re-encrypting everything at once
4. Mixing user-prompted passwords with file-based passwords
EOF
"
=== Create vault passwords for different environments ===
=== Encrypt with vault ID ===
db_password: !vault |
$ANSIBLE_VAULT;1.2;AES256;dev
39383962316536626137653735313931623935333265303166353039633961326462613439633431
...
db_password: !vault |
$ANSIBLE_VAULT;1.2;AES256;prod
32363333393164636437306263386333373363663166306466643566373235393532336638383733
...
=== Vault ID format: label@password_source ===
Examples:
dev@/path/.vault_pass_dev
prod@/path/.vault_pass_prod
dev@prompt (interactive)
prod@/scripts/get_vault_pass.py
=== When to use vault IDs ===
Use Cases for Multiple Vault IDs:
1. Different encryption keys per environment (dev/staging/prod)
2. Different teams have different vault passwords (infra vs app team)
3. Rotating vault passwords without re-encrypting everything at once
4. Mixing user-prompted passwords with file-based passwords