I have a file on my local machine that I want to upload to a remote server, it contains confidential information that I don't want exposed in my VCS. It also has some text I need to replace dynamically in it (at the moment as Jinja2 placeholders "{{}}").
If I use the copy module, then the file is un-vaulted when I upload it, but obviously the placeholders are note replaced.
If i use the template module, then it doesn't un-vault the file and hence it is uploaded in its encrypted format (and also doesn't replace placeholders because they are obfuscated by the encryption).
How can I both template and un-vault a file (using ansible) to the remote server?
As already mentioned in the comments, you could set your secrets in variables and render them into the templates during provision, but if for some reason you want to keep your whole template a secret, there are some workarounds to also do that.
As a workaround you could temporarily decrypt the template locally and after the rollout delete the decrypted file with the local_action
module.
Lets assume your encrypted template resides as template.enc
in your roles templates
directory.
---
- name: Decrypt template
local_action: "shell {{ view_encrypted_file_cmd }} {{ role_path }}/templates/template.enc > {{ role_path }}/templates/template"
changed_when: False
- name: Deploy template
template:
src=templates/template
dest=/home/user/file
- name: Remove decrypted template
local_action: "file path={{ role_path }}/templates/template state=absent"
changed_when: False
Please note the changed_when: False
. This is important in order to run idempotence tests with your ansible roles - otherwise each time you run the playbook a change is signaled.
In group_vars/all.yml
you could set a global decrypt command for reuse, e.g., as view_encrypted_file_cmd
.
group_vars/all.yml
---
view_encrypted_file_cmd: "ansible-vault --vault-password-file {{ lookup('env', 'ANSIBLE_VAULT_PASSWORD_FILE') }} view"
One way: as template
You could set the content of your secret static file (e.g., a private key) as a variable in ansible and provision it as a template.
var.yml
---
my_private_key: |
YOUR KEY
asfdlsafkj
asdlkfjasf
templates/private_key.j2
{{ private_key }}
tasks/main.yml
---
template:
src=templates/private_key.j2
dest=/home/user/.ssh/id_rsa
vars:
private_key: "{{ my_private_key }}"
Another way: via lookup pipe
Another way would be to use the lookup
module with pipe
to set the content
property within the copy
module - that way you do not need an extra variable.
---
- copy:
dest=/your/dest
content=lookup('pipe', 'VAULT_PASSWORD_FILE=path/to/pass_file ansible-vault view path/to/file.enc')