Hi,
I am not sure whether someone has come across this issue previously - trying to search the group for 'when' and 'is defined' did not yield me anything useful. So I am posting it as a new topic here.
I have encountered that in case I use 'when:' clause where I need to test whether one variable is set to 'true' and another one is defined, the following playbook triggers action even if the first variable is 'false':
cat > test_playbook.yaml <<EOF
---
- hosts: all
gather_facts: false
tasks:
- name: Play only if var1 is true and var2 is defined
local_action: command echo "Yes {{ var1 }} is true and {{ var2 }} is defined"
when: var1 and var2 is defined
EOF
$ ansible-playbook -i host -v test_playbook.yaml --extra-vars "var1=false var2='something'"
PLAY [all] ********************************************************************
TASK: [Play only if var1 is true and var2 is defined] *************************
changed: [localhost] => {"changed": true, "cmd": ["echo", "Yes false is true and something is defined"], "delta": "0:00:00.003256", "end": "2014-02-04 11:19:56.720699", "rc": 0, "start": "2014-02-04 11:19:56.717443", "stderr": "", "stdout": "Yes false is true and something is defined"}
PLAY RECAP ********************************************************************
localhost : ok=1 changed=1 unreachable=0 failed=0
Only if I change the conditions to be supplied on separate 'when:' lines, it works as expected:
cat > test1_playbook.yaml <<EOF
---
- hosts: all
gather_facts: false
tasks:
- name: Play only if var1 is true and var2 is defined
local_action: command echo "Yes {{ var1 }} is true and {{ var2 }} is defined"
when: var2 is defined
when: var1
EOF
$ ansible-playbook -i host -v test_playbook.yaml --extra-vars "var1=false var2='something'"
PLAY [all] ********************************************************************
TASK: [Play only if var1 is true and var2 is defined] *************************
skipping: [localhost]
PLAY RECAP ********************************************************************
localhost : ok=0 changed=0 unreachable=0 failed=0
$ ansible-playbook -i host -v test_playbook.yaml --extra-vars "var1=true var2='something'"
PLAY [all] ********************************************************************
TASK: [Play only if var1 is true and var2 is defined] *************************
changed: [localhost] => {"changed": true, "cmd": ["echo", "Yes true is true and something is defined"], "delta": "0:00:00.002733", "end": "2014-02-04 11:22:20.289360", "rc": 0, "start": "2014-02-04 11:22:20.286627", "stderr": "", "stdout": "Yes true is true and something is defined"}
PLAY RECAP ********************************************************************
localhost : ok=1 changed=1 unreachable=0 failed=0
However in this case it fails (not skips) when the var2 is undefined and var1 is true, which is not really a desired behaviour:
$ ansible-playbook -i host -v test_playbook.yaml --extra-vars "var1=true"
PLAY [all] ********************************************************************
TASK: [Play only if var1 is true and var2 is defined] *************************
fatal: [localhost] => One or more undefined variables: 'var2' is undefined
FATAL: all hosts have already failed -- aborting
PLAY RECAP ********************************************************************
to retry, use: --limit @/Users/roman/test_playbook.yaml.retry
localhost : ok=0 changed=0 unreachable=1 failed=0
The order of 'when's also matters, in case their order is reverted like follows
when: var1
when: var2 is defined
the playbook starts behaving like in the first example where 'when' conditions were supplied on one line using the 'and' operator.
If I use
when: var1==true and var2 is defined
the playbook would skip the action even all conditions are satisfied:
$ ansible-playbook -i host -v test_playbook.yaml --extra-vars "var1=true var2='defined'"
PLAY [all] ********************************************************************
TASK: [Play only if var1 is true and var2 is defined] *************************
skipping: [localhost]
PLAY RECAP ********************************************************************
localhost : ok=0 changed=0 unreachable=0 failed=0
The
docs do not shed any more light on that strange behaviour.
Thanks a lot in advance,