Introduction

Ansible Vault provides built-in encryption for protecting sensitive data in your automation workflows — passwords, API keys, certificates, and any secret that shouldn't exist in plaintext. Unlike external secrets managers, Vault is included with Ansible and requires zero additional infrastructure.

This guide covers all Vault operations from basic file encryption to advanced multi-vault setups and CI/CD integration.

Quick Start

Encrypt a File

ansible-vault encrypt vars/secrets.yml

You'll be prompted for a vault password. The file is encrypted in-place using AES-256.

Decrypt a File

ansible-vault decrypt vars/secrets.yml

View Encrypted File

ansible-vault view vars/secrets.yml

Edit Encrypted File

ansible-vault edit vars/secrets.yml

Opens the decrypted file in your $EDITOR, then re-encrypts on save.

Creating Vault-Encrypted Files

New Encrypted File

ansible-vault create vars/vault.yml

This opens your editor with an empty file. Add your secrets:

# vars/vault.yml (will be encrypted on save)
db_password: "SuperSecretP@ss123"
api_key: "sk-abc123def456"
ssl_private_key: |
  -----BEGIN PRIVATE KEY-----
  MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC7...
  -----END PRIVATE KEY-----

Encrypt Individual Strings

Use encrypt_string to encrypt a single value inline:

ansible-vault encrypt_string 'SuperSecretP@ss123' --name 'db_password'

Output:

db_password: !vault |
  $ANSIBLE_VAULT;1.1;AES256
  61626364656667686970...

Paste this directly into your variables file — only this value is encrypted, making the file partially readable:

# vars/main.yml
db_name: myapp_production
db_user: myapp
db_password: !vault |
  $ANSIBLE_VAULT;1.1;AES256
  61626364656667686970...
db_port: 5432

Using Vault in Playbooks

Password Prompt

ansible-playbook site.yml --ask-vault-pass

Password File

ansible-playbook site.yml --vault-password-file ~/.vault_pass

The password file is a plain text file containing just the password:

echo "MyVaultPassword123" > ~/.vault_pass
chmod 600 ~/.vault_pass

Password from Script

The password file can be an executable script:

#!/bin/bash
# ~/.vault_pass.sh
# Fetch from password manager
pass show ansible/vault-password
chmod +x ~/.vault_pass.sh
ansible-playbook site.yml --vault-password-file ~/.vault_pass.sh

Set Default in ansible.cfg

[defaults]
vault_password_file = ~/.vault_pass

Multiple Vault IDs

For environments with different security levels, use multiple vault passwords:

# Encrypt with a vault ID
ansible-vault encrypt --vault-id dev@prompt vars/dev-secrets.yml
ansible-vault encrypt --vault-id prod@~/.vault_pass_prod vars/prod-secrets.yml

Run playbooks with multiple vault IDs:

ansible-playbook site.yml \
  --vault-id dev@prompt \
  --vault-id prod@~/.vault_pass_prod

Vault ID in Encrypted Strings

ansible-vault encrypt_string --vault-id prod@prompt 'secret' --name 'api_key'

Output includes the vault ID:

api_key: !vault |
  $ANSIBLE_VAULT;1.2;AES256;prod
  31323334353637383930...

Best Practices

File Organization

Separate encrypted and unencrypted variables:

group_vars/
  production/
    vars.yml          # Non-sensitive defaults
    vault.yml         # Encrypted secrets
  staging/
    vars.yml
    vault.yml

Reference vault variables with a vault_ prefix:

# group_vars/production/vault.yml (encrypted)
vault_db_password: "SuperSecret123"
vault_api_key: "sk-abc123"

# group_vars/production/vars.yml (plaintext)
db_password: "{{ vault_db_password }}"
api_key: "{{ vault_api_key }}"

This makes it clear which variables come from the vault.

Always Use no_log

Even with Vault, task output can expose decrypted values:

- name: Configure database
  ansible.builtin.template:
    src: db.conf.j2
    dest: /etc/myapp/db.conf
  no_log: true

Rotate Vault Passwords

ansible-vault rekey vars/vault.yml
# Enter old password, then new password

Or with files:

ansible-vault rekey --vault-password-file old_pass --new-vault-password-file new_pass vars/vault.yml

Git Integration

Add to .gitignore:

# Never commit vault passwords
.vault_pass*
*.vault_pass

Use a pre-commit hook to prevent unencrypted secrets:

#!/bin/bash
# .git/hooks/pre-commit
for file in $(git diff --cached --name-only | grep vault); do
  if ! head -1 "$file" | grep -q '^\$ANSIBLE_VAULT'; then
    echo "ERROR: $file is not encrypted!"
    exit 1
  fi
done

CI/CD Integration

GitHub Actions

- name: Run Ansible Playbook
  env:
    ANSIBLE_VAULT_PASSWORD: ${{ secrets.VAULT_PASSWORD }}
  run: |
    echo "$ANSIBLE_VAULT_PASSWORD" > /tmp/.vault_pass
    ansible-playbook site.yml --vault-password-file /tmp/.vault_pass
    rm /tmp/.vault_pass

GitLab CI

deploy:
  script:
    - echo "$VAULT_PASSWORD" > /tmp/.vault_pass
    - ansible-playbook site.yml --vault-password-file /tmp/.vault_pass
    - rm /tmp/.vault_pass
  variables:
    VAULT_PASSWORD: $ANSIBLE_VAULT_PASSWORD

Jenkins

withCredentials([string(credentialsId: 'ansible-vault-pass', variable: 'VAULT_PASS')]) {
    sh """
        echo "\$VAULT_PASS" > /tmp/.vault_pass
        ansible-playbook site.yml --vault-password-file /tmp/.vault_pass
        rm /tmp/.vault_pass
    """
}

Common Errors and Solutions

"Attempting to decrypt but no vault secrets found"

ERROR! Attempting to decrypt but no vault secrets found

Fix: Provide the vault password:

ansible-playbook site.yml --ask-vault-pass
# or
ansible-playbook site.yml --vault-password-file ~/.vault_pass

"Decryption failed"

Wrong vault password. Verify with:

ansible-vault view vars/vault.yml --ask-vault-pass

"input is not vault encrypted data"

The file isn't encrypted or is corrupted. Check the file header:

head -1 vars/vault.yml
# Should show: $ANSIBLE_VAULT;1.1;AES256

Vault vs External Secrets Managers

FeatureAnsible VaultHashiCorp VaultAWS Secrets Manager
CostFreeFree/PaidPay per secret
SetupNoneServer requiredAWS account
Dynamic secretsNoYesYes (rotation)
Access controlFile-levelPolicy-basedIAM-based
Audit loggingNoYesYes
Best forSmall/medium teamsEnterpriseAWS-native

For most teams, Ansible Vault is sufficient. Consider external secrets managers when you need dynamic secret rotation, fine-grained access control, or centralized audit logging.

Ansible Vault Video Series

Conclusion

Ansible Vault provides practical, zero-infrastructure encryption for automation secrets. The essential workflow is: encrypt sensitive files with ansible-vault create/encrypt, use encrypt_string for inline secrets, reference vault variables through a vault_ prefix pattern, and always add no_log: true to tasks handling sensitive data. For CI/CD, pass the vault password through environment variables or secrets managers — never commit it to version control.