Ansible Vault Create — Encrypt Files and Variables
Introduction
ansible-vault create generates a new encrypted file in one step — opening your editor with a blank file, then encrypting the saved content with AES-256. This is the starting point for managing secrets in Ansible: vault-encrypted files store passwords, API keys, certificates, and any sensitive data that must live in version control without being readable.
Basic Usage
# Create a new encrypted file (prompts for vault password)
ansible-vault create secrets.yml
# Create with a password file
ansible-vault create --vault-password-file ~/.vault_pass secrets.yml
# Create with a vault ID (multi-vault)
ansible-vault create --vault-id prod@prompt secrets.yml
# Create with specific editor
EDITOR=nano ansible-vault create secrets.yml
When you run ansible-vault create, it:
- Prompts for a vault password (or reads from file)
- Opens your
$EDITORwith a blank file - Encrypts the saved content
- Writes the encrypted file to disk
Create group_vars Secrets
# Create encrypted secrets per environment
ansible-vault create group_vars/production/vault.yml
ansible-vault create group_vars/staging/vault.yml
ansible-vault create group_vars/all/vault.yml
# Content to type in editor (group_vars/production/vault.yml):
---
vault_db_password: "SuperSecretProd123!"
vault_api_key: "ak_prod_abc123def456"
vault_ssl_private_key: |
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBg...
-----END PRIVATE KEY-----
vault_smtp_password: "email_secret_789"
Variable Naming Convention
# vault.yml (encrypted) — prefix with vault_
vault_db_password: "actual_secret"
vault_api_token: "real_token"
# vars.yml (plain text) — reference vault_ variables
db_password: "{{ vault_db_password }}"
api_token: "{{ vault_api_token }}"
This lets you grep for variable usage without decrypting vault files.
Other Vault Commands
# Encrypt an existing file
ansible-vault encrypt existing-secrets.yml
# View encrypted file (read-only)
ansible-vault view secrets.yml
# Edit encrypted file
ansible-vault edit secrets.yml
# Decrypt file (removes encryption)
ansible-vault decrypt secrets.yml
# Change vault password
ansible-vault rekey secrets.yml
# Encrypt a single string
ansible-vault encrypt_string 'MySecret' --name 'db_password'
Using Encrypted Files in Playbooks
---
- name: Deploy with secrets
hosts: webservers
vars_files:
- group_vars/production/vault.yml
tasks:
- name: Configure database
ansible.builtin.template:
src: db.conf.j2
dest: /etc/myapp/db.conf
mode: '0600'
no_log: true
# Run playbook with vault password prompt
ansible-playbook deploy.yml --ask-vault-pass
# Run with password file
ansible-playbook deploy.yml --vault-password-file ~/.vault_pass
# Run with vault ID
ansible-playbook deploy.yml --vault-id prod@~/.vault_pass_prod
Password File Setup
# Create password file
echo 'YourVaultPassword123!' > ~/.vault_pass
chmod 600 ~/.vault_pass
# Add to ansible.cfg so you don't need --vault-password-file every time
# [defaults]
# vault_password_file = ~/.vault_pass
# IMPORTANT: Add to .gitignore
echo '.vault_pass' >> .gitignore
Multi-Vault with Vault IDs
# Create files with different vault IDs
ansible-vault create --vault-id dev@prompt group_vars/dev/vault.yml
ansible-vault create --vault-id prod@~/.vault_pass_prod group_vars/prod/vault.yml
# Run with multiple vault IDs
ansible-playbook site.yml \
--vault-id dev@prompt \
--vault-id prod@~/.vault_pass_prod
Project Structure
my-project/
├── ansible.cfg
├── .gitignore # Contains .vault_pass
├── .vault_pass # NOT in git
├── inventory/
├── group_vars/
│ ├── all/
│ │ ├── vars.yml # Plain text references
│ │ └── vault.yml # Encrypted secrets
│ ├── production/
│ │ ├── vars.yml
│ │ └── vault.yml # Encrypted
│ └── staging/
│ ├── vars.yml
│ └── vault.yml # Encrypted
├── roles/
└── playbooks/
CI/CD Integration
# GitHub Actions
- name: Run Ansible
env:
ANSIBLE_VAULT_PASSWORD: ${{ secrets.VAULT_PASSWORD }}
run: |
echo "$ANSIBLE_VAULT_PASSWORD" > .vault_pass
chmod 600 .vault_pass
ansible-playbook -i inventory site.yml --vault-password-file .vault_pass
rm -f .vault_pass
Troubleshooting
| Issue | Solution |
|---|---|
| "Decryption failed" | Wrong vault password; check password file |
| "is not a vault encrypted file" | File wasn't created with ansible-vault create/encrypt |
| "No vault secrets found" | Pass --ask-vault-pass or --vault-password-file |
| Editor doesn't open | Set $EDITOR environment variable |
| "input is not vault encrypted data" | File may be double-encrypted or corrupted |
| Can't find vault file | Check vars_files path is relative to playbook |
Best Practices
- One vault file per environment —
group_vars/<env>/vault.yml - Prefix vault variables —
vault_prefix for encrypted values - Never commit password files —
.vault_passin.gitignore - Use
no_log: true— prevent secrets from appearing in output - Use vault IDs — separate passwords for dev/staging/prod
- Rekey regularly —
ansible-vault rekeywhen team members leave - Encrypt files, not entire directories — keep plain text vars separate
Conclusion
ansible-vault create is your starting point for secrets management in Ansible. Create encrypted files for each environment, follow the vault_ variable naming convention, set up a password file in ansible.cfg, and your secrets live safely in version control — encrypted at rest, decrypted only at runtime.