How to Use When Conditionals Statement in Ansible Playbook

Oftentimes, Ansible plays contain various sets of variables. The tasks to be carried out using these variables vary according to the nature of these variables. And this is where Conditional statements come in. Conditional statements are mostly used in Ansible playbooks where there is a mix of different variables, each representing different entities such as software packages, servers, networking devices and so on. In this guide, we will demonstrate how to use various when conditional statements in a setup with servers running different operating systems.

Using ‘when’ conditional statement

Traditional programming language usually uses the if-else statement when more than one outcome is expected. In Ansible, ‘when’ statement is used instead to determine the outcome of a variable. So instead of using the if-else statement, you define what you want to happen. The syntax is as shown below:

  tasks . . .

 when: condition

Let’s take an example of a setup with an Ansible control node and two servers as shown below:

  • CentOS 7 server                   IP: 173.82.115.165
  • Ubuntu 18.04 server           IP: 173.82.202.239
  • Ansible control node           IP: 173.82.120.14

Using the Ansible Control node which has already been set up and configured to communicate with the two servers.

The task at hand will be to install the Apache web server on both web servers using a single playbook.

But here’s the catch,

Installation of Apache on CentOS, which is a Red Hat flavor,  differs from  Ubuntu, which is a Debian flavor. Both use different package managers and the Apache package also differs in both cases.  In such a scenario, where we have different variables at play, a conditional statement is crucial.

Given the differences mentioned,  we are going to use the ‘when’ conditional statement to install Apache web server as shown in the playbook as shown:

---
- name: install Apache Web-Server
  hosts: all
  tasks:
    - name: Install Apache on CentOS  Server
      yum: name=httpd  state=present
      become: yes
      when: ansible_os_family == "RedHat"

    - name: Install Apache on Ubuntu Server
      apt:name=apache2 state=present
      become: yes
      when: ansible_os_family == "Debian"

Ansible-Conditionals-install-apache-server

When you run the playbook, you’ll get the output below

Install-apache-using-ansible-playbook

Let’s break this down:

The first task or play executes the installation of the httpd package, colloquially known as the Apache web-server, on the remote CentOS host using the yum package manager which is the package manager for RHEL distros. Because we have defined all the host systems in our inventory, the installation of the httpd package alongside other dependencies will only take place for servers belonging to the Red Hat family.  This has been defined by the built-in variable ansible_os_family. In effect skips the installation on Ubuntu server, which is evidenced by the line “skipping [173.82.202.239]

Because the Ubuntu server has been omitted in the first play, another play needs to be defined. The second play executes the installation of the Apache2 package using the apt package manager which is the native package manager for the Debian OS family. This implies that the apache2 package will be installed in all systems that fall under the Debian family, for which Ubuntu is a part.

Ultimately, the Apache Web Server will be installed on both  Red Hat and Debian based servers.

Using ‘when’ with the logical AND operator

You can further refine your playbook and narrow it down to the specifics. Suppose you only want Ansible to install apache web server on Ubuntu servers whose version is 18.04, how would you go about it?

In this case, you will define another variable which will restrict the installation of Apache to Ubuntu servers on version 18.04. Here’s how they play would look like.

---
- name: install Apache webserver
  hosts: all
  tasks:
    - name: Install Apache on Ubuntu Server
      apt: name=apache2 state=present
      become: yes
      when: ansible_os_family == "Debian" and ansible_distribution_version == "18.04"

Logical-and-Conditions-Ansible-Playbook

As you have seen, we have used the AND logical operator followed by another built-in Ansible variable known as ansible_distribution_version which has been assigned the value “18.04

For this play to be executed, both conditions have to be TRUE, i.e, the host system has to fall under the  Debian category of OS,  and the version has to be 18.04. As we know, only Ubuntu fits the description i.e Ubuntu 18.04.  If either of the conditions is not met, then the play fails and the installation of Apache will fail.

Using ‘when’ with the logical OR Operator

With OR logical operator, the play is executed when either or all of the conditions are satisfied.

Let’s consider another playbook:

---
- name: Check disk space usage
  hosts: all
  tasks:
    
     - name: Check disk space usage on servers
       shell: df -Th
       register: result
      - debug:
          var: result.stdout_lines
        when: ansible_os_family == "Debian" or ansible_os_family == "RedHat"

Conditionals-Ansible-Playbook-Check-Space

The above playbook displays disk usage metrics on servers in the setup that fall either under Debian or Red Hat distributions or both. Since both servers in our setup fall under the above-mentioned OS families, the playbook will display disk usage for both servers.

Run-Ansible-Playbook-Conditions-Check-Space

Conditional statements are essential in a multi-OS setup where variations exist in package management and server configuration. We hope you can now comfortably use the when conditional statement to perform various tasks according to the distribution of your server.

Also Read : How to Download and Use Ansible Galaxy Roles in Ansible Playbook

Also Read : How to Use Variables in Ansible Playbook

Leave a Reply

Your email address will not be published. Required fields are marked *

Pin It on Pinterest