Support for functions for complex expressions

Hi all,

Ansible has a lot of options, where combining and chaining filters is of great usage.
In certain cases the final result might become a bit hard to maintain if it is re-used in multiple places. E.g. take the following examples:

merged_list: “{{ (lookup(‘vars’, *query(‘varnames’, ‘^.+__merge_list$’)) + [testlist_initial_value]) | flatten(levels=1) }}”

merged_dict: “{{ lookup(‘vars’, *query(‘varnames’, ‘^.+__merge_dict$’)) | combine(testdict_initial_value, recursive=True, list_merge=‘append’) }}”

I couldn’t find anything about Ansible having this functionality, but is it an idea for adding functions/aliases to Ansible where often re-used expressions can be stored as a ‘function’ or ‘alias’ so the user can call it with the appropriate input arguments?

In case of the above e.g. defining the expressions somewhere and calling it as e.g.
{{ merge_dict(‘__merge_dict’, testdict_initial_value) }}

The user then only has to define the complex expression once, after which it can re-use the function in multiple places throughout the project.

Happy to hear any thoughts on this idea (or whether this is already possible).

Regards,
Roy

Jinja2 has this already, macros
https://jinja.palletsprojects.com/en/2.10.x/templates/#macros

Thanks for the link Brian!

I experimented a bit with macros but couldn’t find a working solution.
These are the lines I would like to have available in a macro: https://github.com/rlenferink/ansible-function-test/blob/9c83a40a29eb616a59b4da713771545a2aa44f32/playbook.yml#L15-L16

Knowing that this is called a macro, I found the following feature request: https://github.com/ansible/ansible/issues/36130
It is mentioned in the issue that the decision was made not to add such a feature.

I tried using the described workaround but wasn’t successful so far:

https://github.com/rlenferink/ansible-function-test/tree/macro-try

Honestly using a separate file for defining this macro and then importing it for every usage also feels a bit like a workaround (since this would not something I’d do once, more like in the 100+ occurrences area).

Do you know if there is an alternative to define and use macros within a playbook?
Is it maybe worth reevaluating the feature request for adding support for this?

Roy

Mostly i was thinking for the use of in templates, the only other
thing i can think of is using 'intermediate vars' to keep reusable
expressions and then creating their input when needed:

- play:
  vars:
      merged_list: "{{ (lookup('vars', *query('varnames',
merge_pattern$')) + [testlist_initial_value]) |
flatten(levels=merge_flatten_levels|default(1)) }}"
....

- name: also works with 'vars' in other scopes, using set_fact to
get 'static value'
   set_fact:
       mylist: '{{merged_list}}'
   vars:
     testlist_initial_value: [10,11]
     merge_pattern: '^.+_merge_list'
      a_merge_list: [1,2,3]
      b_merge_list: [4,5,6]