Learning objectives
By the end of this module, you should be able to:
- Use variables instead of duplicating literal values.
- Inspect gathered facts.
- Write simple conditionals based on host data.
Variables make automation reusable
If a port number, package name or environment value might differ between groups or environments, store it as data rather than copying the whole task. This keeps automation logic stable while allowing controlled variation.
Facts describe the managed host
By default, many plays gather facts before running tasks. Facts include information such as operating system family, interfaces and memory. You can inspect them with the setup module and use them in templates or conditions.
Conditionals make intent platform-aware
The when keyword controls whether a task runs. Use conditions to express legitimate differences, such as installing a distro-specific package, but avoid creating a maze of conditions when separate roles or group-specific data would be clearer.
Worked examples
See the idea in practice.
Variables in a play
- name: Configure application
hosts: web
vars:
app_port: 8080
app_owner: appsvc
tasks:
- name: Show selected port
ansible.builtin.debug:
msg: 'Application port is {{ app_port }}'
- Data is named once and reused.
- Template expressions read variable values at execution time.
Inspect a fact
ansible web -i inventory.ini -m ansible.builtin.setup -a 'filter=ansible_distribution*'
- setup gathers host facts.
- Filtering reduces output while learning or troubleshooting.
Condition on OS family
- name: Install SELinux utilities on RedHat-family systems
ansible.builtin.package:
name: policycoreutils
state: present
when: ansible_facts['os_family'] == 'RedHat'
- The task runs only when the condition is true.
- The condition is based on discovered host data.
Hands-on lab
Lab — Drive behaviour from host data
Goal: Gather facts, create a variable and conditionally display platform-specific information.
STEP 1Inspect facts
ansible all -i inventory.ini -m ansible.builtin.setup -a 'filter=ansible_*distribution*'
STEP 2Create facts.yml
- name: Facts practice
hosts: all
vars:
environment_name: training
tasks:
- name: Report platform
ansible.builtin.debug:
msg: '{{ inventory_hostname }} runs {{ ansible_facts["distribution"] }} in {{ environment_name }}'
- name: RedHat-family note
ansible.builtin.debug:
msg: 'This host uses a RedHat-family package ecosystem'
when: ansible_facts['os_family'] == 'RedHat'
STEP 3Run
ansible-playbook -i inventory.ini facts.yml
Verify
- Every host prints its distribution.
- Only matching hosts print the conditional RedHat-family note.
- The environment value is not duplicated across tasks.
Expected outcome
- Different hosts may take different branches while using the same playbook.
If it fails
- Use ansible.builtin.debug to inspect a variable before building a complicated condition.
- If a fact is unavailable, confirm fact gathering has not been disabled and inspect setup output.
Real-world connectionReusable automation keeps logic stable while inventory and variables supply environment-specific data.
Avoid these traps
Common mistakes
- Hard-coding environment values into many tasks.
- Building conditions around facts you have never inspected.
- Placing secrets in ordinary variables files without an appropriate secret-management mechanism.
Knowledge check
Can you explain it without looking back?
Open each answer only after you have tried to answer the question yourself.
1Why separate variables from task logic?
It allows the same automation logic to work with controlled values for different hosts or environments.
2What module gathers and displays host facts?
ansible.builtin.setup.
3What keyword controls conditional task execution?
when.