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 thefiles
directory and not in thetemplates
directory.If you need both Ansible-level and
vault-cli
-level Jinja2 rendering, you’ll need to escape thevault-cli
Jinja2 directives:[myapp] url = {{ myapp_url }} # Ansible rendering token = {{ '{{ vault("myapp").token }}' }} # vault-cli {# Or: #} token = {{ '{{' }} vault("myapp").token {{ '}}' }} # vault-cli