Skip to main content

Using Conditionals

1. Using When Statements

Directive Description Usage
when Conditionally execute a task based on the evaluation of a boolean expression when: ansible_facts.os_family == 'RedHat'

Example: Conditional Task Execution

- name: Install Apache on RedHat systems
  yum:
    name: httpd
    state: present
  when: ansible_facts.os_family == 'RedHat'

Example: Multiple Conditions

- name: Configure firewall rules
  firewalld:
    service: ssh
    permanent: true
    state: enabled
  when: ansible_facts.os_family == 'RedHat' and ansible_facts.architecture == 'x86_64'
Note: The when statement supports all Jinja2 expressions and can include variables, facts, and registered results from previous tasks.

2. Comparing Variables

Operator Description Example Notes
== Equal to {{ item.name }} == 'example' Case-sensitive comparison
!= Not equal to {{ item.status }} != 'running' Case-sensitive comparison
< Less than {{ item.count }} < 10 Works with numbers and strings (lexicographically)
> Greater than {{ item.size }} > 1024 Works with numbers and strings (lexicographically)
<= Less than or equal to {{ item.value }} <= 50 Works with numbers and strings (lexicographically)
>= Greater than or equal to {{ item.version }} >= '2.0' Works with numbers and string (lexicographically)
in Check if value is in a list or string {{ item.role }} in ['admin', 'user'] Can also check substring in string
not in Check if value is not in a list or string {{ item.role }} not in ['guest', 'blocked'] Can also check substring not in string
is defined Check if a variable is defined {{ item.variable is defined }} Useful for optional variables
is not defined Check if a variable is not defined {{ item.variable is not defined }} Useful for validating required variables

Example: Comparing Variables in a Loop

- name: Process items based on status
  debug:
    msg: "Processing item {{ item.name }}"
  when: item.status == 'active'
  loop:
    - name: server1
      status: active
    - name: server2
      status: inactive

Example: Using 'in' Operator

- name: Check if user role is allowed
  debug:
    msg: "User has admin access"
  when: item.role in ['admin', 'superuser']
  loop:
    - role: admin
    - role: user
Note: When comparing strings, lexicographical ordering is used. For example, '10' < '2' evaluates to false because it compares character-by-character.

3. Checking Variable Existence

Check Description Example
vars Check if a variable is defined in the current scope {{ vars['my_var'] }}
hostvars Check if a variable is defined for a specific host {{ hostvars['host1']['my_var'] }}
groupvars Check if a variable is defined in group variables {{ groups['group1']['my_var'] }}

Example: Using vars to check variable existence

- name: Check if variable exists
  debug:
    msg: "Variable my_var is set to {{ vars['my_var'] }}"
  when: vars['my_var'] is defined

Example: Using hostvars to check variable existence

- name: Check if host variable exists
  debug:
    msg: "Host var is set to {{ hostvars[inventory_hostname]['my_var'] }}"
  when: hostvars[inventory_hostname]['my_var'] is defined

4. Testing Boolean Values

Operator Description Usage Example
bool Converts a value to a boolean {{ value | bool }}
{{ "true" | bool }}  # true
{{ "false" | bool }} # false
truthy Checks if a value is truthy {{ value | truthy }}
{{ "yes" | truthy }}   # true
{{ 0 | truthy }}       # false
falsy Checks if a value is falsy {{ value | falsy }}
{{ "" | falsy }}      # true
{{ "no" | falsy }}    # false

Example: Using Boolean Tests in Conditionals

- name: Check if a variable is truthy
  debug:
    msg: "Variable is truthy"
  when: "{{ my_var | truthy }}"

- name: Check if a variable is falsy
  debug:
    msg: "Variable is falsy"
  when: "{{ my_var | falsy }}"
Note: The bool filter converts strings like "yes", "true", "1" to true, and "no", "false", "0" to false.

5. Using Logical Operators

Operator Description Example
and Logical AND operator. Returns true if both operands are true. {{ item.value > 5 and item.value < 10 }}
or Logical OR operator. Returns true if at least one operand is true. {{ item.status == 'active' or item.status == 'pending' }}
not Logical NOT operator. Negates the boolean value. {{ not item.disabled }}

Example: Combining Conditions with Logical Operators

- name: Check if user is admin or superuser
  debug:
    msg: "User has elevated privileges"
  when: user.role == 'admin' or user.role == 'superuser'

Example: Complex Condition with Nested Logical Operators

- name: Deploy application if environment is prod and version is stable
  deploy:
    app_name: myapp
  when: >
    (ansible_env == 'production' and ansible_version is not defined) or
    (ansible_env == 'staging' and ansible_version == 'stable')

6. Checking String Content

Check Description Example
ansible.builtin.match Matches a string against a regex pattern
- name: Check if string matches pattern
  ansible.builtin.debug:
    msg: "String matches"
  when: "my_string | match('^[A-Z][a-z]+\\s+[A-Z][a-z]+$')"
ansible.builtin.search Searches for a regex pattern in a string
- name: Search for email in string
  ansible.builtin.debug:
    msg: "Email found"
  when: "my_string | search('@')"
ansible.builtin.regex_search Searches for a regex pattern in a string and returns match groups
- name: Extract version from string
  ansible.builtin.set_fact:
    version: "{{ my_string | regex_search('v(\\d+\\.\\d+\\.\\d+)', '\\1') }}"
  when: "my_string | regex_search('v(\\d+\\.\\d+\\.\\d+)')"
ansible.builtin.regex_replace Replaces a regex pattern in a string with a replacement value
- name: Replace all digits with X
  ansible.builtin.set_fact:
    masked_string: "{{ my_string | regex_replace('\\d', 'X') }}"
ansible.builtin.startswith Checks if a string starts with a specific prefix
- name: Check if string starts with 'Hello'
  ansible.builtin.debug:
    msg: "Starts with Hello"
  when: "my_string | startswith('Hello')"
ansible.builtin.endswith Checks if a string ends with a specific suffix
- name: Check if string ends with '.txt'
  ansible.builtin.debug:
    msg: "Ends with .txt"
  when: "my_string | endswith('.txt')"
ansible.builtin.contains Checks if a string contains a substring
- name: Check if string contains 'ansible'
  ansible.builtin.debug:
    msg: "Contains ansible"
  when: "my_string | contains('ansible')"
ansible.builtin.length Gets the length of a string
- name: Check if string is longer than 5 characters
  ansible.builtin.debug:
    msg: "String is long"
  when: "my_string | length > 5"

7. Using Jinja2 Tests

Test Description Example
defined Checks if a variable is defined {{ var is defined }}
undefined Checks if a variable is not defined {{ var is undefined }}
even Checks if a number is even {{ 4 is even }}
odd Checks if a number is odd {{ 5 is odd }}
none Checks if a variable is None {{ var is none }}
string Checks if a variable is a string {{ var is string }}
number Checks if a variable is a number {{ var is number }}
boolean Checks if a variable is a boolean {{ var is boolean }}
iterable Checks if a variable is iterable {{ var is iterable }}
mapping Checks if a variable is a mapping (dict-like) {{ var is mapping }}

Example: Using Jinja2 Tests in Conditionals

- name: Check if a variable is defined
  debug:
    msg: "Variable is defined"
  when: "{{ var is defined }}"

- name: Check if a variable is a string
  debug:
    msg: "Variable is a string"
  when: "{{ var is string }}"

- name: Check if a number is even
  debug:
    msg: "Number is even"
  when: "{{ item is even }}"
  with_items:
    - 2
    - 3
    - 4

8. Evaluating Registered Results

Variable Description Usage
ansible_facts Facts gathered about the target host Used to access system information like OS version, network interfaces, etc.
ansible_env Environment variables on the target host Access environment settings such as PATH, HOME, etc.
ansible_pkg_mgr Package manager used on the target host Determines whether yum, apt, or another package manager is in use

Example: Using Registered Results in Conditionals

- name: Check if a package is installed
  command: dpkg -l nginx
  register: nginx_check
  ignore_errors: true

- name: Notify if nginx is installed
  debug:
    msg: "Nginx is installed"
  when: nginx_check.rc == 0

- name: Install nginx if not present
  apt:
    name: nginx
    state: present
  when: nginx_check.rc != 0
Note: The rc field in registered results refers to the return code of the command executed. A return code of 0 typically indicates success.
Warning: When using ignore_errors: true, ensure that your conditional logic properly evaluates the result to avoid unexpected behavior.

9. Checking File States

State Description Usage Notes
absent Ensures the file or directory does not exist. state: absent Deletes the file or directory if it exists.
file Ensures the path is a file. state: file Creates an empty file if it does not exist.
directory Ensures the path is a directory. state: directory Creates the directory if it does not exist.
hard Ensures the path is a hard link to the specified file. state: hard Creates a hard link if it does not exist.
link Ensures the path is a symbolic link to the specified file. state: link Creates a symbolic link if it does not exist.
touch Ensures the file exists and updates its timestamp. state: touch Creates the file if it does not exist.

Example: Check File State

- name: Ensure file exists and is up to date
  ansible.builtin.file:
    path: /etc/myapp/config.ini
    state: touch
    mode: '0644'

Example: Delete a File if It Exists

- name: Remove a directory if it exists
  ansible.builtin.file:
    path: /var/log/myapp
    state: absent

10. Using Complex Conditionals

Operator Description Example
and Logical AND operator {{ item.value > 5 and item.value < 10 }}
or Logical OR operator {{ item.value == 5 or item.value == 10 }}
not Logical NOT operator {{ not item.value }}
| Filter operator (used in Jinja2 templates) {{ item.value | lower }}
== Equality operator {{ item.status == 'running' }}
!= Not equal operator {{ item.status != 'stopped' }}
< Less than operator {{ item.cpu_usage < 80 }}
> Greater than operator {{ item.memory > 1024 }}
<= Less than or equal operator {{ item.count <= 10 }}
>= Greater than or equal operator {{ item.version >= '2.0' }}

Example: Complex conditional in a task

- name: Check system status
  command: uptime
  register: result
  when: 
    - result.rc == 0
    - result.stdout | length > 0
    - "'load average' in result.stdout"

Example: Using variables with complex conditionals

- name: Configure firewall rules
  firewalld:
    port: "{{ item.port }}"
    protocol: "{{ item.protocol }}"
  loop: "{{ firewall_rules }}"
  when: 
    - item.enabled == true
    - item.port is defined
    - item.protocol in ['tcp', 'udp']
    - item.priority <= 5
Note: Complex conditionals in Ansible can involve multiple operators and nested expressions. Use parentheses to group conditions for clarity.

11. Applying Conditionals to Blocks

Property Description Example
when Condition to evaluate for block execution when: ansible_facts.os_family == 'RedHat'
loop Loop over a list or set of items loop: ['item1', 'item2']

Example: Conditional block with loop

- name: Install packages based on OS
  yum:
    name: "{{ item }}"
    state: present
  loop:
    - httpd
    - mod_ssl
  when: ansible_facts.os_family == 'RedHat'
Note: The when clause is evaluated for each item in the loop, allowing conditional execution per iteration.

Was this article helpful?