Ansible template out of the box

Kan Rangsan
2 min readAug 11, 2019
https://www.reddit.com/r/starterpacks/comments/9qwis0/drawing_a_curly_bracket_starterpack/

Background

Ansible Jinja template use double-curly braces {{ xx }}​ to represent the variables. For example, I want to have variable in nginx configuration template. I can simply use as below

user  {{ nginx_user }};
error_log {{ nginx_error_log }};
pid {{ nginx_pidfile }};
...
...

This is easy when the template file don’t have double braces symbol in place. However imagine you are working on the template file that have plenty of curly brace, you need to escape character everywhere and worry about the invalid syntax. It mess things up and hard to maintain the template like below file. I want to make some variables there and there are lot of {{ }} which are Prometheus alert syntax that Ansible will interpret as the variables if I don’t escape them.

alerts:
groups:
- name: etcd
rules:
- alert: etcdInsufficientMembers
annotations:
message: 'etcd cluster "{{ $labels.job }}": insufficient members ({{ $value }}).'
expr: 'sum(up{job=~".*etcd.*"} == bool 1) by (job) < ((count(up{job=~".*etcd.*"}) by (job) + 1) / 2)'
for: 3m
labels:
severity: critical
- alert: etcdNoLeader
annotations:
message: 'etcd cluster "{{ $labels.job }}": member {{ $labels.instance }} has no leader.'
expr: 'etcd_server_has_leader{job=~".*etcd.*"} == 0'

{{ escape with {{ '{{' }} and }} escape with {{ '}}' }} . That’s a lot of work.

Solution

Hold my beer. I have the simpler out of the box solution. I switch to use replace module instead of template and put the variable in double-underscore format __VARIABLE__ instead of double-curly braces.

hosts:
- __ALERTMANAGER_DOMAIN__
tls:
- hosts:
- __ALERTMANAGER_DOMAIN__
## Prometheus data retention period (i.e 360h)
retention: "__PROMETHEUS_DATA_RETENTION__d"
...
...

Then in the playbook,I use the replace module to replace variable with regex double-underscore pattern for variable name and variable value. Put the variable upper case make sure no one is using it. That’s it.

- name: prepare value file
replace:
path: "/tmp/helm-deploy/{{role_name}}/value.yml"
regexp: "__{{ item.name }}__"
replace: "{{ item.value }}"
with_items:
- { name: PROMETHEUS_DATA_RETENTION, value: "{{ PROMETHEUS_DATA_RETENTION }}" }
- { name: PROMETHEUS_DATA_VOLUME_SIZE, value: "{{ PROMETHEUS_DATA_VOLUME_SIZE }}" }
- { name: PROMETHEUS_DOMAIN, value: "{{ PROMETHEUS_DOMAIN }}" }
- { name: ALERTMANAGER_DOMAIN, value: "{{ ALERTMANAGER_DOMAIN }}" }
- { name: ALERTMANAGER_DATA_VALUME_SIZE, value: "{{ ALERTMANAGER_DATA_VALUME_SIZE }}" }

Edit

I just know from Jinja document that the double braces can also be escaped multiple lines by having this block{% raw %} {% endraw %} .

References

--

--