Configure Ansible Vault for secret management and encryption with playbook automation

Intermediate 25 min Apr 21, 2026 14 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Set up Ansible Vault to encrypt sensitive data like passwords, API keys, and certificates in your playbooks. Learn to create encrypted variables, manage vault passwords, and integrate secure secret handling into automated deployments.

Prerequisites

  • Linux server with sudo access
  • Basic Ansible knowledge
  • SSH key access to target hosts

What this solves

Ansible Vault encrypts sensitive data in your playbooks and variable files, preventing passwords, API keys, and certificates from being stored in plain text. This tutorial shows you how to create encrypted variables, manage vault passwords securely, and integrate vault-protected secrets into your automation workflows.

Step-by-step configuration

Install Ansible and required tools

Start by installing Ansible and the tools needed for vault operations.

sudo apt update
sudo apt install -y ansible python3-pip
pip3 install ansible-vault
sudo dnf update -y
sudo dnf install -y ansible python3-pip
pip3 install ansible-vault

Create a vault password file

Create a secure password file that Ansible will use to encrypt and decrypt vault data. Store this outside your project directory.

mkdir -p ~/.ansible/vault
echo 'your-strong-vault-password-here' > ~/.ansible/vault/password
chmod 600 ~/.ansible/vault/password
Security: Use a strong password (minimum 20 characters) and never commit this file to version control. Consider using a password manager to generate and store the vault password.

Configure Ansible to use the vault password file

Set up Ansible configuration to automatically use your vault password file for encryption operations.

[defaults]
vault_password_file = ~/.ansible/vault/password
host_key_checking = False
inventory = inventory.ini

[ssh_connection]
ssh_args = -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no

Create your first encrypted variables file

Create a variables file with encrypted sensitive data like database passwords and API keys.

ansible-vault create group_vars/all/vault.yml

This opens your default editor. Add your encrypted variables:

---
vault_mysql_root_password: "MySecureP@ssw0rd123"
vault_api_key: "sk-1234567890abcdef"
vault_ssl_private_key: |
  -----BEGIN PRIVATE KEY-----
  MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC7
  -----END PRIVATE KEY-----
vault_database_url: "postgresql://user:password@localhost:5432/mydb"

Create a public variables file for non-sensitive data

Create a companion file for non-encrypted variables that reference the vault variables.

---
mysql_root_password: "{{ vault_mysql_root_password }}"
api_key: "{{ vault_api_key }}"
ssl_private_key: "{{ vault_ssl_private_key }}"
database_url: "{{ vault_database_url }}"

Non-sensitive configuration

mysql_port: 3306 api_endpoint: "https://api.example.com" ssl_cert_path: "/etc/ssl/certs/example.com.crt" ssl_key_path: "/etc/ssl/private/example.com.key"

Create an inventory file

Set up your inventory with target hosts for the playbook.

[webservers]
web1 ansible_host=203.0.113.10 ansible_user=ubuntu
web2 ansible_host=203.0.113.11 ansible_user=ubuntu

[databases]
db1 ansible_host=203.0.113.20 ansible_user=ubuntu

[all:vars]
ansible_ssh_private_key_file=~/.ssh/id_rsa

Create a playbook that uses encrypted variables

Build a playbook that demonstrates how to use vault-encrypted secrets in real automation tasks.

---
  • name: Deploy application with encrypted secrets
hosts: webservers become: yes vars_files: - group_vars/all/vars.yml - group_vars/all/vault.yml tasks: - name: Install required packages package: name: - nginx - mysql-client - python3-mysqldb state: present - name: Create application user user: name: appuser shell: /bin/bash home: /opt/myapp system: yes - name: Create SSL certificate directory file: path: /etc/ssl/private state: directory mode: '0700' owner: root group: root - name: Deploy SSL private key from vault copy: content: "{{ ssl_private_key }}" dest: "{{ ssl_key_path }}" mode: '0600' owner: root group: root notify: restart nginx - name: Create application configuration template: src: app.conf.j2 dest: /opt/myapp/config.yml mode: '0640' owner: appuser group: appuser notify: restart application - name: Test database connection with encrypted credentials mysql_db: name: testdb login_host: "{{ database_url.split('@')[1].split(':')[0] }}" login_user: "{{ database_url.split('//')[1].split(':')[0] }}" login_password: "{{ database_url.split(':')[2].split('@')[0] }}" state: present delegate_to: "{{ groups['databases'][0] }}" run_once: true handlers: - name: restart nginx systemd: name: nginx state: restarted enabled: yes - name: restart application systemd: name: myapp state: restarted enabled: yes

Create the application configuration template

Create a Jinja2 template that uses encrypted variables securely.

mkdir -p templates
---
api:
  endpoint: "{{ api_endpoint }}"
  key: "{{ api_key }}"
  timeout: 30

database:
  url: "{{ database_url }}"
  pool_size: 10
  timeout: 5000

ssl:
  certificate: "{{ ssl_cert_path }}"
  private_key: "{{ ssl_key_path }}"
  protocols: ["TLSv1.2", "TLSv1.3"]

logging:
  level: INFO
  file: /var/log/myapp.log

Set up environment-specific vault files

Create separate vault files for different environments to manage secrets per stage.

mkdir -p group_vars/production group_vars/staging
ansible-vault create group_vars/production/vault.yml
ansible-vault create group_vars/staging/vault.yml

Add environment-specific secrets to each file:

---
vault_mysql_root_password: "Pr0d-MySecureP@ssw0rd123"
vault_api_key: "sk-prod-1234567890abcdef"
vault_database_url: "postgresql://produser:prodpass@prod-db:5432/proddb"

Create a vault management script

Build a helper script to manage vault operations across your infrastructure.

#!/bin/bash

VAULT_PASSWORD_FILE="~/.ansible/vault/password"

case "$1" in
    "encrypt")
        if [ -z "$2" ]; then
            echo "Usage: $0 encrypt "
            exit 1
        fi
        ansible-vault encrypt "$2" --vault-password-file="$VAULT_PASSWORD_FILE"
        ;;
    "decrypt")
        if [ -z "$2" ]; then
            echo "Usage: $0 decrypt "
            exit 1
        fi
        ansible-vault decrypt "$2" --vault-password-file="$VAULT_PASSWORD_FILE"
        ;;
    "edit")
        if [ -z "$2" ]; then
            echo "Usage: $0 edit "
            exit 1
        fi
        ansible-vault edit "$2" --vault-password-file="$VAULT_PASSWORD_FILE"
        ;;
    "view")
        if [ -z "$2" ]; then
            echo "Usage: $0 view "
            exit 1
        fi
        ansible-vault view "$2" --vault-password-file="$VAULT_PASSWORD_FILE"
        ;;
    "rekey")
        if [ -z "$2" ]; then
            echo "Usage: $0 rekey "
            exit 1
        fi
        ansible-vault rekey "$2" --vault-password-file="$VAULT_PASSWORD_FILE"
        ;;
    "create")
        if [ -z "$2" ]; then
            echo "Usage: $0 create "
            exit 1
        fi
        ansible-vault create "$2" --vault-password-file="$VAULT_PASSWORD_FILE"
        ;;
    *)
        echo "Usage: $0 {encrypt|decrypt|edit|view|rekey|create} "
        echo "Examples:"
        echo "  $0 create group_vars/all/vault.yml"
        echo "  $0 edit group_vars/all/vault.yml"
        echo "  $0 view group_vars/all/vault.yml"
        echo "  $0 encrypt secrets.yml"
        exit 1
        ;;
esac
chmod +x vault-manager.sh

Run the playbook with encrypted variables

Execute your playbook and verify that encrypted secrets are properly decrypted and used.

ansible-playbook deploy-secure-app.yml --limit webservers --check

Run the actual deployment:

ansible-playbook deploy-secure-app.yml --limit webservers

Configure multiple vault password files

Set up different vault passwords for different environments or teams.

mkdir -p ~/.ansible/vault/environments
echo 'production-vault-password-123' > ~/.ansible/vault/environments/production
echo 'staging-vault-password-456' > ~/.ansible/vault/environments/staging
chmod 600 ~/.ansible/vault/environments/*

Use environment-specific passwords:

ansible-playbook deploy-secure-app.yml --vault-password-file ~/.ansible/vault/environments/production --limit production
ansible-playbook deploy-secure-app.yml --vault-password-file ~/.ansible/vault/environments/staging --limit staging

Advanced vault security practices

Set up vault ID labels for multiple encryption keys

Use vault IDs to manage multiple encryption keys within the same playbook infrastructure.

ansible-vault create --vault-id production@~/.ansible/vault/environments/production group_vars/production/vault.yml
ansible-vault create --vault-id staging@~/.ansible/vault/environments/staging group_vars/staging/vault.yml

Run playbooks with specific vault IDs:

ansible-playbook deploy-secure-app.yml --vault-id production@~/.ansible/vault/environments/production --limit production

Create encrypted strings for inline use

Encrypt individual strings for use directly in playbooks without separate files.

ansible-vault encrypt_string 'MySecretPassword123' --name 'admin_password'

This outputs encrypted data you can paste directly into playbooks:

---
  • name: Deploy with inline encrypted variables
hosts: all vars: admin_password: !vault | $ANSIBLE_VAULT;1.1;AES256 66633939373737386264323233343734346138663639373566353930643238336 3666373865336435353561323637363138656533373263650a373834646466316 63303138653738636666333034356462363661336565353235626562313633626 6662623865653635353864653237343739333363386536310a626436313461363 tasks: - name: Debug encrypted variable debug: msg: "Admin password is {{ admin_password }}"

Set up automated vault password rotation

Create a script to rotate vault passwords and re-encrypt files with new keys.

#!/bin/bash

OLD_PASSWORD_FILE="~/.ansible/vault/password.old"
NEW_PASSWORD_FILE="~/.ansible/vault/password.new"
CURRENT_PASSWORD_FILE="~/.ansible/vault/password"

Generate new password

echo "$(openssl rand -base64 32)" > "$NEW_PASSWORD_FILE" chmod 600 "$NEW_PASSWORD_FILE"

Backup current password

cp "$CURRENT_PASSWORD_FILE" "$OLD_PASSWORD_FILE"

Find all vault files and rekey them

find . -name "*.yml" -exec grep -l "\$ANSIBLE_VAULT" {} \; | while read vault_file; do echo "Rekeying $vault_file..." ansible-vault rekey "$vault_file" \ --vault-password-file="$CURRENT_PASSWORD_FILE" \ --new-vault-password-file="$NEW_PASSWORD_FILE" done

Update current password file

cp "$NEW_PASSWORD_FILE" "$CURRENT_PASSWORD_FILE" echo "Vault password rotation completed" echo "Old password backed up to $OLD_PASSWORD_FILE" echo "Remember to update CI/CD systems with new password"
chmod +x rotate-vault-password.sh

Verify your setup

# Test vault file creation and encryption
ansible-vault view group_vars/all/vault.yml

Verify playbook syntax with vault variables

ansible-playbook deploy-secure-app.yml --syntax-check

Test variable resolution without running tasks

ansible-playbook deploy-secure-app.yml --list-tasks

Check that encrypted files are properly encrypted

cat group_vars/all/vault.yml

Verify vault operations work

./vault-manager.sh view group_vars/all/vault.yml

You should see encrypted content starting with $ANSIBLE_VAULT;1.1;AES256 when viewing raw files, and decrypted content when using vault commands.

Integration with CI/CD pipelines

For automated deployments, set up vault password management in your CI/CD system. Store the vault password as an encrypted environment variable and write it to a temporary file during pipeline execution.

deploy:
  stage: deploy
  script:
    - echo "$ANSIBLE_VAULT_PASSWORD" > /tmp/vault_password
    - chmod 600 /tmp/vault_password
    - ansible-playbook deploy-secure-app.yml --vault-password-file /tmp/vault_password
    - rm -f /tmp/vault_password
  variables:
    ANSIBLE_HOST_KEY_CHECKING: "false"
  only:
    - main

Similar patterns work for GitHub Actions, Jenkins, and other CI/CD platforms. Always clean up temporary password files and use encrypted secrets storage provided by your platform.

Common issues

SymptomCauseFix
ERROR! Decryption failedWrong vault passwordCheck password file path and content with ansible-vault view
Vault password file not foundIncorrect path in ansible.cfgUpdate vault_password_file path or use --vault-password-file
Variables not resolvingVault file not included in vars_filesAdd vault.yml to vars_files section in playbook
Permission denied on password fileWrong file permissionsSet correct permissions: chmod 600 ~/.ansible/vault/password
Vault ID not foundMissing vault-id parameterUse --vault-id label@password_file when multiple IDs exist
Cannot edit vault fileNo EDITOR environment variableSet EDITOR: export EDITOR=nano or export EDITOR=vim

Next steps

Running this in production?

Want this handled for you? Setting up Ansible Vault once is straightforward. Keeping it patched, monitored, backed up and tuned across environments is the harder part. See how we run infrastructure like this for European SaaS and e-commerce teams.

Automated install script

Run this to automate the entire setup

Need help?

Don't want to manage this yourself?

We handle managed devops services for businesses that depend on uptime. From initial setup to ongoing operations.