Ansible Firefighting Hotline Series (10): Automating Linux Network Configuration with RHEL-system-roles.network

Ansible Firefighting Hotline Series (10): Automating Linux Network Configuration with rhel-system-roles.network

#Linux #Automation #Ansible #Network #NetworkManagement #NetworkConfigurationAutomation

πŸ”₯ Say Goodbye to Complexity! Why is Network Configuration in Need of Automation?

Dear operations engineers, SREs, and cloud engineers, please recall these moments that give us headaches:

β€’New Machine Setup 🀯: Dozens of new servers arrive, and you need to log in one by one, typing repetitive <span><span>nmcli</span></span> commands to configure static IPs, gateways, and DNS. The process is long and prone to errors. A single incorrect IP can lead to the failure of the entire application deployment.β€’Bulk Changes β˜•οΈ->πŸ₯Ά: Suddenly notified, “All servers need to change their backup DNS!”. What was once a leisurely afternoon tea time instantly turns into a “copy-paste competition” across dozens or even hundreds of terminal windows.β€’Inconsistent Environments πŸ˜΅πŸ’«: The network configurations of development, testing, and production environments always have subtle differences, relying on documentation and memory to maintain them is a disaster. The lack of standardized configurations lays countless hidden dangers for failures.

In the era of cloud and automation, manual network configuration is synonymous with inefficiency and risk. It is not only repetitive labor but also the enemy of stability.

Today, we will put an end to this chaos! This article will guide you in using the Red Hat Ansible Automation Platform (or the community version of Ansible) to build a modular, precisely controlled NetworkManager management role, upgrading network configuration from a “manual workshop” to an “automated assembly line”, allowing you to easily handle network change requirements of any scale!✨

✨ The Art of Design: Why We Build Automation This Way?

An excellent automation solution should not only work but also be user-friendly and easy to extend. Our design strictly follows the best practices of enterprise-level automation, with core advantages including:

β€’Declarative “Final State” Management 🎯 You no longer need to write step-by-step operation scripts. Instead, you only need to declare your desired network final state in a centralized variable file (<span><span>host_vars</span></span>) like filling out a configuration checklistβ€”such as “I need a connection named <span><span>static-ens10</span></span> with IP xxx and DNS yyy”. Ansible will automatically analyze the differences between the current state and the desired state and execute the necessary operations accurately.β€’Functional Modularity and Logical Decoupling 🧩 We split different operations (viewing, adding, modifying, deleting, controlling) into independent task files. The benefits of this approach are:β€’Single Responsibility🧩 Each file does one thing, making the code logic extremely clear and easy to maintain and debug.β€’Flexible Combination🧩<span><span>configure_network_role.yml</span></span> becomes the master controller, allowing you to enable various functional modules as needed, like building with Legos.β€’Precise Execution through Tags🧩 This is the highlight of this solution! We have tagged each type of operation (<span><span>pre_check</span></span>, <span><span>apply_config</span></span>, <span><span>post_check</span></span>, etc.). This means you can fully control the behavior of the Playbook from the command line:β€’Want to inspect?<span><span>--pre_check</span></span><code><span><span>β€’</span></span><span><span>Want to deploy new configurations?</span></span><code><span><span>--tags apply_config</span></span><span><span>β€’</span></span><span><span>This mode transforms Ansible from a "full execution" tool into a Swiss Army knife that can</span></span><strong><span><span>execute precisely on demand</span></span></strong><span><span>, completely eliminating the risk of misoperation.</span></span><h3><span><span>✨ Ansible Official Tool: </span></span><code><span><span>rhel-system-roles.network</span></span> Introduction

<span><span>rhel-system-roles</span></span> is a set of Ansible roles included in Red Hat Enterprise Linux 8 (in CentOS 8 it is called <span><span>linux-system-roles</span></span>), developed and maintained by Red Hat, aimed at providing a stable and consistent system management automation interface.<span><span>rhel-system-roles.network</span></span> is the role specifically responsible for network configuration, considered the easiest way to configure network settings on managed hosts.

🀩 Its core benefits include:

β€’Abstraction and Simplification: You do not need to worry about whether the underlying system is RHEL 7, 8, or 9, nor do you need to memorize complex <span><span>nmcli</span></span> commands. You only need to describe your desired network configuration through a variable called <span><span>network_connections</span></span>.β€’Idempotency Guarantee: The role has built-in state-checking logic. If you run the Playbook repeatedly, it will only apply necessary changes, skipping configurations that already meet the expected state, ensuring the safety and predictability of the automation process.β€’Comprehensive Functionality: In addition to simple static/DHCP configurations, it also natively supports advanced features such as network bonding, teaming, VLAN, MACVLAN, etc.β€’Official Support: As part of RHEL, this role has been thoroughly tested and supported by Red Hat, making it the preferred choice for enterprise production environments.

The Ansible Role is applicable to the following operating system versions::

β€’βœ… Red Hat Enterprise Linux (RHEL) 7.4+, 8, 9β€’βœ… CentOS 7, 8 Stream, 9 Streamβ€’βœ… Rocky Linux 8, 9β€’βœ… AlmaLinux 8, 9β€’βœ… Oracle Linux 7, 8, 9

πŸš€ Getting Started from Scratch: Three Steps to Deploy Your Linux Network Configuration Automation Tool

Don’t worry about complexity; I have prepared all the steps for you. You just need to copy and paste to have this powerful tool!

Prerequisites πŸ“‹

β€’πŸ’» Control Node: A computer with Ansible installed and the <span><span>rhel-system-roles</span></span> package installed (<span><span>sudo yum install rhel-system-roles</span></span>).β€’πŸ–₯️ Managed Node: A Linux server with Network Manager, and the control node can SSH into it without a password.

πŸš€ Deployment and Execution: Complete Automation in Three Steps

Step 1: πŸ“ Create Project Directory and All Files

A clear directory structure is the beginning of good practice. We will create all necessary files and directories.

1

Execute the following command to create the directory structure::

# Create the main project directory
mkdir network_role_project
cd network_role_project

# Create directories for storing host variables
mkdir -p host_vars/Test-RHEL-7.9-2/network_config.yml
mkdir -p host_vars/Test-RHEL-7.9-3/network_config.yml
mkdir -p host_vars/Test-RHEL-7.9-4/network_config.yml

Your directory structure now looks like this:

[root@ansible25 network_role_project]# tree
.
β”œβ”€β”€ ansible.cfg
β”œβ”€β”€ configure_network_role.yml
β”œβ”€β”€ group_vars
β”‚   └── web_network_servers
β”‚       └── common_config.yml
β”œβ”€β”€ host_vars
β”‚   β”œβ”€β”€ Test-RHEL-7.9-2
β”‚   β”‚   └── network_config.yml
β”‚   β”œβ”€β”€ Test-RHEL-7.9-3
β”‚   β”‚   └── network_config.yml
β”‚   └── Test-RHEL-7.9-4
β”‚       └── network_config.yml
└── inventory

2

Create the <span><span>inventory</span></span> file

β€’Purpose: To inform Ansible on which hosts to perform operations.β€’Location: <span><span>network_role_project/inventory</span></span>β€’Content:

[network_servers]
Test-RHEL-7.9-2
Test-RHEL-7.9-3
Test-RHEL-7.9-4

3

Create a Network Blueprint for Target Machine “Server1”

β€’Purpose: To define the expected network state for server1.β€’Location: network_role_project/host_vars/Test-RHEL-7.9-2/network_config.ymlβ€’Content:

    ---
    # Define network connection for server1 in this file
    network_connections:
      - name: static-ens192
        interface_name: ens192
        type: ethernet
        state: up
        autoconnect: yes
        ip:
          address:
            - "10.71.18.251/23"
          gateway4: "10.71.19.254"
          dns:
            - 10.72.17.5
            - 10.68.5.26
          dns_search:
            - szx.redhat.com
            - redhat.com

4

Create a Network Blueprint for Target Machine “Server2”

β€’Purpose: To define the expected network state for server2.β€’Location: network_role_project/host_vars/Test-RHEL-7.9-3/network_config.ymlβ€’Content:

    ---
    # Define network connection for server2 in this file
    network_connections:
      - name: static-ens192
        interface_name: ens192
        type: ethernet
        state: up
        autoconnect: yes
        ip:
          address:
            - "10.71.18.252/23"
          gateway4: "10.71.19.254"
          dns:
            - 10.72.17.5
            - 10.68.5.26
          dns_search:
            - szx.redhat.com
            - redhat.com

5

Create the <span><span>configure_network_role.yml</span></span> Main Execution Playbook

β€’Purpose: This is the only Playbook you need to run, responsible for calling the role and executing validation tasks.β€’Location: network_role_project/configure_network_role.ymlβ€’Content:

---
- name: Configure network using rhel-system-roles.network
  hosts: network_servers
  become: true

  tasks:
    - name: "Before applying configuration - List network interfaces and basic information"
      ansible.builtin.debug:
        msg: |
          List of network interfaces for host {{ inventory_hostname }}: {{ ansible_facts.interfaces }}
          Default IPv4 interface information:
            Address: {{ ansible_facts.default_ipv4.address | default('N/A') }}
            Gateway: {{ ansible_facts.default_ipv4.gateway | default('N/A') }}
      tags: [pre_check]

    - name: "Apply rhel-system-roles.network role"
      ansible.builtin.include_role:
        name: rhel-system-roles.network
      tags: [apply_config]

    - name: "Refresh host facts to get the latest network status"
      ansible.builtin.setup:
        gather_subset:
          - network
      tags: [post_check]

    - name: "After applying configuration - Confirm and print detailed configuration of eth/ens xx"
      ansible.builtin.debug:
        msg: |
          Configuration applied!
          Current IPv4 configuration for interface 'eth1':
          Address: {{ ansible_facts.eth1.ipv4.address }}
          Subnet Mask: {{ ansible_facts.eth1.ipv4.netmask }}
          Gateway: {{ ansible_facts.default_ipv4.gateway }}
      when: "'eth1' in ansible_facts.interfaces"
      tags: [post_check]

Step 2: πŸš€ Execute Automation

Everything is ready! Now, ensure you are in the <span><span>network_role_project</span></span> directory, and then execute your Playbook!

# ansible-playbook -i inventory configure_network_role.yml

Step 3: πŸ“Š Interpret Output Results

Ansible will show you a clear execution process:

1Gathering Facts: Ansible first collects basic information from all servers.2Before applying configuration – Confirm network interfaces exist: <span><span>pre_check</span></span> task will run, and if there are no <span><span>eth</span></span>/ensX interfaces on the server, it will report an error and prompt you.3Apply rhel-system-roles.network role: The core role begins execution. If the server’s network configuration does not match your “blueprint”, you will see a <span><span>changed</span></span> status here. If it already matches, it will intelligently skip, showing <span><span>ok</span></span>.4Refresh host facts: Recollect network information to ensure we are verifying the latest state.5After applying configuration – Verify if eth/ensX IP address is correct: <span><span>post_check</span></span> task will run and provide the final verification result. If everything goes smoothly, you will see a success message like below:

    TASK [Refresh host facts to get the latest network status] 
    ************
    ok: [Test-RHEL-7.9-2]

    TASK [After applying configuration - Confirm and print detailed configuration of eth/ens xx] 
    ************
    ok: [Test-RHEL-7.9-2]

Advanced Tips: Use Tags for Precise Control

In complex operational scenarios, we do not always need to run the entire Playbook. Sometimes we just want to perform a pre-configuration check, sometimes we only want to apply core changes, and sometimes we just want to do a post-configuration verification. Ansible’s Tags feature is designed for this purpose.

πŸš€ Precise Execution and Output Interpretation

Now, you can use the <span><span>--tags</span></span> (or <span><span>-t</span></span>) command line parameter to precisely call the parts you want to execute.

Scenario A: Check Only Without Applying (Safety Inspection)

Suppose you only want to check whether the ethX/ensX interfaces exist on the server, but do not apply any network changes.

β€’Execute Command:

ansible-playbook -i inventory configure_network_role.yml --tags pre_check

β€’Expected Output: You will see the Playbook only runs tasks with the <span><span>pre_check</span></span> tag, and then it will end directly. The core <span><span>apply_config</span></span> and <span><span>post_check</span></span> tasks will be completely skipped.

    PLAY [Configure network using rhel-system-roles.network] 
    ***************
    TASK [Gathering Facts] 
    ***************
    ok: [Test-RHEL-7.9-2]
    TASK [Before applying configuration - List network interfaces and basic information] 
    ***************
    ok: [Test-RHEL-7.9-2] =&gt;
      msg: |-
        List of network interfaces for host Test-RHEL-7.9-2: ['lo', 'ens192']
        Default IPv4 interface information:
          Address: 10.71.18.251
          Gateway: 10.71.19.254
    PLAY RECAP
    ***************
    Test-RHEL-7.9-2: ok=2 changed=0 unreachable=0 failed=0  ...

Scenario B: Apply Only Without Checking (Quick Deployment)

Suppose you are very sure the configuration is correct and just want to quickly apply the configuration in <span><span>host_vars</span></span>, skipping all checks to save time.

β€’Execute Command:

ansible-playbook -i inventory configure_network_role.yml --tags apply_config

β€’Expected Output: The Playbook will skip <span><span>pre_check</span></span>, directly running the <span><span>apply_config</span></span> task to configure the network, and then end, with <span><span>post_check</span></span> also skipped.

    PLAY [Configure network using rhel-system-roles.network] 
    ***************

    TASK [Gathering Facts] 
    ***************
    ok: [Test-RHEL-7.9-2]

    TASK [Apply rhel-system-roles.network role] 
    ***************
    PLAY RECAP
    ***************
    Test-RHEL-7.9-2: ok=1 changed=0 unreachable=0 failed=0  ...

Scenario C: Apply and Verify (Common CI/CD Pattern)

This is the most common pattern: execute changes and then immediately verify whether the changes were successful.

β€’Execute Command:

ansible-playbook -i inventory configure_network_role.yml --tags apply_config,post_check

β€’Expected Output: The Playbook will skip <span><span>pre_check</span></span>, execute <span><span>apply_config</span></span> to make changes, and thencontinue executing<span><span>post_check</span></span> task to verify if the IP address is configured correctly and output the final success message.

    PLAY [Configure network using rhel-system-roles.network] 
    ***************

    TASK [Gathering Facts] 
    ***************
    ok: [Test-RHEL-7.9-2]

    TASK [Apply rhel-system-roles.network role] 
    ***************

    TASK [Refresh host facts to get the latest network status] 
    ***************
    ok: [Test-RHEL-7.9-2]

    TASK [After applying configuration - Confirm and print detailed configuration of eth/ens xx] 
    ***************
    skipping: [Test-RHEL-7.9-2]

    PLAY RECAP
    ***************
    Test-RHEL-7.9-2: ok=2 changed=0 unreachable=0 failed=0  ...

In this way, the same Playbook can flexibly respond to various operational scenarios, greatly enhancing its practicality and professionalism.

Congratulations! You have successfully used Ansible’s official best practices to complete network automation configuration and verification for multiple servers!

Summary and Resources

Through Red Hat’s official <span><span>rhel-system-roles.network</span></span>, we have achieved a highly reliable and efficient network automation method. This declarative, data-driven model is the core idea of modern automated operations.

Are you eager to deploy it in your environment?

To avoid any omissions while copying the code, we have packaged the complete project containing all categorized and filled code for you!

🎁 Click the link below to 【Read the Original】 (best viewed on a computer), and download the complete source code to add an officially certified “tool” to your operations toolbox!πŸ‘‡πŸ‘‡πŸ‘‡

Leave a Comment