Skip to main content
Cloud DevOps Solutions
Get a quote Talk to an engineer

Ansible / Config Mgmt

Managing Secrets in Ansible with Vault and HashiCorp Vault

Ansible Vault encrypts variables and files so they can live in Git, while HashiCorp Vault serves secrets at run time with audit and short lifetimes. We choose per client, remove plaintext credentials from playbooks, and wire either approach into CI and AWX safely.

Key takeaways

  • Plaintext credentials in playbooks and old Git history are the most common finding in Ansible reviews.
  • Ansible Vault is simple and fine for small teams; HashiCorp Vault suits rotation, audit and many consumers.
  • Vault IDs separate secrets by environment so a staging key cannot decrypt production.
  • Secrets should never appear in logs, so tasks that handle them use no_log.
  • A leaked secret needs a rotation runbook, not just removal from the repository.

The credential in the playbook problem

Almost every Ansible repository we review has at least one of these: a database password in group_vars, an SSH private key committed “temporarily”, a cloud access key in a template, or a token echoed in a CI log. The playbook works, so nobody revisits it. Then someone adds a contractor to the repository, or the repository is mirrored, or an employee leaves with a clone, and the credential is effectively public.

Secrets management for Ansible has two parts: where the secret lives, and how it reaches the task that needs it. This page covers how we handle both within our Ansible configuration management service.

What good looks like

  • No credential exists in plaintext in any repository, including history.
  • Secrets are separated by environment, and a lower environment cannot read production.
  • Access is least-privilege, and you can say who can read each secret.
  • Secrets do not appear in job output, logs or error messages.
  • A rotation is a routine procedure, not an emergency.

How it works in practice

Option 1: Ansible Vault

Ansible Vault encrypts data using AES-256 with a key derived from a password. You can encrypt entire files or single values. Single values are friendlier in code review because the variable name stays readable:

ansible-vault encrypt_string --vault-id prod@prompt 'S3cr3t-value' --name 'db_password'

The output is pasted into group_vars/production/vault.yml:

db_password: !vault |
  $ANSIBLE_VAULT;1.2;AES256;prod
  6338343262343733...

A useful convention is to keep an unencrypted file that references the encrypted one, so grep still finds variable names:

# group_vars/production/vars.yml
app_db_password: "{{ vault_app_db_password }}"

Run with the matching password source:

ansible-playbook site.yml --vault-id prod@~/.vault_pass_prod.sh

The password source can be a script that reads from your password manager, which keeps the password out of the repository and shell history. Vault IDs separate environments, so staging and production use different passwords.

Option 2: HashiCorp Vault

When you need audit logs, rotation or short-lived credentials, Ansible reads from HashiCorp Vault at run time using the community.hashi_vault collection:

- name: Read database credentials
  ansible.builtin.set_fact:
    db_creds: "{{ lookup('community.hashi_vault.hashi_vault',
                 'secret=kv/data/app/production/db',
                 url='https://vault.example.internal:8200',
                 auth_method='approle') }}"
  no_log: true

Authentication uses AppRole, a cloud identity or JWT rather than a long-lived root token. The role is bound to a policy that allows reading one path. With the database secrets engine, Vault can even mint a unique short-lived database account per run, so there is nothing long-lived to leak. Ansible lookups run on the controller, which affects network design: the controller must reach Vault, and the target hosts need not.

Option 3: Cloud secrets managers

If you are all-in on one cloud, AWS Secrets Manager or Azure Key Vault, read through the matching collection lookups, may be simpler than operating Vault yourself. You trade features like dynamic secrets for less to maintain.

Preventing leaks

Three habits matter more than the tool choice:

  1. no_log: true on any task that touches a secret. Without it, a failure prints the full task arguments.
  2. Pre-commit and CI scanning with a tool such as gitleaks, so a plaintext secret is rejected before merge. Our pipeline for playbook linting includes this check.
  3. Never use secrets in command arguments, because they show up in process listings on the target.

Running in AWX

AWX has first-class credential types, including vault credentials and external secret lookup plugins for HashiCorp Vault and cloud managers. Credentials are stored encrypted, and users who can run a job template can use a credential without ever seeing its value. That is a major improvement over passwords on engineers’ laptops.

Decisions and trade-offs

FactorAnsible VaultHashiCorp VaultCloud secrets manager
Setup effortMinutesSignificant (HA, unseal, policies)Low
Audit trailGit history onlyFull request auditCloud audit logs
RotationManual rekeyBuilt in for many enginesBuilt in for some
Dynamic secretsNoYesLimited
Best forSmall teams, bootstrapMany consumers, strict complianceSingle-cloud estates

When not to adopt HashiCorp Vault. If you have a handful of secrets and a team of three, running a highly available Vault cluster adds operational burden that outweighs the benefit. Ansible Vault with disciplined practice is perfectly respectable.

Common failure modes

  • One password for everything. A single vault password makes every environment equally exposed. Use vault IDs.
  • Vault password in the repository. Defeats the purpose. Hold it in a password manager, CI secret store or AWX credential.
  • Secrets in facts. set_fact values can end up in fact caches or callback output. Use no_log and avoid caching them.
  • Forgotten history. Removing a secret from the latest commit does not remove it from the past. We rotate first, then clean history where practical.
  • Break-glass lockout. Only one person holds the vault password and is on holiday. We document escrow arrangements.

Delivery and handover

We deliver a secrets inventory (what exists, where, who uses it), the chosen vault configuration, CI checks for plaintext secrets, rotation runbooks and a short training session. Where hardening the hosts themselves is in scope, the server baseline role removes credentials left on disk. For wider secret handling in clusters, see our notes on sealed secrets.

What to do when a secret has already leaked

If a credential has been committed, assume it is compromised. Rotate it first, then remove it from the working tree, and only then decide whether rewriting history is worth the disruption. Rewriting does not help if the repository was ever cloned or mirrored, so rotation is the real fix. We write this order into the runbook so nobody wastes the first hour cleaning history while the credential is still valid.

How to tell it is working

  • A repository scan finds no plaintext credentials, including in history.
  • A staging engineer genuinely cannot decrypt production values.
  • Rotating a credential takes minutes and touches one place.
  • Job logs are clean even when a task fails.
  • You can say who read a given secret last month, if you chose a runtime store.

To find out what is currently exposed in your repositories, contact us.

References

How we deliver it

  1. 01

    Find the secrets

    We scan repositories, history and variable files for credentials, keys and tokens, and list who and what uses each.

  2. 02

    Choose the model

    Ansible Vault, HashiCorp Vault, or a cloud secrets manager, picked for your team size, rotation needs and existing tooling.

  3. 03

    Restructure variables

    Secrets are separated from ordinary variables, named consistently and referenced indirectly so the plaintext is in one place only.

  4. 04

    Integrate with CI and AWX

    Vault passwords and tokens are held as credentials in the platform, never in the repository or pipeline logs.

  5. 05

    Rotate and clean up

    Exposed secrets are rotated, history is addressed, and a scheduled rotation process is documented.

  6. 06

    Hand over procedures

    Runbooks cover adding, rekeying and revoking secrets, including who holds the break-glass access.

Tools and technologies

Ansible VaultHashiCorp Vaultcommunity.hashi_vaultAWS Secrets ManagerAzure Key VaultAWXansible-lintgitleakspre-commitGitHub Actions

Frequently asked questions

What is Ansible Vault?
Ansible Vault is a built-in feature that encrypts files or individual variable values with a password or key, so they can be stored in version control. Playbooks decrypt them at run time when given the vault password. It protects data at rest in Git but offers no access auditing or automatic rotation.
Should we use Ansible Vault or HashiCorp Vault?
Ansible Vault suits small teams with few secrets and no existing vault server. HashiCorp Vault suits teams that need audit logs, short-lived credentials, dynamic database accounts or many consumers beyond Ansible. Running both is common: Ansible Vault for bootstrap, HashiCorp Vault for application secrets.
How do we stop secrets appearing in Ansible logs?
Set no_log: true on tasks that handle sensitive values, avoid passing secrets on the command line, and keep verbosity low in production. In AWX, job output is stored, so one unprotected task can leak a password into history. We test with deliberate failures to confirm nothing sensitive is printed.
How do we use multiple vault passwords for different environments?
Use vault IDs, for example dev and prod, each with its own password source. Encrypted values are labelled with their ID, and Ansible tries the matching password. This means a developer with the staging password cannot decrypt production secrets, which also limits the damage of a leaked password.
Is it safe to store encrypted secrets in Git?
It is acceptable when the encryption is strong, the password is long and stored elsewhere, and access to the repository is controlled. The risk is that a later leak of the password exposes all history. For high-value secrets, a runtime store with rotation is the safer design.

Talk to an engineer about ansible vault secrets management

Book a free 30-minute call. We review your current setup and tell you honestly whether and how we can help.

Written by Saddique Khan, DevOps / SRE / Cloud Consultant Engineer. Last updated 2026-10-08.