The Ansible When Conditional is an important feature when you want to execute tasks only if certain conditions are met. You can use Ansible’s when conditional to control the execution of tasks based on specific conditions or facts about the target system.
It allows you to run tasks only when certain criteria are met, such as checking the operating system, verifying the status of a service, or using the output of previous tasks.
In this guide, we’ll explore how to use the when conditional in Ansible to control task execution based on specific conditions.
Table of Contents
Basic Syntax
The basic syntax of the when conditional in Ansible is simple. You use the when keyword followed by a condition that evaluates to true or false. Here’s a simple example:
- name: Install Apache on Debian
apt:
name: apache2
state: present
when: ansible_os_family == 'Debian'
In this example, the Apache package will only be installed if the target system belongs to the Debian family.
Use Ansible When Condition with Roles
Assume you want to configure Nginx on servers that are in the production environment and have a specific role. We’ll use inventory variables and check multiple conditions.
In this example playbook, Nginx is installed, configured, and restarted only on servers in the production environment with the role web.
- hosts: web_servers
vars:
env: production
role: web
tasks:
- name: Ensure Nginx is installed
apt:
name: nginx
state: present
when: env == 'production' and role == 'web'
- name: Configure Nginx
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
when: env == 'production' and role == 'web'
- name: Restart Nginx
service:
name: nginx
state: restarted
when: env == 'production' and role == 'web'
Use Ansible When Conditional with AND Operator
Sometimes, you need to check multiple conditions. You can use the and operator to combine them.
In this playbook, the web server will only restart if both service_running and config_changed are true.
- name: Restart web server if the service is running and the configuration has changed
service:
name: apache2
state: restarted
when: service_running and config_changed
Use Ansible When Conditional with NOT Operator
In a situation where you need to perform maintenance tasks only if a service is not running, you can use the NOT operator.
This playbook runs maintenance tasks only if PostgreSQL is not currently active.
- hosts: db_servers
tasks:
- name: Check if PostgreSQL is running
shell: systemctl is-active postgresql
register: postgresql_status
failed_when: false
- name: Perform maintenance if PostgreSQL is not running
shell: ./maintenance_tasks.sh
when: postgresql_status.stdout != 'active'
Use Ansible When Conditional with NOT Equal Operator
Let’s consider a scenario where you want to start a service only if the current timezone is not set to UTC. This can be useful in cases where certain services or configurations are specific to non-UTC timezones.
In this playbook, the when condition checks if the current timezone is not equal to ‘UTC’. If the condition is true (i.e., the timezone is not UTC), the task will execute.
- name: Start the ntpd service if timezone is not UTC
ansible.builtin.systemd:
name: ntpd
state: started
when: ansible_date_time.tz != 'UTC'
Use Ansible Ansible When Conditional with Register
Using the register keyword, you can capture the output of a task and use it as a condition for subsequent tasks. This is particularly useful for making decisions based on dynamic data during playbook execution.
In this playbook, disk cleanup will only be performed if the disk usage exceeds 80%.
- hosts: all
tasks:
- name: Check disk space
shell: df -h / | tail -1 | awk '{print $5}' | sed 's/%//'
register: disk_usage
- name: Print disk usage
debug:
msg: "Disk usage is {{ disk_usage.stdout }}%"
- name: Clean up disk if usage is above 80%
shell: ./cleanup_disk.sh
when: disk_usage.stdout | int > 80
Use Ansible When Conditional with Facts
Ansible gathers facts about the system it manages and stores them in variables. You can use these facts to make decisions in your playbooks. Let’s consider an example where you want to install packages only if the target system has a certain amount of memory.
In this playbook, high-memory-package will be installed on systems with more than 4GB of RAM, while low-memory-package will be installed on systems with 4GB or less.
- hosts: all
tasks:
- name: Gather facts
setup:
- name: Ensure high-memory package is installed
apt:
name: high-memory-package
state: present
when: ansible_memtotal_mb > 4096
- name: Ensure low-memory package is installed
apt:
name: low-memory-package
state: present
when: ansible_memtotal_mb <= 4096
Use Ansible When Conditional with Boolean Variable
Let’s say you have a boolean variable enable_firewall that determines whether the firewall should be enabled on a server. You can use the when conditional to apply this setting.
In this example, the firewalld service will be started and enabled only if the enable_firewall variable is true.
- name: Enable and start the firewall if enable_firewall is true
ansible.builtin.systemd:
name: firewalld
state: started
enabled: true
when: enable_firewall
Use Ansible When Conditional to Install Packages Based on the Operating System
To install packages based on the operating system using Ansible’s when conditional, you can check the OS family or distribution and then apply the appropriate package management tasks. This approach allows you to tailor package installations to different types of systems, such as RedHat-based or Debian-based distributions.
Here’s a playbook that installs httpd on RedHat-based systems and apache2 on Debian-based systems:
- name: Install web server based on OS
hosts: all
become: yes
tasks:
- name: Install httpd on RedHat-based systems
ansible.builtin.yum:
name: httpd
state: present
when: ansible_os_family == 'RedHat'
- name: Install apache2 on Debian-based systems
ansible.builtin.apt:
name: apache2
state: present
when: ansible_os_family == 'Debian'
Use Ansible When with Multiple Conditios
You can combine multiple conditions using and and or. The following playbook installs the httpd package (which is the Apache web server) on all hosts that meet specific conditions. It runs on all target machines with elevated privileges.
The httpd package is only installed if the system is running a Red Hat-based distribution like Rocky Linux or CentOS with a major version of 8 or higher.
- name: Install httpd package based on multiple conditions
hosts: all
become: yes
tasks:
- name: Install httpd on eligible systems
ansible.builtin.yum:
name: httpd
state: present
when:
- ansible_os_family == 'RedHat'
- ansible_distribution in ['Rocky', 'CentOS']
- (ansible_distribution_major_version | int >= 8) or (ansible_distribution == 'Rocky' and ansible_distribution_major_version | int >= 8)
Conclusion
In this article, we explored the various ways to use the Ansible When Conditional to control task execution based on different conditions. Use these techniques in your projects to conditionally execute tasks, making your automation scripts smarter and more reliable.
Happy automating!
FAQs
1. Can I use multiple conditions in the 'when' statement?
Yes, you can use logical operators like and, or, and not to combine multiple conditions in a single when statement.
2. What happens if the 'when' condition is false?
If the when condition is false, the task is skipped, and Ansible proceeds to the next task in the playbook without failing.
3. How do I debug the 'when' conditional if a task doesn't execute as expected?
You can use the debug module or run the playbook in verbose mode (-vvv) to inspect the value of variables and conditions to troubleshoot issues.