- detect target operating systems and versions using facts,
- apply environment-specific configuration using variables,
- reuse common tasks while running environment-specific steps only where appropriate.

Facts: What they are and how to use them
Ansible facts are automatically gathered system variables (unless you disable gathering). Facts provide details like distribution, distribution version, os_family, architecture, and more — and are commonly used insidewhen conditionals to drive OS-specific behaviour.
Helpful links:
- Ansible user guide — conditionals: https://docs.ansible.com/ansible/latest/user_guide/playbooks_conditionals.html
- Facts & the setup module: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/setup_module.html
By default Ansible gathers facts at the start of a play using the setup module. If you set gather_facts: false, you must call the setup module explicitly (or enable gathering) before relying on
ansible_facts.| Fact name | Typical use case | Example value |
|---|---|---|
ansible_facts['os_family'] | Broad family checks (Debian, RedHat, Windows) | Debian |
ansible_facts['distribution'] | Distribution-specific checks | Ubuntu, CentOS |
ansible_facts['distribution_major_version'] | Version-specific checks | 18, 7 |
ansible_facts['architecture'] | Architecture-specific package choices | x86_64 |
- ansible <host-pattern> -m setup Or by adding a debug task to a play:
Scenario 1 — Install Nginx only on Ubuntu 18.04
Use facts in awhen conditional to target a specific distribution and major version.
Example task (apt-based install only for Ubuntu 18.04):
- For targeting all Debian-family distributions you could use
ansible_facts['os_family'] == 'Debian'. - Always validate the exact fact keys by inspecting gathered facts on your hosts.
Scenario 2 — Use a variable to apply environment-specific configuration
Define an environment variable (for exampleapp_env) to drive templating so each environment receives its specific configuration.
Example templating task that chooses the source template based on app_env:
app_env:
- inventory (host_vars or group_vars)
- dedicated variable files
- at the play level:
- template module: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/template_module.html
Scenario 3 — Reuse common tasks, but start services only in production
Many tasks are common across all hosts (package installation, directories, permissions). Use awhen conditional to run environment-only actions (for example starting services) on production hosts.
A compact example play that brings the scenarios together:
- Replace the
apttask withyumorwin_chocolateyon non-Debian systems when needed. - Use
notify+handlersto centralize service restarts after configuration changes.
Best practices and tips
- Keep environment and role variables out of inline tasks. Prefer inventory (
host_vars/group_vars) or dedicated variable files to make playbooks reusable and easy to manage. - Use consistent variable names across repositories (e.g.,
app_envorenvironment) to avoid confusion. - Inspect facts frequently with the setup module or debug to determine which fact names and values are available on your target hosts.
- Use multiple
whenconditions as lists for readability: when:- condition1
- condition2
- Prefer checking
os_familyfor portability across similar distributions, and usedistribution+distribution_major_versionfor precise control.
Summary
Ansible conditionals — combining gathered facts and variables — let you write readable, maintainable automation for mixed OS environments. Use facts to detect OS and versions, variables to parameterize environment-specific behavior, andwhen conditionals to reuse common tasks while restricting environment-specific changes to the appropriate hosts.
Further reading:
- Ansible documentation: https://docs.ansible.com/ansible/latest/index.html
- Playbooks and conditionals: https://docs.ansible.com/ansible/latest/user_guide/playbooks_conditionals.html