I use Ansible Vault to securely store the project's secrets (e.g. API keys, default passwords, private keys, etc.) in the git repository for many of my infrastructure projects. I also like to make sure I cover everything possible in automated tests/CI, using either Jenkins or Travis CI (usually).

But this presents a conundrum: if some of your variables are encrypted with an Ansible Vault secret/passphrase, and that secret should be itself store securely... how can you avoid storing it in your CI system, where you might not be able to guarantee it's security?

The method I usually use for this case is including the Vault-encrypted vars at playbook runtime, using include_vars:

That way, in my CI environment, I can make sure the test_mode variable is set to True, and it won't include the encrypted variable. Great! But there's still one more issue. Even though you're not using the included variable file, if you have a vault_password_file defined in your project ansible.cfg, then Ansible will always look for that file prior to beginning playbook execution (since the include_vars will be dynamically performed later in the execution, and Ansible needs to load in the password at the beginning).

D'oh! Not quite what we were expecting. This used to work, but in Ansible 2.3.2+, a check was added to verify the vault_password_file is not empty. So, we have to make sure the file is not empty. Change the earlier command to:

Comments

Just out of curiosity, why not just pass the test password as an extra var? I guess that means you possibly have to change your playbooks if the password isn't already a variable. So " -e "{ test_mode: True, test_pass: test-password }" Then you could override them whenever (like a Tower survey), but I guess it's six of one, half a dozen though.

This is a very cool idea and I have one more suggestion. In 2.3 you can encrypt a single variable, which means that variable will be decrypted only if it's used. So in a test environment if you don't use it, you will never need to decrypt it.