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:

  1. Prompts for a vault password (or reads from file)
  2. Opens your $EDITOR with a blank file
  3. Encrypts the saved content
  4. 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

IssueSolution
"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 openSet $EDITOR environment variable
"input is not vault encrypted data"File may be double-encrypted or corrupted
Can't find vault fileCheck vars_files path is relative to playbook

Best Practices

  1. One vault file per environment — group_vars/<env>/vault.yml
  2. Prefix vault variables — vault_ prefix for encrypted values
  3. Never commit password files — .vault_pass in .gitignore
  4. Use no_log: true — prevent secrets from appearing in output
  5. Use vault IDs — separate passwords for dev/staging/prod
  6. Rekey regularly — ansible-vault rekey when team members leave
  7. 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.