Home Ansible How To Use When Conditional Statements In Ansible Playbooks

How To Use When Conditional Statements In Ansible Playbooks

Decision Making With When Conditional Statements In Ansible

By Karthick
Published: Updated: 14.8K views

If you are from a programming or scripting background then you should be familiar with the concept called "conditional statements". The conditional statements allow you to execute the code based on the result of the condition. Similarly in ansible, you can use the "when conditional statements" to execute tasks. If the condition is evaluated to true, the task will run, else the task will be skipped.

The syntax for the when conditional statement is as follows. You will learn how to apply the conditional statement with tasks in the subsequent sections.

Play definition

tasks:

    Task 1
    when: condition 

    Task 2
    when: condition 

'When' Conditional Statements With Ansible Facts

Facts are system-related information collected by ansible using the setup module on managed nodes. There may be cases where you have to make decisions based on the facts gathered.

If you have no idea about facts, we have a brief article about facts and you can access it using the link below.

In the following playbook, I have written a task to install the epel-release repository using the dnf module. Using the fact(ansible_distribution), I have written the conditional statement to install the package only on "rocky" Linux. I have used the jinga2 case conversion filter(lower) to convert the ansible_distribution output to lower case.

---
- name: Installing packages
  hosts: all
  become: true
  gather_facts: true    # By default it is set to true

  tasks:

   - name: Install epel-release
     dnf:
       pkg: epel-release
       state: present
     when: ansible_distribution | lower == "rocky"

When I run the playbook, the when condition will evaluate and run the task only on Rocky Linux. Task will be skipped for all other distributions.

$ ansible-playbook when_condition_test.yml 

PLAY [Installing packages] ********************************************************

TASK [Gathering Facts] ************************************************************
ok: [rocky.anslab.com]
ok: [ubuntu.anslab.com]

TASK [Install epel-release] ***********************************************************************************
skipping: [ubuntu.anslab.com]
ok: [rocky.anslab.com]

PLAY RECAP ***********************************************************************************
rocky.anslab.com           : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
ubuntu.anslab.com          : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

Ansible 'When' Conditional Statements With Logical AND/OR Operators

You can use the logical AND/OR operator to evaluate multiple conditions. I am using the same playbook but added one more condition based on facts. This play will be skipped since the distribution version I am running with is 8 and I am checking the condition against version 9.

   - name: Logical AND Testing
     dnf:
       pkg: htop
       state: present
     when: ansible_distribution | lower == "rocky" and ansible_distribution_major_version == "9"

Sample Output:

TASK [Gathering Facts] *********************************************************************************************************************
ok: [rocky.anslab.com]
ok: [ubuntu.anslab.com]

TASK [Logical AND Testing] *****************************************************************************************************************
skipping: [ubuntu.anslab.com]
skipping: [rocky.anslab.com]

You can also write logical AND using YAML list format.

   - name: Logical AND using List syntax
     dnf:
       pkg: htop
       state: present
     when:
       - ansible_distribution | lower == "rocky"
       - ansible_distribution_major_version == "9"

When I run the same playbook against logical OR operator, the task will run fine.

TASK [Gathering Facts] *********************************************************************************************************************
ok: [ubuntu.anslab.com]
ok: [rocky.anslab.com]

TASK [Logical OR Testing] ******************************************************************************************************************
skipping: [ubuntu.anslab.com]
ok: [rocky.anslab.com]

When you have multiple expressions to be evaluated you can put them inside parentheses. Here I am using JINJA2 syntax(int >= 8) to evaluate if the distribution version is greater than or equal to 8.

   - name: Multiple conditions
     dnf:
       pkg: epel-release
       state: present
     when: (ansible_distribution | lower == "centos" or ansible_distribution | lower == "rocky") and ansible_distribution_major_version | int >= 8

Ansible 'When' Conditional Statement With Membership Operator

You can use the IN operator to evaluate the expression against a list of values. In the following playbook, I created a task to run on RHEL based distros.

   - name: Membership Operator
     dnf:
       pkg: epel-release
       state: present
     when: ansible_distribution | lower in ["centos","rocky"]

Sample Output:

TASK [Gathering Facts] **********************************************************************************
ok: [ubuntu.anslab.com]
ok: [rocky.anslab.com]

TASK [Membership Operator] ***********************************************************************************
skipping: [ubuntu.anslab.com]
ok: [rocky.anslab.com]

'When' Conditional Statements With Ansible Variables

You can evaluate conditions against the magic variables, host vars, group vars.

If you have no idea about ansible variables, you can take a look at our article using the link below.

In the playbook below, I have created a variable called trigger_pipeline and set it to no. The condition is set in a way that the task will only run when trigger_pipeline is set to execute.

---
- name: Pipeline call
 hosts: all
 gather_facts: false

 vars:
   trigger_pipeline: no

 tasks:

   - name: Trigger Pipeline
     debug:
       msg: Running pipeline
     when: trigger_pipeline == "execute"

When I run the playbook, this task will be skipped.

TASK [Trigger Pipeline] *********************************************************
skipping: [rocky.anslab.com]

I can override the variable trigger_pipeline from the command line by running the following command.

$ ansible-playbook when_condition_test.yml -e trigger_pipeline=execute

TASK [Trigger Pipeline] **********************************************************************************
ok: [rocky.anslab.com] => {
    "msg": "Running pipeline"
}

Using the IS operator, you can check if a variable is declared on not in the conditional statements.

when: trigger_pipeline is defined          # TRUE only when var is defined
when: trigger_pipeline is undefined        # TRUE only when var is not defined

'When' Conditional Statements With Ansible Register

Register directive is used to store the output of a task. It is similar to storing the result to a variable and later using it for further processing. Based on the data stored in the register variable, you can write conditional statements.

In the tasks below, I have created two tasks where the first task will use the shell module and run /bin/true. The output will be stored in the variable register which is used in the second task to print.

 tasks:

   - name: set to true
     shell: /bin/true
     register: result

   - name: print result
     debug:
       var: result

Sample Output:

ok: [rocky.anslab.com] => {
    "result": {
        "ansible_facts": {
            "discovered_interpreter_python": "/usr/libexec/platform-python"
        },
        "changed": true,
        "cmd": "/bin/true",
        "delta": "0:00:00.003477",
        "end": "2022-05-23 17:13:15.056197",
        "failed": false,
        "msg": "",
        "rc": 0,
        "start": "2022-05-23 17:13:15.052720",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "",
        "stdout_lines": []
    }
}

You can use any of these values to create conditions. Let’s say you want to run the task only when the rc is set to zero, then you can write the condition like below.

when: result.rc == 0

Similarly based on the values available, you can write as many conditions in accordance with the use case. Below are some of the conditions based on the result variable output.

when: result.stdout != ""             # Checking if stdout is not empty
when: result.failed == "false"        # checking if failed is set to false
when: changed == "true"               # Checking if the status of changed is true

'When' Conditional Statements With Loops

You can combine the conditional statement with loops. In this case, for every item in the loop conditional statement will evaluate against the given expression.

Take a look at the play below. I am creating two users named ubuntu and rocky using the user module. The loop directive will loop against the username variable. Here the condition is written in a way that the ubuntu user should be created only in ubuntu Linux host and rocky user should be created in rocky Linux host.

- name: Create Users
  hosts: all
  gather_facts: true
  become: true

 vars:
   username:
     - ubuntu
     - rocky

 tasks:

   - name: Create the user
     user:
       name: "{{ item }}"
       state: present
       password: "{{  item | password_hash('sha512') }}"
     loop: "{{ username }}"
     when: (item == "ubuntu" and ansible_distribution | lower == "ubuntu") or (item == "rocky" and ansible_distribution | lower == "rocky")

As you can see from the below output, the users are created in the respective distributions in accordance with the condition.

TASK [Create the user] ********************************************************************************
skipping: [rocky.anslab.com] => (item=ubuntu) 
changed: [ubuntu.anslab.com] => (item=ubuntu)
skipping: [ubuntu.anslab.com] => (item=rocky) 
changed: [rocky.anslab.com] => (item=rocky)

Conclusion

In this article we have seen what a conditional statement is and how to use the when conditional statements in Ansible to evaluate conditions and run tasks based on the outcome.

When you learn advanced concepts like roles, imports, includes, you will come to know more about conditional statements and how to use them more efficiently.

Resource:

You May Also Like

Leave a Comment

* By using this form you agree with the storage and handling of your data by this website.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

This website uses cookies to improve your experience. By using this site, we will assume that you're OK with it. Accept Read More