Bootstrap FreeKB - Ansible - when parameter (if else statement)
Ansible - when parameter (if else statement)

Updated:   |  Ansible articles

The when parameter (which is like an if statement) can be used to do something when a condition evaluates to true or false.

when: <some condition>

 

Often, the when parameter is used to compare a variable to a boolean (such as true, false, 1, or 0), to a string (such as Hello World), or to an integer (such as 12345). In this example, the when parameter is used to determine if the foo variable contains string "bar". Notice foo is not wrapped in quotes and bar is wrapped in quotes. Since foo is not wrapped in quotes, foo is interpreted as a variable. Because bar is wrapped in quotes, bar is interpreted as a string.

---
- hosts: all
  tasks:
  - ansible.builtin.debug: 
      msg: the foo variable does not equal 'bar'
    when: foo != 'bar'
...

 

The when parameter can also be used to compare a variable to another variable. In this example, the foo variable is compared to the bar variable. Notice both foo and bar are not wrapped in quotes, meaning that both will be interpreted as variables.

---
- hosts: all
  tasks:
  - ansible.builtin.debug: 
      msg: the foo variable does not equal the bar variable
    when: foo != bar
...

 

Or you may want to pipe a variable to a boolean, integer, or string. In this example, the bar variable is piped to a string.

---
- hosts: all
  tasks:
  - ansible.builtin.debug:
      msg: the foo variable does not equal the bar variable piped to a string
    when: foo != bar|string
...

 

AVOID TROUBLE

Jinja2 double curly braces cannot be used in the when parameter

---
- hosts: all
  tasks:
  - ansible.builtin.debug:
      msg: this will cause the playbook to fail fatal because Jinja double curley braces cannot be used in a when statement
    when: foo != {{ bar }}
...

 

Here is how you can use variables in a when statement. In this example, the variable named item is used in the when statement.

In this example, target_directory will be set to /tmp/foo if my_directory is /tmp/foo or target_directory will be set to /tmp/bar if my_directory is /tmp/bar.

---
- hosts: all
  tasks:  
  - ansible.builtin.set_fact:
      target_directory: /tmp/{{ foo }}
    when: my_directory is regex '/tmp/'+item
    with_items:
    - 'foo'
    - 'bar'
...

 

Multiple when statements can be used.

---
- hosts: all
  tasks:
  - ansible.builtin.debug: 
      msg: multiple when statements
    when: foo != hello and foo != world
...

 

Or like this, using or.

---
- hosts: all
  tasks:
  - ansible.builtin.debug:
      msg: multiple when statements using or
    when: foo != hello or foo != world
...

 

Or like this. This would perform an "and" situation, where all of the when statements would have to evaluate to true, not an "or" situation.

---
- hosts: all
  tasks:
  - ansible.builtin.debug:
      msg: multiple when statements
    when:
    - foo != hello
    - foo != world
...

 

Or like this, using or.

---
- hosts: all
  tasks:
  - ansible.builtin.debug: 
      msg: multiple when statements using or
    when:
    - foo != hello or
    - foo != world
...

 

Here is an example of a when statement that has multiple and & or conditions.

---
- hosts: all
  tasks:
  - ansible.builtin.debug: 
      msg: multiple when statements
    when: ((foo != hello) and (foo != world)) or ((bar != hello) and (bar != world))
...

 

Sometimes, for more complex situation, or to avoid multiple tasks, I will use a jinja if else statement.

---
- hosts: all
  tasks:
  - ansible.builtin.set_fact:
    bar: "{%- if foo == 'hello' -%}Hello
          {%- elif foo == 'world' -%}World
          {%- else -%}false
          {%- endif -%}"
...

 

And here is a jinja2 if else statement that checks if the foo variable contains hello or world.

---
- hosts: all
  tasks:
  - ansible.builtin.set_fact:
    bar: "{%- if 'hello' in foo -%}Hello
          {%- elif 'world' in foo -%}World
          {%- else -%}false
          {%- endif -%}"
...

 

Or like this.

---
- hosts: all
  tasks:
  - ansible.builtin.set_fact:
    bar: "{%- if foo | regex_search('.*hello.*') -%}Hello
          {%- elif 'world' in foo -%}World
          {%- else -%}false
          {%- endif -%}"
...

 

Here are more common when statements.

when the foo variable is defined or undefined (undefined can be prevented with the default filter)

when: foo is defined

when: foo is undefined

when the foo variable or list is empty or not empty

when: foo | length > 0

when: foo | length == 0

when the foo variable does or does not equal string hello or world

when: foo == 'hello'

when: foo != 'world'

when the foo variable does or does not contain an integer

when: foo | type_debug == 'int'

when: foo | type_debug != 'int'

when the foo variable does or does not contain a boolean

when: foo | type_debug == 'bool'

when: foo | type_debug != 'bool'

when the foo variable does or does not equal boolean true or false

when: foo == true

when: foo != false

when the foo variable, list or dictionary does or does not contain string hello or world

when: foo is search 'hello|world'

when: foo is not search 'hello|world'

when the content of the foo variable does or does not contain the content of the bar variable

when: bar in foo

when: bar not in foo

when the foo variable or list does or does not contain boolean true

when: true in foo

when: false not in foo

when the foo variable does or does not contain string hello or world with no whitespace

when: foo is regex '(?i)^(hello|world)$'

when: foo is not regex '(?i)^(hello|world)$'

when the foo variable does or does not contain the bar variable

when: foo is regex '(?i).*'+bar+'.*'

when: foo is not regex '(?i).*'+bar+'.*'

when the foo variable does or does not contain string hello (see regex_search)

when: foo | regex_search('(?i).*hello.*')

when: not foo | regex_search('(?i).*hello.*')

when the foo variable does or does not contain the bar variable (see regex_search)

when: foo | regex_search('(?i).*'+bar+'.*')

when: not foo | regex_search('(?i).*'+bar+'.*')

when hostname in one or more groupswhen: inventory_hostname in ( groups['foo'] + groups['bar'] )
if file existssee FreeKB - Ansible - Determine if a file or directory exists using the stat module

 




Did you find this article helpful?

If so, consider buying me a coffee over at Buy Me A Coffee



Comments


April 26 2022 by Suresh
Very useful and well written

Add a Comment


Please enter 68e504 in the box below so that we can be sure you are a human.