Guide to Securing Configuration Secrets Using Ansible Vault Effectively

Secure Ansible secrets with Vault commands, encrypted variable files, password handling, and practical playbook usage.

Guide to Securing Configuration Secrets Using Ansible Vault Effectively

Ansible Vault helps you keep configuration secrets out of plain text while still using normal Ansible variables. If your playbooks contain database passwords, API keys, or private keys, committing them unencrypted can turn a routine repository leak into an infrastructure incident.

Ansible Vault encrypts structured variable files or individual values and decrypts them only when Ansible has the vault password. This guide shows the commands you will actually use, how to load vaulted variables in playbooks, and where teams usually make mistakes.

Understanding Ansible Vault Core Concepts

Ansible Vault uses strong symmetric encryption (AES256) to protect data. The core mechanism requires a Vault Password which acts as the master key. This password must be provided to Ansible whenever it needs to access or modify encrypted content.

Why Use Ansible Vault?

  • Security: Keeps sensitive data encrypted at rest, protecting against repository breaches.
  • Compliance: Helps meet industry standards (e.g., PCI DSS, SOC 2) requiring encryption of credentials.
  • Workflow: Allows configuration files containing secrets to be safely committed to version control systems (like Git).

Essential Ansible Vault Commands

The ansible-vault command is a standalone utility used for managing encrypted files outside of a playbook run.

1. Creating a New Vaulted File

To create a new file specifically intended for secrets, use the create command. This immediately prompts you for a new vault password and then opens the file in your default text editor ($EDITOR).

ansible-vault create secrets/db_passwords.yml

Example Content (db_passwords.yml after saving):

# This file is encrypted
db_user: app_admin
db_pass: HighlySecurePassword123!
api_key: abc-123-def-456

After saving and closing the editor, the content is encrypted, and the file is ready to be committed to version control.

2. Viewing Encrypted Content

If you need to quickly inspect the contents of a vaulted file without editing it, use the view command. You will be prompted for the vault password.

ansible-vault view secrets/db_passwords.yml

3. Editing an Existing Vaulted File

The edit command is the primary way to modify secrets. Ansible decrypts the file, opens it in your editor, and upon saving, re-encrypts the file automatically.

ansible-vault edit secrets/db_passwords.yml

Tip: Ensure your $EDITOR environment variable is set correctly (e.g., export EDITOR=vim) for a smooth editing experience.

4. Encrypting and Decrypting Existing Files

If you have an existing plain-text file that needs to be secured, use the encrypt command. Conversely, decrypt is used to revert an encrypted file back to plain text (used cautiously, usually for migration).

# Encrypt an existing file
ansible-vault encrypt plain_vars.yml

# Decrypt an existing vaulted file (Dangerous! Only use if necessary)
ansible-vault decrypt secured_vars.yml

5. Changing the Vault Password (Rekey)

To update the master password for a vaulted file, use the rekey command. This requires you to provide the current password and then set a new one.

ansible-vault rekey secrets/db_passwords.yml

This is essential for security rotations or when transitioning to a new credential management system.

Integrating Vaulted Secrets into Ansible Playbooks

Once files are encrypted, you need a method to load them during playbook execution and supply the necessary vault password.

Loading Encrypted Variables

Encrypted variable files are loaded just like any other variable file, typically using the vars_files directive in your playbook.

Playbook Example (site.yml):

---
- name: Deploy application requiring database secrets
  hosts: webservers
  vars_files:
    - secrets/db_passwords.yml  # Ansible automatically detects this is vaulted

  tasks:
    - name: Ensure database user is configured
      ansible.builtin.template:
        src: config.j2
        dest: /etc/app/config.conf
        mode: '0600'
      # Variables like {{ db_user }} and {{ db_pass }} are now available

Supplying the Vault Password During Execution

Ansible offers several secure methods to provide the vault password without leaving it exposed in history or scripts.

Method 1: Interactive Prompt

The simplest method is to use the --ask-vault-pass flag, which prompts the user for the password securely at runtime.

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

Method 2: Using a Password File

For automation, CI/CD pipelines, or environments where interactive prompts are undesirable, you can use a plain-text password file (often stored outside the primary repository and secured via restricted file permissions).

# Note: The password file MUST contain ONLY the vault password text.
ansible-playbook site.yml --vault-password-file ~/.ansible/vault_key.txt

Method 3: Encrypting Single Variables (encrypt_string)

If you only need to encrypt a single, small variable (e.g., in an inventory file) rather than an entire YAML file, use ansible-vault encrypt_string.

# Use 'echo' or 'printf' to pass the secret directly
ansible-vault encrypt_string 'MySuperSecretAPIKey' --name 'prod_api_key'

This command outputs the encrypted string which can be pasted directly into an inventory or variable file:

prod_api_key: !vault |
  $ANSIBLE_VAULT;1.1;AES256
  37666236613364656165386638323438646132646337326462613134373463353434613861313361
  ... (rest of encrypted data)

Best Practices for Enterprise Vault Management

Effective secret management extends beyond simply encrypting a file. Adopting these best practices ensures security and maintainability:

1. Dedicated Vault Password File

Always use the --vault-password-file method in automated environments. The file containing the password should have extremely restrictive permissions (chmod 400) and should never be committed to Git.

2. Environment Segregation

Use separate vault files for different environments (Development, Staging, Production). This prevents low-risk environments from accessing high-risk production credentials.

  • vars/prod_vault.yml
  • vars/stage_vault.yml

Load these files conditionally using inventory groups or conditional logic in your playbooks.

3. Use External Secret Stores When Vault Is Not Enough

For larger environments, consider external secret stores such as HashiCorp Vault, AWS Secrets Manager, or cloud-native key management. Ansible lookup plugins can fetch those values at runtime, while Ansible Vault remains useful for small secrets, bootstrap values, or teams that do not have a dedicated secret platform yet.

4. Group Variables vs. Playbook Variables

It is often cleaner to store vaulted variables under group_vars or host_vars using normal variable file names. Ansible decrypts vaulted content when the file is loaded; the extension is only a convention, not the feature that triggers decryption.

# Structure example
inventory/
├── hosts
└── group_vars/
    └── webservers/
        └── vault.yml

Keep Vault Practical

Start by encrypting the secrets your playbooks already load, then standardize how your team supplies the vault password. Keep the vault password outside Git, separate production secrets from lower environments, and rotate the password with ansible-vault rekey when access changes.