skip to content

What is Ansible Vault, and what does encrypting a file with it protect you against — and what does it not protect you against?

level: juniorimportance: must knowfreq 78%

answer

  1. symmetric password, whole file
  2. commit ciphertext, decrypt at run time
  3. header names cipher and format
  4. no per-user access, no audit
  5. decrypted values still print without no_log

basics

~20 s

Ansible Vault symmetrically encrypts variable files or single values with a password so they can be committed to git. Ansible decrypts them in memory at run time. It protects secrets at rest only — anyone holding the password reads everything.

solid answer

~40 s

Ansible Vault is a symmetric-encryption feature of the `ansible-vault` command line tool. `ansible-vault encrypt secrets.yml` rewrites the file in place as an armoured blob beginning with an `$ANSIBLE_VAULT;1.1;AES256` header, so the file can sit in version control without exposing the values. At run time `ansible-playbook` is given the password — via `--ask-vault-pass`, `--vault-password-file`, or `--vault-id` — decrypts the content into memory, and uses the variables normally. What it buys you is confidentiality at rest: a repository read, a stolen laptop, or a CI artifact leak yields ciphertext. What it does not buy you is access control, auditing, rotation, or leak-proof execution: one password unlocks the whole file for everyone who has it, and a decrypted value can still be printed by a task, a callback plugin, or `-vvv` output unless you set `no_log: true`.

code

bash · 11 lines
bash
# encrypt an existing plaintext vars file in place
ansible-vault encrypt group_vars/prod/vault.yml

# read it without writing plaintext to disk
ansible-vault view group_vars/prod/vault.yml

# change a value: decrypt to a temp file, edit, re-encrypt on save
ansible-vault edit group_vars/prod/vault.yml

# run a playbook that needs it, supplying the password from a file
ansible-playbook site.yml --vault-password-file ~/.ansible/vault_pass

go deeper

for a junior

Be able to say plainly that Ansible Vault encrypts files or values with a password so they can be committed safely, and name encrypt, decrypt, edit and view as the everyday subcommands.

for a middle

Explain the mechanics: whole-file in-place encryption under a salted key, lazy decryption at run time, and the three ways a password reaches the run — prompt, password file, or vault ID.

for a senior

Show you know the boundary in production: shared password means no revocation or audit, decrypted values still leak through task output without no_log, and a previously committed secret must be rotated, not merely encrypted.

for a principal

Own the decision of where the secret boundary sits — which credentials are cheap enough to keep in git under Vault, which belong in a managed secret store with leases and audit, and how a single bootstrap password is protected and rotated across the estate.

## The problem it solves Ansible's whole value proposition is that configuration lives in files you review and version-control. But real playbooks need database passwords, API tokens, TLS keys and licence strings, and those must not be committed in plaintext. Ansible Vault is the built-in answer: encrypt the sensitive files (or the sensitive values inside them) with a password, commit the ciphertext, and give the password to the humans and machines that actually run the playbook. ## What encryption actually does to the file `ansible-vault encrypt secrets.yml` replaces the file's contents in place. What is left is a text header followed by a hex-armoured payload: ``` $ANSIBLE_VAULT;1.1;AES256 34643766316239383066396336626635383234... ``` The header names the format version and the cipher; the payload is the encrypted body plus an authentication tag. The password you type is not used directly as a key — it is run through a key-derivation function with a random salt, which is why encrypting the same file twice produces different ciphertext. Because the whole file is one blob, nothing about its structure survives: not the YAML keys, not the number of variables, not which line changed between two commits. The main subcommands you will be asked to name: - `ansible-vault create secrets.yml` — open `$EDITOR` on a new file and encrypt on save. - `ansible-vault encrypt secrets.yml` / `ansible-vault decrypt secrets.yml` — convert an existing file in place. `decrypt` leaves plaintext on disk, which is what people accidentally commit. - `ansible-vault edit secrets.yml` — decrypt to a temporary file, open the editor, re-encrypt on save. The normal way to change a secret. - `ansible-vault view secrets.yml` — print the plaintext to stdout without persisting it. - `ansible-vault rekey secrets.yml` — re-encrypt the same content under a new password. - `ansible-vault encrypt_string` — encrypt one scalar so it can be pasted into an otherwise plaintext YAML file. ## How the password reaches the run Encrypted content is useless unless `ansible-playbook` can unlock it, and Ansible offers exactly three shapes for that: prompt interactively (`--ask-vault-pass`), read a file (`--vault-password-file secret.txt`), or use a labelled identity (`--vault-id prod@prompt`). The password file may be a plain file containing the password on one line, or an executable script whose stdout is taken as the password — that hook is how teams fetch the password from an external secret manager instead of storing it. The same file can be set once via the `ANSIBLE_VAULT_PASSWORD_FILE` environment variable or the equivalent `ansible.cfg` setting. Encrypted files are decrypted lazily, so a playbook that never loads `secrets.yml` never needs the password at all. ## The security boundary, stated honestly This is the part interviewers listen for. **It is confidentiality at rest, nothing more.** Ansible Vault is a symmetric cipher with a shared password. There is no per-user key, so you cannot revoke one engineer's access without rotating the password and re-encrypting everything. There is no audit trail: the file cannot tell you who decrypted it. There is no versioned secret store, no lease, no automatic expiry. **Git history is forever.** If a secret was committed in plaintext before someone thought to encrypt it, encrypting it today changes nothing — the old commit still holds the value. That secret must be rotated at its source, not merely encrypted. **Decryption puts plaintext in play.** Once a vault variable is loaded it behaves like any other variable. A `debug` task, a registered result, a template rendered with `-vvv`, or a module that echoes its arguments can print it. Mark such tasks `no_log: true`, and remember the same value may be written into a config file on the managed host with whatever permissions your `template` or `copy` task set. **The password itself is the real secret.** A vault password sitting in `~/.vault_pass` on a shared jump box, or checked into the repo "temporarily", collapses the whole scheme. Interviewers ask "where does the vault password live?" precisely because the answer exposes whether the story is real. ## When it is the right tool Ansible Vault fits small-to-medium estates where the secrets change rarely, the team is small enough to share one or a few passwords, and everything already lives in a git repository. When you need per-team access control, short-lived credentials, dynamic database logins, or an audit log, the honest answer in an interview is that a dedicated secret manager is the right layer and Ansible reads from it at run time, with Vault reserved for the bootstrap credential that unlocks that manager.

  • If a password was committed in plaintext last year and you encrypt that file today, are you safe?
    No. The old commit still contains the plaintext, and anyone with repository history — or a fork, or a CI cache — can read it. Encrypting the current file only protects future disclosure. The credential itself has to be rotated at the system that issued it, and only then is the new value worth encrypting.
  • How do you stop a vault-sourced value from appearing in playbook output?
    Set `no_log: true` on the task that handles it, which suppresses the task's arguments and result from stdout and callbacks. Be aware it also hides genuine failure detail, so it makes debugging harder, and it does not protect the value once it has been written into a file on the managed host — set restrictive `mode` and owner there too.
  • Does every playbook run need the vault password?
    Only if the run actually loads encrypted content. Ansible decrypts vault files when it reads them, so a play that never picks up the encrypted vars file, role defaults, or inventory variable runs fine without a password. Once any encrypted file is in scope and no password source is supplied, the run fails immediately with a decryption error rather than skipping the variable.

saying these in an interview costs you the question

  • Claiming Vault gives per-user access control or an audit trail
  • Confusing Ansible Vault with HashiCorp Vault, a separate server product
  • Saying encrypted values cannot leak into task output or logs
  • Thinking encrypting a file today hides what git history already recorded
  • Assuming ansible-vault decrypt is the normal way to read a file

context