Lesson 8 of 11 ↓
- 1.Ansible Basic Setup Guide
- 2.Ansible Inventory Guide (hosts)
- 3.Ansible Configuration Guide (ansible.cfg)
- 4.Ansible Ad-hoc Commands Guide
- 5.Ansible Playbook Guide (playbook.yml)
- 6.Ansible Variables & Precedence Guide
- 7.Ansible Loops Guide
- 8.Ansible Conditionals Guide (when)
- 9.Ansible Vault Guide
- 10.Ansible Handlers Guide
- 11.Ansible Custom Roles Guide
5 min read
Ansible Conditionals Guide (when)
A comprehensive guide to understanding and using Conditionals in Ansible. This document covers how to control task execution flow using the when statement, from basic checks to advanced logic.
What are Conditionals?
In automation, you don't always want to run every task on every server.
-
Scenario: You want to install
httpdon CentOS butapache2on Ubuntu. -
Solution: Use the
whenstatement. It checks a condition (True/False). If True, the task runs. If False, the task is Skipped.
Part 1: Basic Examples (the Essentials)
Run Task Only on Redhat-based Systems
This is the most common use case: handling different Operating Systems.
- name: Install httpd only on RedHat
hosts: all
become: true
tasks:
- name: Install httpd
yum:
name: httpd
state: present
when: ansible_os_family == "RedHat"Detailed Explanation:
-
ansible_os_family: A "Fact" gathered automatically by Ansible. It groups OS types (e.g., RHEL, CentOS, Fedora, Amazon Linux are all "RedHat"). -
==: The equality operator. -
Logic: "Only run this
yumtask if the OS family is exactly RedHat".
Run Task if Variable Matches Value
You can control flow using your own custom variables defined in the playbook or passed via CLI.
- name: Install selected package
hosts: all
become: true
vars:
pkg_name: nginx # Defining a variable
tasks:
- name: Install nginx
yum:
name: nginx
state: present
when: pkg_name == "nginx"Detailed Explanation:
-
vars: Defines a variable namedpkg_name. -
when: pkg_name == "nginx": Checks the value. If you changedpkg_nametoapache, this task would be skipped.
Use 'when' with Hostname
Useful when you need to run a specific task on a specific node (e.g., only the Master node).
- name: Show message only on server01
hosts: all
tasks:
- name: Print a message
debug:
msg: "This is server01"
when: ansible_hostname == "server01"Detailed Explanation:
-
ansible_hostname: A built-in fact containing the short hostname of the server. -
debugmodule: Prints messages to the terminal (likeechoin bash). Useful for testing conditions without changing the system.
Run Task if File Exists (advanced Pattern)
This is a powerful pattern: Check something first, register the result, then use it.
- name: Run only if file exists
hosts: all
become: true
tasks:
- name: Check file
stat:
path: /tmp/test.conf
register: file_status # Saves the result of 'stat' into this variable
- name: Remove file
file:
path: /tmp/test.conf
state: absent
when: file_status.stat.exists # True if file was foundDetailed Explanation:
-
statmodule: Checks file details (size, permissions, existence). -
register: file_status: Stores the output of thestattask. -
file_status.stat.exists: This specific path inside the variable returnstrueorfalse. -
Logic: "If the file exists, delete it. If not, do nothing."
Use 'when' with Os Distribution
More specific than os_family. Use this when you care about the exact Distro (Amazon vs CentOS vs Ubuntu).
- name: Install package depending on OS
hosts: all
become: true
tasks:
- name: Install package on Amazon Linux
yum:
name: httpd
state: present
when: ansible_distribution == "Amazon"Part 2: Advanced Logic (multiple Conditions)
The and Operator
To run a task only if multiple conditions are true.
Method A: List format (Recommended for readability)
when:
- ansible_distribution == "CentOS"
- ansible_memtotal_mb >= 1024Logic: Run ONLY if it is CentOS AND has more than 1GB RAM.
Method B: String format
when: ansible_distribution == "CentOS" and ansible_memtotal_mb >= 1024The or Operator
To run a task if at least one condition is true.
when: ansible_os_family == "RedHat" or ansible_os_family == "Debian"Logic: Run on RedHat OR Debian systems.
Part 3: Controlling Task Status (must Know!)
Sometimes a command fails, but you don't want Ansible to stop. Or a command runs successfully, but you don't want to report "Changed".
failed_when (custom Failure)
Define what constitutes a "failure" for a task.
- name: Check for error in log
command: cat /var/log/app.log
register: log_output
failed_when: "'CRITICAL' in log_output.stdout"- Logic: The command
catworks fine (exit code 0), but we want to fail the playbook if the word "CRITICAL" is found in the text.
changed_when (clean Output)
Commands usually report "Changed" every time they run. You can suppress this.
- name: Verify nginx configuration
command: nginx -t
register: nginx_check
changed_when: false # Never report 'Changed', always report 'OK'- Why? Running
nginx -tdoesn't change the server state; it just checks config. Reporting "Changed" is misleading.
Part 4: Conditionals with Loops
You can filter items in a loop directly using when.
- name: Install packages only if they don't exist
yum:
name: "{{ item }}"
state: present
loop:
- httpd
- mariadb
- php
when: ansible_os_family == "RedHat"- Logic: The
whenstatement is evaluated for every item in the loop. In this case, if the OS is not RedHat, the entire loop is skipped.
Advanced Loop Condition:
- name: Create users based on group
user:
name: "{{ item.name }}"
state: present
loop:
- { name: 'alice', type: 'admin' }
- { name: 'bob', type: 'user' }
when: item.type == 'admin'- Result: Creates 'alice', skips 'bob'.
Summary Checklist
| Keyword | Use Case |
|---|---|
when |
The main conditional statement (If...Then). |
== / != |
Equals / Not Equals. |
and / or |
Logical operators for multiple conditions. |
is defined |
Check if a variable exists (when: my_var is defined). |
register |
Capture task output to test it in the next task. |
failed_when |
Override default failure logic. |
changed_when |
Override "Changed" status (useful for read-only commands). |
Comments
Loading the discussion…