Task

Deploy Across Mixed Fleets seamlessly

Ansible · 12 min · Practical

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.

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.

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.

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.

The full task list

install_apache.yml
---
- 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"

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]
skipping: [centos-srv]

TASK [Install Apache on CentOS] *************************************
skipping: [ubuntu-srv]
changed: [centos-srv]

$

Lessons from running this in production