Render templated files with secrets¶
Sometimes, you need to write a configuration file that contains secrets. That what
vault-cli template is for. This command lets you write Jinja2 templates and
have vault render them, replacing calls to vault() by the corresponding
secrets.
Warning
Ideally, it’s best to avoid writing secrets to the disk (see Avoid writing secrets to the disk). This command can still be useful, but consider coupling it with ways to write on ephemeral storage, and check your umask and the permissions of the created file. See Integrate with SystemD for safe integration strategies.
We’ll consider that your vault has been setup with the following secret:
$ vault-cli set myapp token=mysecrettoken
Create your template using Jinja2, indicating where you want to inject secrets and
which secrets by editing e.g. /etc/myapp.conf.j2:
[myapp]
url = http://example.com
token = {{ vault("myapp").token }}
Render your template:
$ vault-cli template /etc/myapp.conf.j2 --output /etc/myapp.conf
$ cat /etc/myapp.conf
[myapp]
url = http://example.com
token = mysecrettoken
If output file is not specified or -, stdin will be used.
Writing template files with ansible¶
The following is relevant only if your setup includes Ansible.
If you write your template using Ansible, you will need a way to instruct it not to
try rendering the Jinja2 instructions that are meant for vault-cli to process.
There are two classic ways for doing this:
If your template doesn’t need Ansible-level Jinja2 rendering, make sure you write it with a
file:task and not atemplate:task. To make things clearer, in your playbook or role, store the template in thefilesdirectory and not in thetemplatesdirectory.If you need both Ansible-level and
vault-cli-level Jinja2 rendering, you’ll need to escape thevault-cliJinja2 directives:[myapp] url = {{ myapp_url }} # Ansible rendering token = {{ '{{ vault("myapp").token }}' }} # vault-cli {# Or: #} token = {{ '{{' }} vault("myapp").token {{ '}}' }} # vault-cli