sudo subscription-manager refresh
sudo subscription-manager repos --list | grep ansible
RHEL 7.4 introduced RHEL System Roles, a collection of Ansible roles and modules that provide a stable and consistent configuration interface for remote management of Red Hat Enterprise Linux. These System Roles are applicable to RHEL 6.10 and above, easing management of 3 generations of RHEL. The effort is based on development of the Linux System Roles project (link: https://linux-system-roles.github.io/upstream). The following roles are provided and supported as follows:
There are a number of roles available in RHEL 8, including:
selinux
kdump (kernel crash dump)
network
timesync
storage
postfix
The full list can be found here: Red Hat Enterprise Linux (RHEL) System Roles
For further information on Ansible, see the Ansible Quick-Start Guide for Sysadmins (https://www.redhat.com/en/blog/system-administrators-guide-getting-started-ansible-fast) or Quick Start Video (https://www.ansible.com/resources/videos/quick-start-video) for help learning how to use Ansible.
We need to install two packages RPM packages to use system roles: ansible
and rhel-system-roles
. Use subscription-manager to list the Ansible Engine repositories available. Note that the generic "2" repository will always provide the latest release of the 2.X stream as opposed to configuring a more specific version such as 2.8.
sudo subscription-manager refresh
sudo subscription-manager repos --list | grep ansible
Now persistently enable the Ansible Engine repository for RHEL 8 using Red Hat Subscription Manager:
sudo subscription-manager repos --enable ansible-2-for-rhel-8-x86_64-rpms
And install the required packages:
sudo yum install rhel-system-roles ansible
The rhel-system-roles
package will install by default to the following locations where SUBSYSTEM
is the name of the subsystem that contains the individual role manages. Examples may include network, timesync, or other subsystems as they become supported. Each subsystem role will include a README file which documents how to use the role and supported parameter values, as well as the matching README in the linux-system-roles Ansible Galaxy landing space (link: https://galaxy.ansible.com/linux-system-roles/network)
/usr/share/doc/rhel-system-roles/SUBSYSTEM/
/usr/share/ansible/roles/rhel-system-roles.SUBSYSTEM/
This example assumes the following:
Generally, Ansible is not installed on every system, but rather on a single system designated as the Ansible management or control node who’s purpose is to manage other systems via Ansible.
Since we’re running Ansible on the same instance we’re changing, the target of the Ansible playbook is localhost
.
We’ve added a 2nd network interface to our test system, eth1
.
Take a look at the networking playbook that we have provided:
cat example-network-playbook.yml
--- - hosts: localhost become: yes vars: network_connections: - name: DBnic state: up type: ethernet interface_name: eth1 autoconnect: yes ip: dhcp4: no auto6: no address: - "10.10.10.{{ 254 | random( start=2) }}/24" roles: - role: rhel-system-roles.network
As you can probably tell, this playbook creates a network interface called DBnic
, with an IPv4 address of 10.10.10.<something>
, and brings it up. This is just a simple example of what can be done with the system network role.
Now let’s test access to our localhost
using the Ansible ad-hoc command:
ansible localhost -m ping
localhost | SUCCESS => { "changed": false, "ping": "pong" }
Query the Ansible Facts for this system to see the network configuration:
ansible localhost -m setup -a 'gather_subset=network filter=ansible_interfaces'
localhost | SUCCESS => { "ansible_facts": { "ansible_interfaces": [ "lo", "eth1", "eth0" ] }, "changed": false }
Examine the current configuration of eth1
using the ip
and nmcli
commands:
ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc fq_codel state UP group default qlen 1000 link/ether 06:62:b5:81:e3:65 brd ff:ff:ff:ff:ff:ff inet 10.10.0.63/24 brd 10.10.0.255 scope global dynamic noprefixroute eth0 valid_lft 2055sec preferred_lft 2055sec inet6 fe80::462:b5ff:fe81:e365/64 scope link valid_lft forever preferred_lft forever 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc fq_codel state UP group default qlen 1000 link/ether 06:7d:2c:e9:2f:01 brd ff:ff:ff:ff:ff:ff inet 10.10.0.135/24 brd 10.10.0.255 scope global dynamic noprefixroute eth1 valid_lft 3588sec preferred_lft 3588sec inet6 fe80::6cb5:e657:5c52:e6d1/64 scope link noprefixroute valid_lft forever preferred_lft forever
nmcli con
NAME UUID TYPE DEVICE System eth0 5fb06bd0-0bb0-7ffb-45f1-d6edd65f3e03 ethernet eth0 Wired connection 1 9738a5c6-39dd-3515-aa1c-895f763851a6 ethernet eth1 ens3 50e9a523-3280-4238-a07b-dbfd7d335273 ethernet --
Now let’s run our playbook to create a new connection profile called DBnic, turn off DHCP, and assign a static ip address:
ansible-playbook example-network-playbook.yml
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' PLAY [localhost] ****************************************************************************************************** TASK [Gathering Facts] ************************************************************************************************ ok: [localhost] TASK [rhel-system-roles.network : Check which services are running] *************************************************** ok: [localhost] TASK [rhel-system-roles.network : Check which packages are installed] ************************************************* ok: [localhost] TASK [rhel-system-roles.network : Print network provider] ************************************************************* ok: [localhost] => { "msg": "Using network provider: nm" } TASK [rhel-system-roles.network : Install packages] ******************************************************************* skipping: [localhost] TASK [rhel-system-roles.network : Enable and start NetworkManager] **************************************************** ok: [localhost] TASK [rhel-system-roles.network : Enable network service] ************************************************************* skipping: [localhost] TASK [rhel-system-roles.network : Ensure initscripts network file dependency is present] ****************************** skipping: [localhost] TASK [rhel-system-roles.network : Configure networking connection profiles] ******************************************* [WARNING]: [003] <info> #0, state:up persistent_state:present, 'DBnic': connection DBnic, 3b54603b-c603-46b9-9bd9-e6fc295e7a11 already up to date [WARNING]: [004] <info> #0, state:up persistent_state:present, 'DBnic': up connection DBnic, 3b54603b-c603-46b9-9bd9-e6fc295e7a11 (not-active) changed: [localhost] TASK [rhel-system-roles.network : Re-test connectivity] *************************************************************** ok: [localhost] PLAY RECAP ************************************************************************************************************ localhost : ok=7 changed=1 unreachable=0 failed=0 skipped=3 rescued=0 ignored=0
Now let’s see how the Ansible playbook changed our network configuration:
ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc fq_codel state UP group default qlen 1000 link/ether 06:62:b5:81:e3:65 brd ff:ff:ff:ff:ff:ff inet 10.10.0.63/24 brd 10.10.0.255 scope global dynamic noprefixroute eth0 valid_lft 3522sec preferred_lft 3522sec inet6 fe80::462:b5ff:fe81:e365/64 scope link valid_lft forever preferred_lft forever 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 06:7d:2c:e9:2f:01 brd ff:ff:ff:ff:ff:ff inet 10.10.10.10/24 brd 10.10.10.255 scope global noprefixroute eth1 valid_lft forever preferred_lft forever inet6 fe80::2bcc:cea2:c7fb:6bba/64 scope link noprefixroute valid_lft forever preferred_lft forever
nmcli con
NAME UUID TYPE DEVICE System eth0 5fb06bd0-0bb0-7ffb-45f1-d6edd65f3e03 ethernet eth0 DBnic 3b54603b-c603-46b9-9bd9-e6fc295e7a11 ethernet eth1 ens3 50e9a523-3280-4238-a07b-dbfd7d335273 ethernet -- Wired connection 1 9738a5c6-39dd-3515-aa1c-895f763851a6 ethernet --
Linux System Roles based on Ansible playbooks make it easy and consistent to enable specific services and configurations on your RHEL hosts, and across many versions. We experimented with the network system role in this exercise, but storage, kdump (kernel crash dump), selinux, and timesync are also available.
Domain |
![]() |
|
Workshop | ||
Student ID |