Does anyone have an example of decrypting and uploading a file using ansible-vault.
I am thinking about keeping my ssl certificates encrypted in source control.
It seems something like the following should work.
---
- name: upload ssl crt
copy: src=../../vault/encrypted.crt dest=/usr/local/etc/ssl/domain.crt
The copy module now does this seamlessly as of Ansible 2.1.x. Just encrypt your file with Ansible Vault and then issue the copy task on the file.
(For reference, here's the feature that added this: https://github.com/ansible/ansible/pull/15417)
UPDATE: Deprecated as of 2016, Ansible 2.1
On any Ansible version prior of 2.1
:
That's not going to work. What you will get is your encrypted.crt
(with Ansible Vault) uploaded literally as domain.crt
What you need to do is make your playbook part of a "Vault" and add a variable that contains your certificate content. Something like this:
---
- name: My cool playbook
hosts: all
vars:
mycert: |
aasfasdfasfas
sdafasdfasdfasdfsa
asfasfasfddasfasdfa
tasks:
# Apparently this causes new lines on newer ansible versions
# - name: Put uncrypted cert in a file
# shell: echo '{{ mycert }}' > mydecrypted.pem
# You can try this as per
# https://github.com/ansible/ansible/issues/9172
- copy:
content: "{{ mycert }}"
dest: /mydecrypted.pem
- name: Upload Cert
copy: src=/home/ubuntu/mydecrypted.pem dest=/home/ubuntu/mydecrypteddest.pem
- name: Delete decrypted cert
file: path=/home/ubuntu/mydecrypted.pem state=absent
You can choose to put your mycert
variable in a separate variable file using Ansible Vault too.
The copy module has been updated in Ansible 2.1. From the changelog: "copy module can now transparently use a vaulted file as source, if vault passwords were provided it will decrypt and copy on the fly." Noting it here, since some people will inevitably not look past the accepted answer. – JK Laiho
There is a feature request to support this natively in the copy module. But until that is implemented, here is the workaround (similar to @dave1010's answer, but repeating common parts for completeness):
Create a secrets.yml
file encrypted with ansible vault which contains your secrets, for example:
---
private_ssl_key: |
-----BEGIN PRIVATE KEY-----
abcabcabcabcabcabcabcabcabc
-----END PRIVATE KEY-----
private_crt: |
-----BEGIN CERTIFICATE-----
abcabcabcabcabcabcabcabcabc
-----END CERTIFICATE-----
In your playbook, include it:
vars_files:
- secrets.yml
Then you can use the variables in tasks:
- name: Copy private kay
copy: content="{{ private_ssl_key }}" dest=/some/path/ssl.key
However, this doesn't work if the file that you are trying to copy is a binary file. In that case, you need to first encode the content with base64:
cat your_secret_file | /usr/bin/base64
Then put the base64 encoded value in your secrets.yml
file, e.g.:
crt_b64: |
ndQbmFQSmxrK2IwOFZnZHNJa0sKICAxdDhFRUdmVzhMM...
Then you can create the remote file in two steps:
- name: Copy certificate (base64 encoded)
copy: content="{{ crt_b64 }}" dest=/some/path/cert.b64
- name: Decode certificate
shell: "base64 -d /some/path/cert.b64 > /some/path/cert.txt"
args:
creates: /some/path/cert.txt
Note that you could delete the temporary cert.b64
file on the remote host. But then re-running the playbook will re-create it instead of skipping this task. So, I prefer to leave it there.
UPDATE: This feature has been implemented in Ansible 2.1.
copy module can now transparently use a vaulted file as source, if vault passwords were provided it will decrypt and copy on the fly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With