can anyone explain the following Jinja behaviour in Ansible?
The following code works: The task is skipped because the job_function is not in the exclusion_functions array
- name: Lowercase test
hosts: localhost
gather_facts: false
vars:
job_function: 'VRIJwillig'
exclusion_functions:
- vrijwilliger
- maatje
tasks:
- name: Test for function in exclusions
debug:
msg: In exclusions
when: (job_function | lower) in exclusion_functions
The following code works as well, the second task is skipped.
- name: Lowercase test
hosts: localhost
gather_facts: false
vars:
job_function: 'VRIJwillig'
exclusion_functions:
- Vrijwilliger
- Maatje
tasks:
- name: Initialiseer variabelen
set_fact:
exclusions: "{{ exclusion_functions | lower }}"
- name: Test for function in exclusions
debug:
msg: In exclusions
when: (job_function | lower) in exclusions
But this doesn't work, the task isn't skipped:
---
- name: Lowercase test
hosts: localhost
gather_facts: false
vars:
job_function: 'VRIJwillig'
exclusion_functions:
- Vrijwilliger
- Maatje
tasks:
- name: Test for function in exclusions
debug:
msg: In exclusions
when: (job_function | lower) in (exclusion_functions | lower)
Why is the task not skipped in the last code snippet? job_function | lower
is vrijwillig
, and exclusion_functions | lower
is ['vrijwilliger','maatje']
, and the first one isn't in the second one.
The value of the variable exclusion_functions is a list
- debug:
msg: |
{{ exclusion_functions }}
{{ exclusion_functions | type_debug }}
gives
msg: |-
['Vrijwilliger', 'Maatje']
list
The filter lower converts the argument to a string
- debug:
msg: |
{{ exclusion_functions | lower }}
{{ exclusion_functions | lower | type_debug }}
The output looks like a list but it isn't. It's a string
msg: |-
['vrijwilliger', 'maatje']
str
This explains why the below task isn't skipped
- name: Test for function in exclusions
debug:
msg: In exclusions
when: (job_function | lower) in (exclusion_functions | lower)
The value VRIJwillig
of the variable job_function is converted to lowercase vrijwillig
which is in the string ['vrijwilliger', 'maatje']
The solution is to map the filter lower to each list's item
- debug:
msg: |
{{ exclusion_functions | map('lower') }}
{{ exclusion_functions | map('lower') | type_debug }}
shows the result is a list with items converted to lowercase
msg: |-
['vrijwilliger', 'maatje']
list
Then, as expected, the below task is skipped
- name: Test for function in exclusions
debug:
msg: In exclusions
when: (job_function | lower) in (exclusion_functions | map('lower'))
Example of a complete playbook for testing
- name: Lowercase test
hosts: localhost
vars:
job_function: VRIJwillig
exclusion_functions:
- Vrijwilliger
- Maatje
tasks:
- debug:
msg: |
{{ exclusion_functions }}
{{ exclusion_functions | type_debug }}
- debug:
msg: |
{{ exclusion_functions | lower }}
{{ exclusion_functions | lower | type_debug }}
- name: Test for function in exclusions
debug:
msg: In exclusions
when: (job_function | lower) in (exclusion_functions | lower)
- debug:
msg: |
{{ exclusion_functions | map('lower') }}
{{ exclusion_functions | map('lower') | type_debug }}
- name: Test for function in exclusions
debug:
msg: In exclusions
when: (job_function | lower) in (exclusion_functions | map('lower'))