ansible-vault and GPG

ansible-vault and GPG #

TODO

Consider rewriting for using ssh keys instead of GPG keys? I think this is now what Debian does for package signing, and would be more accessible as many people do not have GPG set up but do have ssh-agent.

If you already have some corporate secret store, like Square’s Keywhiz, Hashicorp’s Vault, or one of many others, you should probably use it with Ansible.

However, if you don’t have one handy, there’s a neat trick for transparently decrypting the Ansible vault when your GPG agent is unlocked. It works very well for just one person, and scales okay for a small team.

  1. Make sure all of your vaults are named vault.yml, e.g. group_vars/all/vault.yml or host_vars/xxx.example.com/vault.yml etc.

  2. Encrypt your desired ansible-vault passphrase with GPG, and save it as .vault-passphrase.gpg in the root of your Ansible repository. You can encrypt it for several users if you want to share it on a small team.

  3. Create a .vault-pass-script.sh (see below)

  4. Set the option vault_password_file = .vault-pass-script in the [defaults] section of ansible.cfg.

  5. Add a line to .gitattributes (create the file if it doesn’t exist) like this: **/vault.yml diff=ansible-vault merge=binary. This tells git to decrypt any file with ansible-vault when diffing, so you will be able to see line-by-line changes to your vault with git diff.

.vault-pass-script.sh should look like this:

#!/bin/sh
set -eu
# When run by ansible, this is run from the root of the ansible directory
# But when run by git in a smudge filter, it's run from the root of the git repo
# So we have to look for .vault-passphrase.gpg in two relative places
if test -e .vault-passphrase.gpg; then
    vp=.vault-passphrase.gpg
elif test -e ansible/.vault-passphrase.gpg; then
    vp=ansible/.vault-passphrase.gpg
else
    echo "CANNOT FIND .vault-passphrase.gpg FROM PWD $(pwd)"
    exit 1
fi
gpg --quiet --decrypt "$vp"

Now you can run commands like

  • ansible-vault edit group_vars/all/vault.yml
  • git diff group_vars/all/vault.yml
  • ansible-vault view host_vars/xxx.example.com/vault.yml

and ansible-vault will transparently decrypt the vault for you, prompting you for your GPG password if it’s not in memory.