/dev/blog/ID10T

Ansible: Extend variable values in Jinja 2 templates

• Ansible • Comments
Advertisement

In a Jinja 2 Template for one of my Ansible playbooks I wanted to construct a string containing several potentially filled variables to eventually append it to a command execution.

I tried this:

{% set additional_opts = '' %}
{% for opt_arg, opt_name in [
  (item.exclusive_labels|default(''), '--exclusive_labels'),
  (item.ignore_labels|default(''), '--ignore_labels'),
  (item.exclusive_prefixes|default(''), '--exclusive_prefixes'),
  (item.ignore_prefixes|default(''), '--ignore_prefixes')
] %}
{% if opt_arg %}
{% set additional_opts %}{{ additional_opts }} {{ opt_name }}="{{ opt_arg }}"
{%- endset %}
{% endif %}
{% endfor %}

runme.py {{ additional_opts }}

But that didn’t work. The additional_opts variable never contained any value outside of the loop. After some research, I found out, that this is working as intended. This is even mentioned in Jinjas (excellent) Template Designer Documentation:

Please keep in mind that it is not possible to set variables inside a block and have them show up outside of it. This also applies to loops.

And there’s even a proposal how to achieve this use case properly:

As of version 2.10 more complex use cases can be handled using namespace objects which allow propagating of changes across scopes

After reading that, correcting my template didn’t take long. It ended up looking like this:

{% set ns=namespace(additional_opts='') %}
{% for opt_arg, opt_name in [
  (item.exclusive_labels|default(''), '--exclusive_labels'),
  (item.ignore_labels|default(''), '--ignore_labels'),
  (item.exclusive_prefixes|default(''), '--exclusive_prefixes'),
  (item.ignore_prefixes|default(''), '--ignore_prefixes')
] %}
{% if opt_arg %}
{% set ns.additional_opts %}{{ ns.additional_opts }} {{ opt_name }}="{{ opt_arg }}"
{%- endset %}
{% endif %}
{% endfor %}

runme.py {{ ns.additional_opts }}

While this way is a bit less intuitive, it works like a charm.

Advertisement
More posts
comments powered by isso

Advertisement