I have a list of proxies that need to be selected based on the cluster location. For example, my cluster names are 'abc' and 'def'. All nodes on clusters start with the cluster name (e.g. abc1023.net for abc etc.)
I want to select the proxies for pip based on the current inventory_hostname and provide it in the arguments. I tried to use the map of with_items and 'creating' the when condition within the map as per the code below:
- name: run pip on proxy
pip:
name: <package_name>
extra_args: "--proxy item.proxy"
when: "item.when"
with_items:
- {proxy: 'http:abc_proxy:port', when: "'abc' in {{inventory_hostname|lower}}"}
- {proxy: 'http:def_proxy:port', when: "'def' in {{inventory_hostname|lower}}"}
The problem I am facing is that this condition is always perceived as true. I tried replacing when: "'abc' in {{inventory_hostname|lower}}" to when: false and that actually works. That is, making it an explicit false actually returns false but not when I check the condition in string quotes. I think this when within the map is just perceived as true if it contains any value.
How do I explicitly check this condition in the when map? Removing the quotes does not help as it throws syntactical error:
We could be wrong, but this one looks like it might be an issue with missing quotes. Always quote template expression brackets when they start a value. For instance: with_items: - {{ foo }} Should be written as: with_items: - "{{ foo }}" exception type: <class 'yaml.parser.ParserError'>
Other solutions tried
- Added the vars within the task
- name: run pip on proxy
vars:
abc_status: "{{ true if 'abc' in {{inventory_hostname|lower}} else false }}"
def_status: "{{ true if 'def' in {{inventory_hostname|lower}} else false }}"
pip:
name: <package_name>
extra_args: "--proxy item.proxy"
when: "item.when"
with_items:
- {proxy: 'http:abc_proxy:port', when: abc_status}
- {proxy: 'http:def_proxy:port', when: def_status}
2.Added the task to set_fact
- set_fact:
abc_status: true
when: inventory_hostname|lower is match('abc.*')
- set_fact:
def_status: true
when: inventory_hostname|lower is match('def.*')
- Tested the false case
I tested the false case in the following ways on abc cluster:
- name: run pip on proxy
vars:
abc_status: "{{ true if 'abc' in {{inventory_hostname|lower}} else false }}"
def_status: "{{ true if 'def' in {{inventory_hostname|lower}} else false }}"
pip:
name: <package_name>
extra_args: "--proxy item.proxy"
when: "item.when"
with_items:
- {proxy: 'http:def_proxy:port', when: def_status}
This should always fail as the proxy as well as the when condition is checking on def cluster whereas it is running on abc cluster. But I get the following Ansible output:
TASK [<project> : run pip on proxy] ************************************************
changed: [abc1023.net] => (item={u'when': u'def_status', u'proxy': u'http:def_proxy:port'})
This is the output I always get with other tried solutions as well.
Question
Even after trying above different solutions, when: "item.when" always return true (even when it should return false). How can I fix this? Is there any better solution to implement my use case?
For completeness, I am using ansible 2.4.1.0.