- name: Bug report
hosts: localhost
gather_facts: no
connection: local
vars:
foo: no
bar: "{{ foo }}"
tasks:
- debug: msg='This should not be skipped!'
when: not bar
`
Seeing the code one would expect that the message “This should not be skipped” is displayed when the code is executed. In reality, however, the code gets skipped because the bar parameter is not correctly resolved to its value no. Rewriting the when clause to look like this:
when: not {{ bar }}
seems to fix the problem.
Also it seems that this problem is only caused when the not operator is used, because if I use the following code sample:
`
name: Bug report
hosts: localhost
gather_facts: no
connection: local
vars:
foo: yes
bar: “{{ foo }}”
tasks:
debug: msg=‘This should not be skipped!’
when: bar
`
everything seems to work as expected.
So is this a bug (perhaps a known issue) or am I doing something wrong?
This is mostly due to how ansible casts values when dereferencing.
It is always safest to use the |bool filter when evaluating a variable that you think should be a boolean.
Such as:
when: not bar|bool
Otherwise, in your example it is evaluating the string value “no” instead of a falsely YAML no value. And a non-zero length string evaluates as truthy.
It seems this is a source of a lot of confusion. Looking at it - it should be a best practice to use the bool filter whenever you use when. The documentation doesn’t do that and this leads to confusion.
I am interested on the opinions of others - can this be fixed in Ansible to work as expected or should casting to bool should be a best practice in when-s?