Ansible is a configuration management tool used for automating remote system management tasks like software deployment and installing updates, configuration management, orchestration, and many other IT tasks.
Here at LinuxAPT , we shall look into the "When" statement and how to use the "When" statement in different situations.
Here, we will use various "When" conditional statements in a setup with servers running different operating systems.
Let's say:
In the Setup, we have an Ansible controller host with Ubuntu 20.04 system. There are two target nodes: one with the Ubuntu 20.04 system and another one with Debian Buster.
Suppose you are working on a certain Ansible project, and at a certain point, you want to skip a specific step for a specific host.
To understand it better, let's take an example, suppose you want to skip installing some sort of package on a host if the required version of the software is not available. This is where the "When" clause comes in handy.
A basic conditional statement works with a single task. What you have to do is to create a task and then add a condition using the "when" statement. This "when" statement applies to a test or simply a condition for this task.
An example is given below:
tasks:
- name: Running shutdown command on CentOS-based systems
ansible.builtin.command: /sbin/shutdown -t now
when: ansible_facts['os_family'] == "CentOS"
When a task or playbook is executed, the tests are checked against all the hosts. If the test is passed for any host, Ansible will execute the task; otherwise, it will skip the execution. In the above example, the shutdown command will be executed for any system that matches the criteria of being a CentOS-based OS.
A task can also be skipped based on facts. Facts are property of a host, such as IP of the host, type of operating system, etc.
The following are some fact-based use cases:
Multiple conditions for a "when" clause can also be merged. This uses logical operators like or not.
An example is given below:
tasks:
- name: Shut off Debian 10 and Debian 11 systems
ansible.builtin.command: /sbin/shutdown -t now
when: (ansible_facts['distribution'] == "Debian" and ansible_facts['distribution_major_version'] == "10") or
(ansible_facts['distribution'] == "Debian" and ansible_facts['distribution_major_version'] == "11")
As previously explained, Ansible performs conditional evaluations on the targets(hosts) prior to running a task. In the task above, If the condition, i.e., the system is Debian 10 or Debian 11, is found to be true, Ansible will execute the requested shutdown task. If the condition is unmet, Ansible will simply skip this task.
If multiple tasks are required to be true simultaneously(a logical "and" condition), we can list them as:
tasks:
- name: Shut off Ubuntu 17.04 systems
ansible.builtin.command: /sbin/shutdown -t now
when:
- ansible_facts['distribution'] == "Ubuntu"
- ansible_facts['distribution_major_version'] == "17.04"
In Ansible, registered variables can also be used with conditionals. These variables are obtained from the output of a task in a play and can be used as a base for further tasks.
An Example is given below:
- hosts: web_servers
tasks:
- name: Running a shell command and registering its outcome as a variable using the 'register' keyword.
ansible.builtin.shell: /usr/bin/pwd
register: var_object
- name: Running a shell command based on the result of the last task
ansible.builtin.shell: /usr/bin/ls
when: var_object.stdout = =”ubuntu”
Here, Ansible will check if a specific user exists on the remote host. If the user’s (myuser) directory is found, it will create a file(myfile.txt) inside this directory.
First, create a playbook (my-playbook.yml) with the below content:
---
- hosts: all
gather_facts: no
become: true
tasks:
- name: Check if the user is present or not.
stat:
path: /home/vagrant
register: myuser
- name: If the directory is present, then create a file(myfile.txt)
file:
path: /home/vagrant/myfile.txt
state: touch
when: myuser.stat.exists
Here, Ansible will gather facts about the OS family and shut off all the Ubuntu-based remote systems using the when statement:
---
- hosts: all
gather_facts: yes
become: true
tasks:
- name: shutdown Debian-based servers
ansible.builtin.command: /sbin/shutdown -t now
when: ansible_facts['os_family']=="Debian"
This article covers how to use the "when" clause in Ansible. In fact, In Ansible, you can define conditions that will be evaluated before a task is executed. When a condition is not met, the task is then skipped. This is done with the when keyword, which accepts expressions that are typically based on a variable or a fact.