# 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.
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
--- - 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
gather_factsansible_factspayload from the target. - evaluate apt
Checks if the OS is Ubuntu. If true, installs
when == "Ubuntu"apache2via apt. If false, skips entirely. - evaluate yum
Checks if the OS is CentOS. If true, installs
when == "CentOS"httpdvia yum. If false, skips entirely.
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.
Lessons from running this in production
Fact values are strictly case-sensitive! "Ubuntu" and "CentOS" must be capitalized exactly as Ansible reports them, or the condition will fail silently.
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).
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.