Control Whitespace in Ansible Templates
Ansible uses the powerful Jinja templating engine. However, the way it handles whitespace in templates is not ideal. Specifically, the fact that it preserves leading whitespace around Jinja blocks. So, you can either not indent Jinja syntax, making the templates hard to comprehend, or accept broken indentation in the resulting file (not an option with whitespace-sensitive formats such as yaml).
Luckily, there is a third option. Jinja has two configuration options regarding whitespace:
-
trim_blocks
- first newline after template tag is removed automatically -
lstrip_blocks
- strip tabs and spaces from beginning of the line to the start of a block
While trim_blocks
has been on by default since Ansible 2.4, that is not the case with lstrip_blocks
. In order to turn it on, you need to put the following line at the very top of your template:
#jinja2: lstrip_blocks: "True"
Comparison
Let’s take the following template:
{% set _dataset = datasets[dataset] %} [{{ dataset }}] {% for key, value in _dataset.items() %} {{ key }} = {{ value }} {% endfor %}
without lstrip_blocks
, the result would look like this:
[home] recursive = yes use_template = default
Now, with lstrip_blocks
on, you get correct indentation:
[home] recursive = yes use_template = default
Naturally, you can locally overwrite the configuration by adding +
to the Jinja block:
{%+ if foo %}Preserve indentation{% endif %}
Conclusion
This configuration option was a lifesaver for me. Hopefully, it will help you make your Ansible templates more readable as well. You can find more examples in the Jinja documentation.