2

I’m building some Ansible (4.6.0) / Jinja2 (3.0.1) templates that all rely on a shared import for some helper macros.

A few of these macros are complex enough that they require many arguments to be passed from the local calling context:

example.j2

{# many files use this helper module #}
{% import 'helpers.j2' as helpers -%}

Simple:  {{ helpers.simple_action() }}
Complex: {{ helpers.complex_action(so, many, args, required, from, the, local, context, it, gets, ridiculous) }}

helpers.j2

{# helpers.j2 #}
{% macro simple_action(optional=True) %}
{% if optional %}
Do the thing
{% else %}
Do the OTHER thing
{% endif %}
{% endmacro %}

{% macro complex_action(so, many, args, required, from, the, local, context, it, gets, ridiculous) %}
{# Use the arguments to build a complex response #}
So: {{ so }}
Many: {{ many }}
Args: {{ args }}
{# […] #}
{% endmacro %}

What I would much rather do for the complex_action is pass the entire local context, and let it pull out what it needs. My searching for this haven’t turned up anything for Ansible, though it looks like Django has this available for its templates.

Further, this answer shows how I might go about it with bare Jinja2, but I‘m not sure where to define the pass_context (which I think was renamed from contextfunction in Jinja2 3.0) function to make use of it in an Ansible template.

I suspect I can create an Ansible plugin to provide it if that is the only way, but I have to wonder if there isn’t something I’m clearly missing.

My Goal

In short, here’s what I envision, once the function (or built-in I’ve missed) is working:

context_example.j2

{% import 'context_helpers.j2' as helpers -%}
{{ helpers.complex(local_context(), other_arg="example")

context_helpers.j2

{% macro complex_action(ctx, other_arg) %}
So: {{ ctx.so }}
Many: {{ ctx.many }}
Args: {{ ctx.args }}
{# […] #}
Other: {{ other_arg }}
{% endmacro %}
Erik Ogan
  • 21
  • 2

0 Answers0