# ansible / configuration / conditionals

Deploy Across Mixed Fleets seamlessly

Stop writing separate playbooks for Debian and RedHat. By gathering system facts and applying conditional logic, a single playbook dynamically routes tasks to the correct package manager.

$ ansible-playbook install_apache.yml
Targetubuntu-web-01
Fact Gatheringok
APT Taskchanged
YUM Taskskipped
when
condition
facts
context
2 tasks
playbook
# overview

Why Facts Matter

Hardcoding package managers breaks as soon as your infrastructure diversifies. By instructing Ansible to gather facts, the playbook becomes context-aware, making decisions at runtime based on the actual target environment.

context

Gathering Facts

Ansible automatically queries the target system for hundreds of variables (OS, IP, CPU config) before running tasks, storing them in the ansible_facts dictionary.

logic

The when Clause

Tasks attached to a when statement are evaluated before execution. If the condition evaluates to false, Ansible safely skips the task without throwing an error.

# playbook

The full task list

install_apache.ymlYAML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
---
- name: Install package based on OS
  hosts: all
  become: yes
  gather_facts: yes

  tasks:
    - name: Install Apache on Ubuntu
      apt:
        name: apache2
        state: present
      when: ansible_facts['distribution'] == "Ubuntu"

    - name: Install Apache on CentOS
      yum:
        name: httpd
        state: present
      when: ansible_facts['distribution'] == "CentOS"

Run order

  • discovery

    Ansible executes the implicit setup module to collect the ansible_facts payload from the target.

    gather_facts
  • evaluate apt

    Checks if the OS is Ubuntu. If true, installs apache2 via apt. If false, skips entirely.

    when == "Ubuntu"
  • evaluate yum

    Checks if the OS is CentOS. If true, installs httpd via yum. If false, skips entirely.

    when == "CentOS"
# verify

Check the playbook output

When running against a mixed inventory (e.g., one Ubuntu server and one CentOS server), you will see Ansible explicitly reporting the skipped tasks where the logic did not match.

terminal
TASK [Gathering Facts] **********************************************
ok: [ubuntu-srv]
ok: [centos-srv]
 
TASK [Install Apache on Ubuntu] *************************************
changed: [ubuntu-srv]
 
TASK [Install Apache on CentOS] *************************************
changed: [centos-srv]
 
$
# notes

Lessons from running this in production

WARN

Fact values are strictly case-sensitive! "Ubuntu" and "CentOS" must be capitalized exactly as Ansible reports them, or the condition will fail silently.

INFO

While the generic package module exists to abstract apt/yum, using explicit conditionals is mandatory here because the actual software name differs (apache2 vs httpd).

OK

gather_facts: yes is the default behavior in Ansible, but explicitly writing it in your playbook is an excellent practice when your logic strictly relies on it.