I am working on an ansible playbook task in ansible version 2.9 and I have a loop paired with a when conditional and I'd like to have the conditional test for two values rather than just one (which works for me). Is there a way to perform a boolean OR using a search() test in the when statement?
Here is what I have used that works (just testing one value):
- name: Test Interface Looping
hosts: test
vars:
desc_search: "test"
desc_search_c: "TEST"
tasks:
- name: IOS Facts
ios_facts:
gather_subset:
- '!all'
- '!min'
gather_network_resources:
- 'interfaces'
register: result
- debug: var=result
- name: Update all descriptions
ios_interfaces:
config:
- name: "{{ item.key }}"
description: "Test Done"
state: replaced
loop: "{{ ansible_net_interfaces|dict2items }}"
when: item.value.description is search(desc_search)
Here is what I would like to do if possible (so far not working):
- name: Test Interface Looping
hosts: test
vars:
desc_search: "test"
desc_search_c: "TEST"
tasks:
- name: IOS Facts
ios_facts:
gather_subset:
- '!all'
- '!min'
gather_network_resources:
- 'interfaces'
register: result
- debug: var=result
- name: Update all descriptions
ios_interfaces:
config:
- name: "{{ item.key }}"
description: "Test Done"
state: replaced
loop: "{{ ansible_net_interfaces|dict2items }}"
when: item.value.description is search(desc_search) or search(desc_search_c)
I have tried adding the | bool
at the end of the when
statement as well but in both cases I get the error: The conditional check 'item.value.description is search(desc_search) or search(desc_search_c)' failed. The error was: error while evaluating conditional (item.value.description is search(desc_search) or search(desc_search_c)): 'search' is undefined...
Is it possible to do what I'm trying to do here? Apologies for any incorrect terminology I may have used. I am a network engineer so not formally educated in ansible or programming/scripting.
There are 3 answers to your question, starting with the error you are receiving: search
is not a jinja2 "filter" it's a "test", meaning it must be used with the is
or is not
keywords (as you correctly did in the first half of the when
):
when: item.value.description is search(desc_search) or item.value.description is search(desc_search_c)
the second answer is that since what you care about appears to be a case insensitive search, you can specify that via the (?i)
regex modifier, or the ignorecase=True
kwarg
when: item.value.description is search(desc_search, ignorecase=True)
and as an alternate to that, if you really only want test
and TEST
(meaning my presumption about ignorecase
was wrong), and you do care about the case, but just want those two strings, you can use the |
regex alternation character:
when: item.value.description is search(desc_search+"|"+desc_search_c)
It's like many things in programming, there are a lot of ways to accomplish that goal, and you should pick the one that's easiest for you and your team to reason about when you look at this code next month :-)