Chapter 8: Simplifying Playbooks with Roles and Collections
Exercise: Reusing content with system roles
You will install the system roles collection into a project, read the timesync role's documentation, and use the role to synchronise time on two database servers. Then you will set a different time zone for each data centre with tasks after the role and a handler that reboots the host.
The project ~/role-system has an ansible.cfg, an inventory, and the collection archive. Its inventory puts servera and serverb in database_servers, servera in na_datacenter and serverb in europe_datacenter.
Reusing content with system roles
- Install the system roles collection into a project.
- Find and read a system role’s documentation.
- Configure time synchronisation and time zones with a system role and tasks.
Prerequisites: Complete control-node setup and the preceding lessons in this chapter. Run commands as student on workstation unless a step names another machine.
From the project directory, run the relevant home-lab check. For an exercise with several checkpoints, grade each state before changing or removing it:
lab grade role-systemThe grader reads project files and host state. A passing report covers the listed checks; also perform the task’s independent connection, repeat-run, and reboot checks where requested.
Give one lab host a different time zone through host variables and explain how it overrides the group value.
Record the published result first. The grader checks the original requirements, so a changed name or value may intentionally fail those checks.
Configure time on database_servers with configure_time.yml.
- The project's system-roles collection must be discoverable from
collections/. - Use the timesync role with the time source described for your environment below; at home, use the public pool rather than the classroom's private source.
- Hosts in
na_datacentermust useAmerica/Chicago; hosts ineurope_datacentermust useEurope/Helsinki. - Change zones only when needed and reboot after a zone change. Verify synchronization configuration and each zone after reboot; another run must make no change.
lab start role-system packages the redhat.rhel_system_roles collection that section 1.6 installed on workstation as redhat-rhel_system_roles-1.120.5.tar.gz (your version may differ). This exercise reboots servera and serverb at the end.
Install the collection into the project
[student@workstation ~]$ cd ~/role-system
[student@workstation role-system]$ mkdir -p collectionsAdd collections_path to the [defaults] section of ansible.cfg, with the project's directory first:
[defaults]
inventory = ./inventory
remote_user = devops
interpreter_python = auto_silent
collections_path = ./collections:~/.ansible/collections:/usr/share/ansible/collections
...output omitted...[student@workstation role-system]$ ansible-galaxy collection install \
> -p collections/ redhat-rhel_system_roles-1.120.5.tar.gz
Starting galaxy collection install process
Process install dependency map
Starting collection install process
Installing 'redhat.rhel_system_roles:1.120.5' to '/home/student/role-system/collections/ansible_collections/redhat/rhel_system_roles'
redhat.rhel_system_roles:1.120.5 was installed successfully
[student@workstation role-system]$ ansible-galaxy collection list
# /home/student/role-system/collections/ansible_collections
Collection Version
------------------------ -------
redhat.rhel_system_roles 1.120.5
...output omitted...Start the playbook
Create configure_time.yml with one play for database_servers that applies the timesync role:
---
- name: Time Synchronization
hosts: database_servers
roles:
- redhat.rhel_system_roles.timesyncRead the role's documentation
[student@workstation role-system]$ less \
> collections/ansible_collections/redhat/rhel_system_roles/roles/timesync/README.mdThe Role Variables section describes the two you need:
timesync_ntp_servers:
- hostname: foo.example.com # Hostname or address of the server
minpoll: 4 # Minimum polling interval (default 6)
maxpoll: 8 # Maximum polling interval (default 10)
iburst: true # Flag enabling fast initial synchronization
# (default false)
pool: false # Flag indicating that each resolved address
# of the hostname is a separate NTP server
# (default false)
...output omitted...
# Possible values are "chrony" and "ntp". If not defined, the currently active
# or enabled service will be configured. If no service is active or enabled, a
# package specific to the system and its version will be selected.
timesync_ntp_provider: chronySet the time source for all hosts
These settings apply to every host, so they go in group_vars/all:
[student@workstation role-system]$ mkdir -pv group_vars/all
mkdir: created directory 'group_vars'
mkdir: created directory 'group_vars/all'---
#redhat.rhel_system_roles.timesync variables for all hosts
timesync_ntp_provider: chrony
timesync_ntp_servers:
- hostname: classroom.example.com
iburst: true---
#redhat.rhel_system_roles.timesync variables for all hosts
timesync_ntp_provider: chrony
timesync_ntp_servers:
- hostname: 0.rocky.pool.ntp.org
iburst: trueSet the time zone after the role
Add post_tasks and a handler to the play. The first task reads the current time zone; the second changes it only if it differs from host_timezone, and notifies a handler that reboots the host.
---
- name: Time Synchronization
hosts: database_servers
roles:
- redhat.rhel_system_roles.timesync
post_tasks:
- name: Get time zone
ansible.builtin.command: timedatectl show
register: current_timezone
changed_when: false
- name: Set time zone
ansible.builtin.command: "timedatectl set-timezone {{ host_timezone }}"
when: host_timezone not in current_timezone.stdout
notify: reboot host
handlers:
- name: reboot host
ansible.builtin.reboot:The when condition is what keeps the command task idempotent: on the second run the zone already matches, so the task is skipped.
One time zone per data centre
Find the zone names, then give each data centre group its own value:
[student@workstation role-system]$ timedatectl list-timezones | grep Chicago
America/Chicago
[student@workstation role-system]$ timedatectl list-timezones | grep Helsinki
Europe/Helsinki
[student@workstation role-system]$ mkdir -pv group_vars/{na_datacenter,europe_datacenter}
mkdir: created directory 'group_vars/na_datacenter'
mkdir: created directory 'group_vars/europe_datacenter'
[student@workstation role-system]$ echo "host_timezone: America/Chicago" > \
> group_vars/na_datacenter/timezone.yml
[student@workstation role-system]$ echo "host_timezone: Europe/Helsinki" > \
> group_vars/europe_datacenter/timezone.ymlRun it
[student@workstation role-system]$ ansible-navigator run -m stdout configure_time.yml --syntax-check
playbook: /home/student/role-system/configure_time.yml
[student@workstation role-system]$ ansible-navigator run -m stdout configure_time.yml
...output omitted...
RUNNING HANDLER [redhat.rhel_system_roles.timesync : Restart chronyd] **********
changed: [servera.lab.example.com]
changed: [serverb.lab.example.com]
TASK [Get time zone] ***********************************************************
ok: [servera.lab.example.com]
ok: [serverb.lab.example.com]
TASK [Set time zone] ***********************************************************
changed: [servera.lab.example.com]
changed: [serverb.lab.example.com]
RUNNING HANDLER [reboot host] **************************************************
changed: [serverb.lab.example.com]
changed: [servera.lab.example.com]
PLAY RECAP *********************************************************************
servera.lab.example.com : ok=23 changed=6 unreachable=0 failed=0 skipped=32 ...
serverb.lab.example.com : ok=23 changed=6 unreachable=0 failed=0 skipped=32 ...The role's own handler restarts chronyd after its tasks; your handler reboots the hosts at the end of the play. A second run reports changed=0.
Check the time zones
[student@workstation role-system]$ ssh devops@servera date
Wed Sep 30 06:37:55 PM CDT 2026
[student@workstation role-system]$ ssh devops@serverb date
Thu Oct 1 02:37:56 AM EEST 2026The same moment, shown in two time zones.
Finish
Check your work with lab grade role-system, then put the exercise away with lab finish role-system.