I recently started an open source ansible infrastructure approach with encrypted secrets and Travis CI testing (GitHub link).
I used ansible-vault to encrypt the secrets. For each project Travis creates a key pair and with the help of the travis-client you can use it to securely set the vault password within the Travis build environment.
Your case with an ansible-vault approach
In your particular case (you only want to deploy one secret key), there are 2 easy ways to encrypt the key secret with ansible-vault
.
1st approach: Encrypt the static key file
ANSIBLE_VAULT_PASSWORD_FILE=vault_pass ansible-vault encrypt <key_file>
Then with the following task you could copy it to the node:
- copy:
content={{ lookup('pipe', 'ansible-vault --vault-password-file vault_pass view <key_file>') }}
dest=/<deploy_user>/.ssh/id_rsa
The lookup
workaround is necessary, since ansible-vault
was designed to encrypt/decrypt .yml
variable files and it does not automatically decrypt static files or templates during a rollout.
2nd approach: Place key in variable and encrypt var file
Another approach would be to add your private key to a .yml
file (and encrypt it like above), which can then be decrypted on the fly by ansible:
secrets.yml
private_key: |
<copy-key-here>
You can then reference that variable in a task.
Finally, both approaches can be rolled out via:
ANSIBLE_VAULT_PASSWORD_FILE=vault_pass ansible-playbook -i <inventory-file> <playbook-file>
Now you need to share your vault_pass
(or a password to decrypt the vault_pass
file) with Travis. This is very well documented in the Travis link above. In the last section I provide an article which also explains how to do that.
Digging deeper
Even though it might be a little out of scope for your problem at hand, I'd like to share some more thoughts about this topic.
Security concerns
While testing with Travis is quite comfortable, one major problem though is that you are still handing over your secrets to the Travis environment (and obviously if Travis gets compromised, your secrets are gone) - so I suggest that maybe it is safer to deploy/rollout fake data in your Travis rollout tests. The project I provided above is still in early stages and does not contain any real production secrets (yet), but I will design my provisioning in a way that I can easily deploy fake data in my Travis rollouts. Also, ensure that you do not log too much in Travis (since for open source repos, the travis build logs are open source too). You can avoid logging with the no_log: yes
variable inside a playbook.
HashiCorp Vault
Another very interesting project for handling secrets comes from HashiCorp: Vault (not to be mistaken with ansible-vault
!) I didn't have the time to look into it closer yet, but it looks very promising and seems like a good idea for bigger setups.
External article
Here is a more detailed article about using ansible-vault
with Travis CI (also for cases in which you wish to encrypt sensitive templates or other static files, which requires some small workarounds since ansible-vault
was only designed to encrypt .yml
files containing variables). It also briefly discusses the issue of sharing secrets with external services. (Secret management is a very interesting topic and I am still adjusting my approaches, so the article is still kind of in the making, but most of the ideas are already provided there)