Managing Red Hat Enterprise Linux (RHEL) at scale requires consistent, repeatable configuration across hundreds or thousands of hosts. Doing this by hand means encoding the details of every subsystem into your own automation, including installing packages, editing configuration files, restarting services, and handling the dependencies between all of these steps. And that knowledge must be maintained as your fleet grows and as RHEL evolves across versions. That's why RHEL system roles take a higher-level approach.
In RHEL, each system role provides a single, declarative interface to an entire subsystem. You describe what you want, not how to get there. The role handles package installation, configuration file generation, service management, and cross-version compatibility behind the scenes.
Introduction to RHEL system roles covers the fundamentals of RHEL system roles: What they are, how to set up a control node, and how to write your first playbook. In this article, I demonstrate how RHEL system roles and Red Hat Ansible Automation Platform are better together, and how the roles provide the automation content while Ansible Automation Platform provides the enterprise framework around it. I also highlight the roles that have been added recently, and walk through a practical example using the bootloader role.
New roles since the previous article
The last RHEL system roles article was published in 2024. Since then, we've been working hard on expanding the collection, and a series of new ready-to-use roles have landed:
aide: Sets up the Advanced Intrusion Detection Environment for file integrity monitoring.sudo: Manages sudoers configuration files and rules.gfs2: Configures GFS2 shared-storage filesystems in high-availability cluster environments.snapshot: Creates and manages LVM snapshots for safe rollback during maintenance operations.bootloader: Configures GRUB2 boot loader settings and kernel command-line parameters, as demonstrated later in this post.
We also have more roles incoming. The auditd role helps manage the Linux Audit daemon, and the trustee roles help with confidential computing attestation. These are in development as I write this article, and are planned to be available in upcoming releases.
For more information, refer to this complete list of all available roles and their supported RHEL versions.
Why the RHEL system roles abstraction matters
Configuring an operating system subsystem is rarely a single operation. Consider the bootloader. It involves understanding GRUB2 internals, kernel command-line parameters, the differences between BIOS and UEFI systems, the behavior of grubby, and how to handle changes that require a reboot. Capturing that domain knowledge in your own automation means writing it once, and then maintaining it as RHEL evolves across major versions.
RHEL system roles take on that burden for you. The bootloaderrole exposes a small set of variables — bootloader_settings, bootloader_reboot_ok, bootloader_timeout — and handles everything else internally. You don't need to know which packages to install, which configuration files to edit, or how the underlying tools differ between, for instance, RHEL 8 and RHEL 9. The role adapts automatically.
This is the value of the abstraction: You describe the outcome you want, and the role delivers it. And because that description is pure declarative data, it can live in version control and be managed as Configuration-as-Code (a point I return to in the Ansible Automation Platform section, below).
What RHEL system roles handle for you
- Roles manage packages: No need to figure out which packages are needed to configure the subsystem.
- Roles manage services: No need to figure out which services are needed to configure the subsystem.
- Roles manage paths: No need to figure out which directories/files need to be created, and their ownerships/permissions.
- Roles hide OS version differences: No need to keep track of differences of argument values, packages, services per OS.
- Roles provide convenient features: Many roles provide a way to erase existing settings, for those cases where it is necessary to start from a known configuration.
- Roles simplify playbooks: Smaller playbooks, fewer playbook changes, less QE for playbook changes, sometimes no playbook changes are required. All configuration lives in inventory variables, so the same playbook is reusable across environments without modification.
- Roles handle reboot orchestration: Several roles detect when changes require a reboot and can handle the reboot sequence automatically, or report the need if not permitted.
- Roles detect and correct configuration drift: Because roles manage the entire subsystem state idempotently, re-running them catches and fixes manual changes across the subsystem.
Benefits of RHEL system roles
- Designed in conjunction with RHEL subsystem maintainers. Handles best practices, corner cases, new RHEL features.
- Hides RHEL major and minor version differences. The same inventory and playbook can be used to manage a mix of multiple different RHEL major and minor versions. Many subsystems have major version differences, and some have minor version differences (for example,
fapolicyd). - Can manage a list of settings. There's no need for looping in the playbook. You can define the list of settings in the inventory, the role takes care of applying those settings idempotently.
- Aids in upgrade. You don't need to change your playbook or inventory when upgrading managed nodes.
- Extensively tested by Red Hat QE, with over 600 integration tests, many unit tests, included with the roles, tested across many different versions of RHEL and Ansible Automation Platform, as well as multiple versions of ansible-lint and ansible-test.
- Roles are composable. Internally, some roles which provide a network service use the
certificaterole for the TLS cert/key, thefirewallrole for managing the firewall ports, and theselinuxrole for managing port policy, so the user doesn't have to manage these separately. Externally, users can chain multiple roles in a single playbook for complete end-to-end scenarios — for example, combining thecertificate,firewall, andcockpitroles to deploy the RHEL web console with trusted certificates in one run. - Consistent API/naming across multiple roles. A variable with the, for example, a
_certsuffix means the same thing in all roles. - Can manage immutable systems (ostree).
- Works with explicit fact gathering — each role knows how to gather facts needed by the role.
- Handles lifecycle management beyond initial setup. Roles support ongoing operations such as encryption key rotation, certificate renewal, snapshot revert, and configuration updates, not just first-time provisioning.
- Included with every RHEL subscription — no additional product purchase required.
- Standalone with no external collection dependencies. Easy to bring into air-gapped or disconnected environments. You can install it as a RHEL RPM or as a collection tarball downloaded from Ansible automation hub, with no live connection to a content source required.
What RHEL customers can do today
Every RHEL subscription includes access to RHEL system roles. No additional products are required. You install the rhel-system-roles package on a control node running RHEL, write a playbook and an inventory file, and run it with ansible-playbook.
Setting up the control node
On a RHEL 9 host that serves as the control node:
$ sudo dnf install rhel-system-roles ansible-coreThis installs all available roles along with ansible-core. The roles are placed in /usr/share/ansible/roles/and their documentation in /usr/share/doc/rhel-system-roles/.
Example: Configuring the boot loader
Suppose I want to accomplish 2 things across my managed nodes:
- Add the
quietkernel command-line parameter to all existing boot entries, so that detailed boot messages are suppressed. - Set the GRUB2 menu timeout to 10 seconds.
I start by creating an inventory file. In my example environment, I have 3 servers running a RHEL 8 host, a RHEL 9 host, and a RHEL 10 host. This is intentional. The same playbook with the same variables will configure all of them because the role handles version-specific differences internally.
My inventory.yml file:
# inventory.yml
all:
hosts:
rhel8-node1.example.com:
rhel9-node1.example.com:
rhel10-node1.example.com:Next, I create the playbook. The bootloader role uses the bootloader_settingsvariable to define kernel command-line modifications. I also set bootloader_reboot_ok: trueso that the role can reboot the managed nodes, should the changes require it. Additionally, I set bootloader_gather_facts:true so that the role populates the bootloader_facts variable with boot information for all kernels on each managed node. After the role runs, I will use a debug task to print those facts.
My configure_bootloader.ymlplaybook:
# configure_bootloader.yml
---
- name: Configure GRUB2 boot loader settings
hosts: all
vars:
bootloader_settings:
- kernel: ALL
options:
- name: quiet
state: present
bootloader_timeout: 10
bootloader_reboot_ok: true
bootloader_gather_facts: true
roles:
- redhat.rhel_system_roles.bootloader
tasks:
- name: Display boot loader facts
ansible.builtin.debug:
var: bootloader_factsRun the playbook:
$ ansible-playbook -i inventory.yml -b \
configure_bootloader.ymlAfter the playbook completes, the debugtask prints the boot configuration that the role collected from each managed node. The output for a single host looks similar to this:
TASK [Display boot loader facts] **********************************************
ok: [rhel10-node1.example.com] => {
"bootloader_facts": [
{
"args": "ro rhgb crashkernel=2G-64G:256M,64G-:512M net.ifnames=0 console=tty0 console=ttyS0,115200n8 quiet",
"default": true,
"id": "7b231b72e2584d78bdb73dae1eac85e0-6.12.0-252.el10.x86_64",
"index": "1",
"initrd": "/boot/initramfs-6.12.0-252.el10.x86_64.img",
"kernel": "/boot/vmlinuz-6.12.0-252.el10.x86_64",
"root": "UUID=e30e5751-d525-4842-a8fb-74ec71c1b839",
"title": "Red Hat Enterprise Linux (6.12.0-252.el10.x86_64) 10.3 (Coughlan)"
},
{
"args": "ro rhgb crashkernel=2G-64G:256M,64G-:512M net.ifnames=0 console=tty0 console=ttyS0,115200n8 quiet",
"default": false,
"id": "7b231b72e2584d78bdb73dae1eac85e0-0-rescue",
"index": "2",
"initrd": "/boot/initramfs-0-rescue-7b231b72e2584d78bdb73dae1eac85e0.img",
"kernel": "/boot/vmlinuz-0-rescue-7b231b72e2584d78bdb73dae1eac85e0",
"root": "UUID=e30e5751-d525-4842-a8fb-74ec71c1b839",
"title": "Red Hat Enterprise Linux (0-rescue-7b231b72e2584d78bdb73dae1eac85e0) 10.3 (Coughlan)"
}
]
}Each entry in the bootloader_facts list represents one kernel boot entry on that host. The args field confirms that the quiet parameter is now present. The default field indicates which kernel boots by default, and the remaining fields provide the kernel path, initrd path, root filesystem, and GRUB menu title. This structured output makes it straightforward to verify the configuration programmatically or to feed it into subsequent automation tasks.
I can also verify the configuration manually on any managed node:
$ ssh rhel8-node1.example.com "grubby --info=ALL | grep args"
args="ro crashkernel=auto net.ifnames=0 rhgb console=tty0 console=ttyS0,115200n8 quiet $tuned_params"
args="ro crashkernel=auto net.ifnames=0 rhgb console=tty0 console=ttyS0,115200n8 quiet $tuned_params"
args="ro crashkernel=auto net.ifnames=0 rhgb console=tty0 console=ttyS0,115200n8 quiet"Notice what I did not have to do. I did not install any packages manually, I did not edit /etc/default/grub or run grub2-mkconfig, I did not write conditional logic for different RHEL versions, and I did not handle the reboot sequence. The role managed all of it.
If you are using Red Hat Ansible Automation Platform, you don't need to install rhel-system-roles on a control node. The redhat.rhel_system_rolescollection is available directly from Ansible automation hub and can be synced into your private automation hub.
The role is invoked as redhat.rhel_system_roles.bootloaderin your playbook, and the inventory is managed through automation controller rather than a local file. The sections below describe how Red Hat Ansible Automation Platform enhances this workflow further.
What Ansible Automation Platform customers can do beyond this
Everything described above works on a standalone RHEL control node with ansible-core. But organizations running Ansible Automation Platform gain capabilities that transform RHEL System Roles from a useful tool into an enterprise automation framework.
Configuration as Code across the enterprise
Because every RHEL system role takes purely declarative input, and all of that input lives in inventory and playbook files, your fleet's desired configuration becomes code — text you can store in Git, review through pull requests, and promote across environments. This is Configuration as Code: The operating system's state is defined, versioned, and tested the same way application source code is, rather than applied by hand host by host. On a handful of machines this is a convenience; across an enterprise-wide inventory it becomes essential, because it is the only practical way to guarantee that thousands of hosts are configured identically — and to prove it.
Ansible Automation Platform is what turns the practice into an enterprise discipline. Automation controller syncs playbooks directly from your Git repositories, runs them against large dynamic inventories, and records every change. The code in Git and the actual state of your fleet stay in lockstep.
Centralized content management
With a standalone RHEL host, you install rhel-system-roles from a local RPM and manage versions manually. With Ansible Automation Platform, the redhat.rhel_system_roles collection is distributed through Ansible automation hub. Your private automation hub acts as a curated content gateway: you control which versions of the collection are approved for use, and every execution environment pulls from the same source. There is no drift between what one team runs and what another team runs.
Role-based access control
On a RHEL control node, anyone with SSH access and sudo privileges can run any playbook against any host. Automation controller introduces role-based access control (RBAC) that lets you define who can run which playbook against which inventory. A junior administrator can apply the timesync role to development servers without being granted access to run the storage role against production databases.
Scheduling and drift detection
A playbook runs from the command line once. In automation controller — the central management interface for running and scheduling automation — you can schedule the same RHEL system roles playbook to run on a recurring basis — daily, weekly, or on a cron schedule. Because RHEL system roles are idempotent, repeated runs detect and correct configuration drift automatically. If someone manually edits /etc/chrony.conf on a host, the next scheduled run of the timesync role restores the desired state.
Credential management
Running ansible-playbook from a RHEL host requires you to manage SSH keys or passwords in files, environment variables, or Ansible vault. Automation controller can draw credentials from whichever source you already trust — external secret stores such as CyberArk or HashiCorp Vault, or its own internal encrypted database. Either way, credentials are injected at runtime without being exposed to playbook authors or written to the filesystem, and every use is audit-logged.
Audit trail and compliance
Every playbook run in automation controller produces a job record with a timestamp, the user who initiated it, the inventory it targeted, the playbook that ran, and the full output. This audit trail satisfies compliance requirements that a shell history on a RHEL control node cannot.
Scaling with execution environments
On a standalone RHEL host, all roles run in the system Python environment. Conflicts between role dependencies or Python library versions can be difficult to resolve. Ansible Automation Platform uses execution environments — containerized Ansible runtime images — that package a known-good set of collections and dependencies, so automation runs the same way everywhere it is executed, independent of the underlying host's system Python or installed packages.
Side-by-side: The same task, two experiences
To illustrate the difference concretely, consider the bootloader example from above.
Aspect | RHEL with ansible-core | Ansible Automation Platform |
Installing the roles | dnf install rhel-system-roles on the control node | Sync |
Managing inventory | Create and maintain a YAML file manually | Define dynamic or static inventories in automation controller with group variables, smart filters, and source syncing |
Setting variables | Edit the playbook or create | Set variables through surveys, inventory group variables in the UI, or credential injection |
Running the playbook | ansible-playbook -i inventory.yml -b playbook.yml | Launch a job template with one click, an API call, or a webhook trigger |
Scheduling | Set up a cron job on the control node | Built-in schedule with notification integrations |
Controlling access | File permissions and sudo rules | RBAC with teams, organizations, and audited permissions |
Viewing results | Terminal output or log files | Centralized job dashboard with searchable output, host-level status, and webhook notifications |
Handling credentials | SSH keys in | Encrypted credential store with rotation, external vault integration, and no filesystem exposure |
Both paths use the exact same role and the exact same variables. The automation logic does not change. What changes is the operational framework around it.
Conclusion
Since the initial release of RHEL system roles, a few principles have become clear from working with customers and the community:
- Abstraction is a feature: Teams that adopt RHEL system roles spend less time debugging playbook failures caused by missing dependencies, incorrect package names, or version-specific configuration differences. The role authors have already handled those edge cases.
- Consistency matters for OS configuration: When the goal is a standard operating environment across a fleet, a well-designed role with a focused interface lets you express that configuration in as few lines as possible. You want every host configured the same way, and roles make that straightforward.
- Roles and Ansible are better together: RHEL system roles provide the automation content. Ansible Automation Platform provides the operational framework — access control, scheduling, credential management, and auditability. Each makes the other more valuable; removing either component diminishes the whole.
- RHEL system roles lower the barrier to automation: Not every team has dedicated Ansible developers. System administrators who are experts in RHEL but new to Ansible Automation Platform can write a working playbook with RHEL system roles in minutes, because the role interface matches the language they already use when thinking about their systems.
Next steps
- Explore the full list of available roles in the RHEL system roles knowledgebase article.
- Review role documentation and examples in the RHEL documentation.
- Try RHEL system roles hands-on in the interactive lab environments.
- If you are evaluating Ansible Automation Platform, see how RHEL system roles integrate with automation controller, Ansible automation hub, and execution environments.
- Read about the scope of support for the Ansible Core package included in RHEL to understand what is covered by your RHEL subscription alone.
Tell us what role you need next! Whether you have in-house automation you would like to see converted into a supported RHEL system role, an Ansible Galaxy role you depend on but need Red Hat backing for, or a manual RHEL administration task you want automated and supported — we want to hear from you. Contact us through your Red Hat account team or open a Red Hat support case to share your ideas.
Product trial
Red Hat Ansible Automation Platform | Product Trial
About the author
Sergei Petrosian is a technical writer at Red Hat working on Satellite and Foreman documentation.
More like this
Red Hat Satellite 6.20 limited availability: Early access registration now open
Automating edge recovery: Minimizing unplanned downtime with Red Hat Edge
Untangling Networks | Compiler
Infrastructure At The Edge | Compiler
Keep exploring
- The automated enterprise
E-book - Try Red Hat Ansible Automation Platform with self-paced, hands-on labsInteractive lab
- Red Hat Ansible Automation Platform: A beginner’s guide
E-book
Browse by channel
Automation
The latest on IT automation for tech, teams, and environments
Artificial intelligence
Updates on the platforms that free customers to run AI workloads anywhere
Open hybrid cloud
Explore how we build a more flexible future with hybrid cloud
Security
The latest on how we reduce risks across environments and technologies
Edge computing
Updates on the platforms that simplify operations at the edge
Infrastructure
The latest on the world’s leading enterprise Linux platform
Applications
Inside our solutions to the toughest application challenges
Virtualization
The future of enterprise virtualization for your workloads on-premise or across clouds