Lab 09: Ansible Vault — Secrets Management

Time: 45 minutes | Level: Architect | Docker: docker run -it --rm ubuntu:22.04 bash

Overview

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.

Prerequisites

  • Completed Lab 06 (Ansible Foundations)

  • Understanding of symmetric encryption concepts

  • Basic CI/CD pipeline knowledge


Step 1: ansible-vault Basics — Create and View

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 '=== ansible-vault version ==='
ansible-vault --version | head -3

echo ''
echo '=== Create a vault password file ==='
echo 'MyS3cretVaultP@ssword' > /tmp/.vault_pass
chmod 600 /tmp/.vault_pass
echo 'Vault password file created (chmod 600)'

echo ''
echo '=== Create encrypted file ==='
cat > /tmp/secrets_plain.yml << 'EOF'
---
db_password: SuperSecret123!
api_key: sk-prod-abc123xyz789
ssl_private_key: |
  -----BEGIN RSA PRIVATE KEY-----
  MIIEowIBAAKCAQEA...
  -----END RSA PRIVATE KEY-----
smtp_password: MailPass456!
EOF

ansible-vault encrypt /tmp/secrets_plain.yml --vault-password-file /tmp/.vault_pass
echo 'File encrypted successfully'

echo ''
echo '=== View encrypted file (raw) ==='
cat /tmp/secrets_plain.yml
"

📸 Verified Output:

💡 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.


Step 3: encrypt_string — Inline Encrypted Variables

📸 Verified Output:

💡 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.


Summary

Operation
Command
Notes

Create encrypted file

ansible-vault create secrets.yml

Opens editor

Encrypt existing file

ansible-vault encrypt file.yml

Modifies in place

View encrypted file

ansible-vault view secrets.yml

Decrypts to stdout

Edit encrypted file

ansible-vault edit secrets.yml

Decrypt → edit → re-encrypt

Decrypt file

ansible-vault decrypt file.yml

Removes encryption

Encrypt string

ansible-vault encrypt_string 'value' --name 'var'

For inline secrets

Rekey (rotate password)

ansible-vault rekey file.yml --new-vault-password-file

Password rotation

Password file

--vault-password-file /path/.vault_pass

File-based password

Interactive password

--ask-vault-pass

Prompt at runtime

Vault ID

--vault-id label@/path/.vault_pass

Multi-vault support

vault_ prefix

vault_db_password in vault.yml

Naming convention

Audit encrypted

grep -rl '$ANSIBLE_VAULT' .

Find all vault files

CI/CD env var

ANSIBLE_VAULT_PASSWORD_FILE=/dev/stdin

Inject from secrets

Encrypt header

$ANSIBLE_VAULT;1.1;AES256

Standard format

Vault ID header

$ANSIBLE_VAULT;1.2;AES256;label

With vault ID

Last updated