Red Hat Certified Engineer (RHCE) #13: System roles (rhel-system-roles)

8 min read

In #12 Collection: Galaxy, Automation Hub we learned how to bundle roles and modules into a collection to distribute and pull them in. This post covers rhel-system-roles — a set of roles Red Hat builds and validates itself. Instead of writing your own roles, you pull in already-validated roles and just fill in variables to automate the time synchronization, firewall, and SELinux configuration you used to do by hand in RHCSA.

rhel-system-roles is a shortcut to locking in points quickly on the exam. When a question asks you to configure NTP, a firewall, or SELinux, you don’t write tasks one line at a time — you call the relevant role and fill in a few variables, and you’re done. This post walks through everything from installation to using the docs to the variables of the most common roles.

What is rhel-system-roles #

rhel-system-roles is a set of Ansible roles Red Hat provides and validates. It abstracts common management tasks on a RHEL system behind a standardized interface — without knowing the internal implementation, you fill in a few variables and apply configuration like time synchronization, firewall, or SELinux consistently.

The core value is abstraction. The sequence of manual steps from RHCSA — installing chronyd, editing /etc/chrony.conf, and enabling the service — is reduced by the timesync role to a single timesync_ntp_servers variable. Even when the RHEL version changes and the underlying tooling differs, the role’s variable interface stays the same, so the same playbook works across multiple versions.

Because Red Hat tests and supports these roles directly, they offer better idempotency and stability than a role you write yourself. You can trust and use them on the exam, too.

How they differ from roles you write yourself #

In #11 we wrote a role from scratch. With a role you write, you have to design every task and variable yourself, whereas rhel-system-roles are finished products where you only need to know the interface. When a question on the exam says “apply this configuration,” you’re free to either write the tasks yourself or use a system role — but the system role is faster and leaves less room for mistakes.

Installation #

rhel-system-roles is installed via two paths. Use whichever fits your environment.

1) Install as an RPM package #

This installs it as a package from RHEL’s default repository. It’s the most common case in the exam environment.

Install via RPM
sudo dnf install -y rhel-system-roles

Once installed, the roles themselves live under /usr/share/ansible/roles/, and the docs and examples under /usr/share/doc/rhel-system-roles/. The roles at this path can be referenced either by an FQCN like redhat.rhel_system_roles.timesync or by a short name like rhel-system-roles.timesync.

2) Install as a collection #

This pulls it in as a collection from Ansible Galaxy or Automation Hub. Use it to get the latest version in an environment with internet access.

Install as a collection
ansible-galaxy collection install redhat.rhel_system_roles

When installed as a collection, you call the role by the redhat.rhel_system_roles.<role> FQCN. For example, timesync becomes redhat.rhel_system_roles.timesync.

The exam environment blocks internet access, so RPM installation is the default. Check first whether the package is already installed with rpm -q rhel-system-roles.

Using the docs and examples #

The key to using rhel-system-roles well is the habit of reading the docs directly. You can’t memorize every role’s variable names for an exam with no internet, so the right answer is to quickly find the local docs and copy an example to use.

Where the docs live #

The installed docs are at the following path.

Check the docs location
ls /usr/share/doc/rhel-system-roles/

Each role has a subdirectory, and inside it are a README.md and an example playbook.

Inspect the timesync docs
ls /usr/share/doc/rhel-system-roles/timesync/
# README.md  example-timesync-playbook.yml  ...

The README.md lays out the list of variables the role takes, their descriptions, and their defaults. The example playbook contains a ready-to-run call example.

The example-copy pattern #

The fastest path on the exam is to copy the example playbook into your working directory and just edit the variables. The risk of memorizing variable names or making typos disappears.

Copy the example playbook
cp /usr/share/doc/rhel-system-roles/timesync/example-timesync-playbook.yml \
   ~/myplaybook.yml

After copying, refer to the README.md and just adjust the hosts and variable values to fit your environment. This pattern applies identically to every system role, not just timesync.

Common roles and variables #

rhel-system-roles includes dozens of roles, but the ones used often on the exam and in practice are fixed. Here are the main roles and their core variables.

RolePurposeCore variables
timesyncNTP time synchronizationtimesync_ntp_servers
firewallfirewalld rulesfirewall (list of services, ports, zones)
selinuxSELinux mode, booleans, ports, fcontextselinux_state, selinux_booleans
storageLVM and filesystem configurationstorage_pools, storage_volumes
networknetwork interfaces and connectionsnetwork_connections
postfixmail transfer agent configurationpostfix_conf

Always confirm the exact variable list for each role in its README.md. Below we work through the three exam regulars as examples.

timesync role #

The timesync role takes a list of NTP servers, then installs and configures chronyd and synchronizes. It replaces RHCSA’s time-synchronization task with a single block.

timesync playbook
---
- name: Configure NTP time synchronization
  hosts: all
  become: true
  vars:
    timesync_ntp_servers:
      - hostname: 0.pool.ntp.org
        iburst: true
      - hostname: 1.pool.ntp.org
        iburst: true
  roles:
    - redhat.rhel_system_roles.timesync

timesync_ntp_servers takes a hostname and iburst for each entry. iburst: true is the option that speeds up the initial synchronization, and it’s the same value you wrote by hand in /etc/chrony.conf in RHCSA.

firewall role #

The firewall role manages firewalld’s services, ports, and zones declaratively. You give a list of rules to the firewall variable.

firewall playbook
---
- name: Configure firewall rules
  hosts: webservers
  become: true
  vars:
    firewall:
      - service: http
        state: enabled
        permanent: true
      - service: https
        state: enabled
        permanent: true
      - port: 8080/tcp
        state: enabled
        permanent: true
  roles:
    - redhat.rhel_system_roles.firewall

Each rule specifies a service or a port, uses state for enabled/disabled, and uses permanent: true to keep it after a reboot. It’s a direct abstraction of the work you did in RHCSA with firewall-cmd --add-service and --permanent.

selinux role #

The selinux role manages SELinux mode, booleans, port labels, and file contexts. It’s often used to turn a boolean on permanently or to attach a label to a port.

selinux playbook
---
- name: Configure SELinux
  hosts: webservers
  become: true
  vars:
    selinux_state: enforcing
    selinux_booleans:
      - name: httpd_can_network_connect
        state: on
        persistent: true
    selinux_ports:
      - ports: "8080"
        proto: tcp
        setype: http_port_t
        state: present
  roles:
    - redhat.rhel_system_roles.selinux

selinux_state sets enforcing/permissive, selinux_booleans sets a boolean permanently (persistent: true), and selinux_ports attaches a type to a port. These correspond to RHCSA’s setsebool -P and semanage port -a.

When you use the selinux role and a boolean or fcontext change requires a reboot, the role tells you. It’s safer to give the README’s caveats a quick read.

Multiple roles in one playbook #

System roles are independent of each other, so you can call several of them together in one playbook. To configure a single web server, you’d bundle them like this.

Multiple roles in one playbook
---
- name: Standard web server configuration
  hosts: webservers
  become: true
  vars:
    timesync_ntp_servers:
      - hostname: 0.pool.ntp.org
        iburst: true
    firewall:
      - service: http
        state: enabled
        permanent: true
    selinux_booleans:
      - name: httpd_can_network_connect
        state: on
        persistent: true
  roles:
    - redhat.rhel_system_roles.timesync
    - redhat.rhel_system_roles.firewall
    - redhat.rhel_system_roles.selinux

Each role reads only its own variables, so gathering the variables in one place doesn’t cause a conflict. That said, once you have a lot of variables, splitting them out into group_vars reads better.

Checking idempotency #

Red Hat guarantees the idempotency of system roles, but check for yourself that the playbook you wrote behaves as intended. The habit of running it twice and checking whether the second run reports changed as 0 is a principle that has run through this series since #5.

Verify idempotence — run twice
ansible-navigator run -m stdout site.yml
ansible-navigator run -m stdout site.yml

If the second run shows changed=0, idempotency held. The variable values are already applied, so the role makes no changes.

Exam points #

  • Drill the flow of copying an example and just editing the variables. Copy the example playbook from /usr/share/doc/rhel-system-roles/<role>/ into your working directory, confirm the variables from the README.md in the same directory, and just change the values — that’s the fastest and safest path.
  • Write the role’s call name exactly. If you installed via a collection, use the redhat.rhel_system_roles.timesync FQCN; for the short name in an RPM environment, use rhel-system-roles.timesync. Confirm first which form is installed in your environment.
  • NTP, firewall, and SELinux are exam regulars. Practice the flow ahead of time — time synchronization with timesync, firewall rules with firewall, SELinux booleans and ports with the selinux role.
  • Don’t drop the permanent-apply option. You have to spell out settings that persist after a reboot, like firewall’s permanent: true and a selinux boolean’s persistent: true, or you’ll lose points in grading.
  • Verify idempotency with two runs. Build the habit of checking whether changed is 0 on the second run.

Wrap-up #

What this post locked in:

  • rhel-system-roles is a set of roles Red Hat has validated, abstracting RHCSA tasks behind a variable interface.
  • Installation has two paths — dnf install rhel-system-roles (RPM) or ansible-galaxy collection install redhat.rhel_system_roles (collection) — and RPM is the default in the exam environment.
  • The docs live at /usr/share/doc/rhel-system-roles/, and the copy-the-example-playbook-and-just-edit-the-variables pattern is the fastest.
  • The commonly used roles are timesync, firewall, selinux, storage, network, and postfix, and you confirm each role’s variables from its README.md.
  • NTP, firewall, and SELinux configuration are exam regulars, so practice the core variables of these three roles until they are second nature.

Next — RHCSA automation 1 #

That wraps up the Ansible syntax and structuring (role, collection, system roles) area. Now we move into RHCSA task automation, which makes up half the exam’s weight.

In #14 RHCSA automation 1: users/groups, packages/repositories, we’ll work through creating accounts with the user and group modules and managing packages and repositories with the dnf and yum_repository modules, writing playbooks in exactly the form that shows up often on the exam.

X