Ansible "when variable == true" not behaving as expected
You need to convert the variable to a boolean:
force_install|bool == true
I don't claim I understand the logic behind it. In python any non-empty string should be truthy. But when directly used in a condition it evaluates to false.
The bool filter then again interprets the strings 'yes'
, 'on'
, '1'
, 'true'
(case-insensitive) and 1
as true (see source). Any other string is false.
You might want to also set a default value in case force_install
is not defined, since it would result in an undefined variable error:
force_install|default(false)|bool == true
Yeah... certainly requires testing. I recommend
| bool
is good unless you expect undefined varsvar is defined and (var | bool)
if you expect undefined vars
default(False)
is OK as long and you are happy that these are true if the input is not parsed from YAML. I.e. variables defined through --extra_vars
CLI parameter are strings.
"false"
"null"
"defined string"
Hope this helps:
#!/usr/bin/env ansible-playbook
---
- name: Test truthiness
hosts: localhost
gather_facts: False
vars:
truthy_vars:
# TRUE
- True
- 1
- "true"
# FALSE
- "false"
- null
- False
- 0
# ERROR (invalid sytax error stops the loop of the first of these)
- "null"
- "defined string"
# ERROR
# truthy_var_undefined
# FALSE
truthy_var_defined:
tasks:
- name: Test truthy
debug:
msg: "is truthy"
ignore_errors: True # beware, the loo
when: item
loop: "{{ truthy_vars }}"
loop_control:
label: Test {{ item }}
- name: truthy_var_undefined
debug:
when: truthy_var_undefined
ignore_errors: true
- name: truthy_var_defined
debug:
when: truthy_var_defined
- name: Test | default(False)
hosts: localhost
gather_facts: False
vars:
default_pipe_vars:
# TRUE
- True
- 1
- "true"
# beware these:
- "false"
- "null"
- "defined string"
# FALSE
- null
- False
- 0
# FALSE
# default_pipe_undefined
# FALSE
default_pipe_defined:
tasks:
- name: Test | default(False)
debug:
msg: "is not | default(False)"
when: item | default(False)
loop: "{{ default_pipe_vars }}"
loop_control:
label: Test {{ item }}
- name: default_pipe_undefined | default(False)
debug:
when: default_pipe_undefined | default(False)
- name: default_pipe_defined | default(False)
debug:
when: default_pipe_defined | default(False)
- name: Test | bool
hosts: localhost
gather_facts: False
vars:
bool_vars:
# TRUE
- True
- 1
- "true"
# FALSE
- "defined string"
- "null"
- "false"
- null
- False
- 0
# ERROR
# bool_undefined
# FALSE
bool_defined:
tasks:
- name: Test bool parsing
debug:
msg: "parsed as true booleans"
when: item | bool
loop: "{{ bool_vars }}"
loop_control:
label: Test {{ item }}
- name: bool_undefined | bool
debug:
when: bool_undefined | bool
ignore_errors: true
- name: bool_defined var | bool
debug:
when: bool_defined | bool
- name: Test is defined and | bool
hosts: localhost
gather_facts: False
vars:
defined_bool_vars:
# TRUE
- True
- 1
- "true"
# FALSE
- "defined string"
- "null"
- "false"
- null
- False
- 0
# FALSE
# defined_bool_undefined
# FALSE
defined_bool_defined:
tasks:
- name: Test bool parsing
debug:
msg: "parsed as true booleans"
when:
- item is defined
- item | bool
loop: "{{ defined_bool_vars }}"
loop_control:
label: Test {{ item }}
- name: defined_bool_undefined | bool
debug:
when:
- defined_bool_undefined is defined
- defined_bool_undefined | bool
ignore_errors: true
- name: defined_bool_defined var | bool
debug:
when:
- defined_bool_defined is defined
- defined_bool_defined | bool
https://gist.github.com/kcd83/4ea23d201c271b58f1c4ef7844408657