Ansible Emergency Hotline Series: Linux Automation – (17) RHEL9 Standardized Configuration

πŸ€– Ansible Emergency Hotline | Is RHEL9 Standardized Configuration Too Complicated? One-Click Automation to Say Goodbye to Repetitive Work!

Tired of repeatedly configuring users, firewalls, and time synchronization for each RHEL9 server? Today, we bring you a comprehensive Ansible automation solution that will help you say goodbye to the nightmare of manual configuration!

🎯 Pain Points Addressed

The daily routine of an operations engineer: New server goes live β†’ Manually configure users β†’ Set up firewalls β†’ Configure time synchronization β†’ Deploy monitoring β†’ Optimize system parameters… Repeating this for each server is exhausting!

Even worse: Manual configuration is prone to errors, leading to inconsistent configurations and difficulties in later maintenance. Have you ever thought that if there were a standardized automation configuration solution, all these problems would be solved?

✨ Solution Preview

Today, we share an RHEL9 One-Click Standardized Configuration Ansible automation scenario, which includes 8 core functional modules, allowing your server configuration to be standardized, automated, and repeatable!

⭐ Automation Scenario Ratings

Rating Dimension Rating Description
Ease of Use ⭐⭐⭐⭐⭐ One-click execution, detailed comments, beginner-friendly
Reusability ⭐⭐⭐⭐⭐ Variable configuration, supports multi-host parallel execution
Stability ⭐⭐⭐⭐⭐ Idempotent design, comprehensive error handling
Scalability ⭐⭐⭐⭐⭐ Modular roles, easy to extend functionality
Best Practices Compliance ⭐⭐⭐⭐⭐ Follows Ansible best practices, code standards

πŸ—‚οΈ Project Directory Structure

02_RHEL9_One_Click_Standardized_Configuration/
β”œβ”€β”€ inventory                    # Host inventory configuration
β”œβ”€β”€ group_vars/
β”‚   └── all.yml                 # Global variable configuration
β”œβ”€β”€ playbook.yml                # Main playbook file
β”œβ”€β”€ ansible.cfg                 # Ansible configuration file
β”œβ”€β”€ roles/                      # 8 core functional roles
β”‚   β”œβ”€β”€ user_management/        # User management
β”‚   β”œβ”€β”€ system_config/          # System configuration
β”‚   β”œβ”€β”€ firewall_config/        # Firewall configuration
β”‚   β”œβ”€β”€ hosts_config/           # Standardization of hosts file
β”‚   β”œβ”€β”€ chrony_config/          # Time synchronization configuration
β”‚   β”œβ”€β”€ node_exporter/          # Monitoring deployment
β”‚   β”œβ”€β”€ system_optimization/    # System optimization
β”‚   └── verification/           # Configuration verification
β”œβ”€β”€ quick_start.sh              # Quick start script
└── troubleshooting_guide.md     # Problem troubleshooting guide

πŸ“„ Core File Content Overview

🎯 Main Playbook File (playbook.yml)

---
- name: RHEL9 One-Click Standardized Configuration
  hosts: diagnose
  gather_facts: yes
  become: yes

  pre_tasks:
    - name: Check system version
      ansible.builtin.shell: cat /etc/redhat-release
      register: system_version

    - name: Display system information
      ansible.builtin.debug:
        msg: "Starting configuration for system: {{ inventory_hostname }} ({{ system_version.stdout }})"

  roles:
    - role: user_management
      tags: user_management
    - role: system_config
      tags: system_config
    - role: firewall_config
      tags: firewall_config
    - role: hosts_config
      tags: hosts_config
    - role: chrony_config
      tags: chrony_config
    - role: node_exporter
      tags: node_exporter
    - role: system_optimization
      tags: system_optimization
    - role: verification
      tags: verification

  post_tasks:
    - name: Configuration completion notification
      ansible.builtin.debug:
        msg: "πŸŽ‰ RHEL9 Standardized Configuration Completed!"

    - name: Ask if reboot is needed
      ansible.builtin.pause:
        prompt: "Should the system be rebooted to apply all configurations? (y/n)"
      register: reboot_choice

    - name: Reboot system
      ansible.builtin.reboot:
      when: reboot_choice.user_input | lower == 'y'

πŸ”§ Host Inventory Configuration (inventory)

[RHEL9_Servers] 
10.66.208.232

[template_servers]
template_server ansible_host=10.66.208.237

[all:vars]
ansible_user=root
ansible_ssh_private_key_file=~/.ssh/id_rsa
ansible_become=yes
ansible_become_method=sudo
ansible_ssh_common_args='-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'

βš™οΈ Global Variable Configuration (group_vars/all.yml)

# Administrator user configuration
admin_user: admin
admin_password: redhat

# Firewall port configuration
firewall_ports:
  - 50051
  - 53
  - 80
  - 443
  - 5432
  - 6379
  - 27199
  - 9000
  - 9001
  - 9002
  - 9003

# NTP server configuration
ntp_servers:
  - ntp.aliyun.com
  - ntp1.aliyun.com
  - ntp2.aliyun.com

# Network configuration
network:
  allowed_subnets:
    - 10.66.0.0/16
    - 192.168.0.0/16

# Template server configuration
template_server:
  host: 10.66.208.237
  hosts_file: /etc/hosts

# Node Exporter configuration
node_exporter:
  version: 1.6.1
  port: 9100
  user: prometheus
  install_path: /opt/node_exporter

# System optimization parameters
system_limits:
  - "prometheus soft nofile 65536"
  - "prometheus hard nofile 65536"
  - "* soft nofile 65536"
  - "* hard nofile 65536"

sysctl_params:
  net.core.somaxconn: 65535
  net.ipv4.tcp_max_syn_backlog: 65535
  vm.max_map_count: 262144

# SELinux configuration
selinux:
  state: permissive
  policy: targeted

# Backup configuration
backup:
  enabled: true
  suffix: ".backup.$(date +%Y%m%d_%H%M%S)"

πŸ” User Management Role (roles/user_management/tasks/main.yml)

---
- name: Create administrator user
  ansible.builtin.user:
    name: "{{ admin_user }}"
    password: "{{ admin_password | password_hash('sha512') }}"
    shell: /bin/bash
    create_home: yes
    state: present

- name: Configure sudo permissions
  ansible.builtin.lineinfile:
    path: /etc/sudoers
    line: "{{ admin_user }} ALL=(ALL) NOPASSWD: ALL"
    state: present
    validate: 'visudo -cf %s'

- name: Enable user session persistence
  ansible.builtin.systemd:
    name: user@{{ admin_user }}
    enabled: yes
    daemon_reload: yes

- name: Verify user creation
  ansible.builtin.shell: id {{ admin_user }}
  register: user_check

- name: Display user information
  ansible.builtin.debug:
    msg: "User {{ admin_user }} created successfully: {{ user_check.stdout }}"

πŸ›‘οΈ Firewall Configuration Role (roles/firewall_config/tasks/main.yml)

---
- name: Ensure firewalld service is running
  ansible.builtin.systemd:
    name: firewalld
    state: started
    enabled: yes

- name: Open TCP ports
  ansible.posix.firewalld:
    port: "{{ item }}/tcp"
    permanent: yes
    state: enabled
  loop: "{{ firewall_ports }}"

- name: Open UDP ports
  ansible.posix.firewalld:
    port: "{{ item }}/udp"
    permanent: yes
    state: enabled
  loop: "{{ firewall_ports }}"

- name: Reload firewall configuration
  ansible.builtin.systemd:
    name: firewalld
    state: reloaded

- name: Verify firewall configuration
  ansible.builtin.shell: firewall-cmd --list-all
  register: firewall_status

- name: Display firewall status
  ansible.builtin.debug:
    msg: "Firewall configuration completed: {{ firewall_status.stdout_lines }}"

⏰ Time Synchronization Configuration Role (roles/chrony_config/tasks/main.yml)

---
- name: Install chrony
  ansible.builtin.dnf:
    name: chrony
    state: present

- name: Configure chrony service
  ansible.builtin.template:
    src: chrony.conf.j2
    dest: /etc/chrony.conf
    owner: root
    group: root
    mode: '0644'
    backup: yes

- name: Start chrony service
  ansible.builtin.systemd:
    name: chronyd
    state: started
    enabled: yes

- name: Wait for time synchronization
  ansible.builtin.pause:
    seconds: 10

- name: Verify time synchronization status
  ansible.builtin.shell: chronyc sources
  register: chrony_sources

- name: Display time synchronization status
  ansible.builtin.debug:
    msg: "Time synchronization configuration completed: {{ chrony_sources.stdout_lines }}"

πŸ“Š Monitoring Deployment Role (roles/node_exporter/tasks/main.yml)

---
- name: Find node_exporter tarball
  ansible.builtin.find:
    paths: /tmp
    patterns: "node_exporter-{{ node_exporter.version }}.linux-amd64.tar.gz"
  register: node_exporter_tarball

- name: Create installation directory
  ansible.builtin.file:
    path: "{{ node_exporter.install_path }}"
    state: directory
    owner: root
    group: root
    mode: '0755'

- name: Unarchive node_exporter
  ansible.builtin.unarchive:
    src: "{{ node_exporter_tarball.files[0].path }}"
    dest: "{{ node_exporter.install_path }}"
    remote_src: yes
    creates: "{{ node_exporter.install_path }}/node_exporter"

- name: Create prometheus user
  ansible.builtin.user:
    name: "{{ node_exporter.user }}"
    system: yes
    shell: /sbin/nologin
    create_home: no

- name: Configure systemd service
  ansible.builtin.template:
    src: node_exporter.service.j2
    dest: /etc/systemd/system/node_exporter.service
    owner: root
    group: root
    mode: '0644'

- name: Set file permissions
  ansible.builtin.file:
    path: "{{ node_exporter.install_path }}/node_exporter"
    owner: "{{ node_exporter.user }}"
    group: "{{ node_exporter.user }}"
    mode: '0755'

- name: Start node_exporter service
  ansible.builtin.systemd:
    name: node_exporter
    state: started
    enabled: yes
    daemon_reload: yes

- name: Wait for service to start
  ansible.builtin.pause:
    seconds: 5

- name: Verify service status
  ansible.builtin.uri:
    url: "http://localhost:{{ node_exporter.port }}/metrics"
    method: GET
  register: node_exporter_check

- name: Display monitoring service status
  ansible.builtin.debug:
    msg: "Node Exporter deployed successfully, status code: {{ node_exporter_check.status }}"

🎯 Main Playbook File (playbook.yml)

---
- name: RHEL9 One-Click Standardized Configuration
  hosts: RHEL9_Servers
  gather_facts: yes
  become: yes

  pre_tasks:
    - name: Check system version
      ansible.builtin.shell: cat /etc/redhat-release
      register: system_version

    - name: Display system information
      ansible.builtin.debug:
        msg: "Starting configuration for system: {{ inventory_hostname }} ({{ system_version.stdout }})"

  roles:
    - role: user_management
      tags: user_management
    - role: system_config
      tags: system_config
    - role: firewall_config
      tags: firewall_config
    - role: hosts_config
      tags: hosts_config
    - role: chrony_config
      tags: chrony_config
    - role: node_exporter
      tags: node_exporter
    - role: system_optimization
      tags: system_optimization
    - role: verification
      tags: verification

  post_tasks:
    - name: Configuration completion notification
      ansible.builtin.debug:
        msg: "πŸŽ‰ RHEL9 Standardized Configuration Completed!"

    - name: Ask if reboot is needed
      ansible.builtin.pause:
        prompt: "Should the system be rebooted to apply all configurations? (y/n)"
      register: reboot_choice

    - name: Reboot system
      ansible.builtin.reboot:
      when: reboot_choice.user_input | lower == 'y'

πŸ”§ Host Inventory Configuration (inventory)

[RHEL9_Servers]
10.66.208.232

[template_servers]
template_server ansible_host=10.66.208.237

[all:vars]
ansible_user=root
ansible_ssh_private_key_file=~/.ssh/id_rsa
ansible_become=yes
ansible_become_method=sudo
ansible_ssh_common_args='-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'

βš™οΈ Global Variable Configuration (group_vars/all.yml)

# Administrator user configuration
admin_user: admin
admin_password: redhat

# Firewall port configuration
firewall_ports:
  - 50051
  - 53
  - 80
  - 443
  - 5432
  - 6379
  - 27199
  - 9000
  - 9001
  - 9002
  - 9003

# NTP server configuration
ntp_servers:
  - ntp.aliyun.com
  - ntp1.aliyun.com
  - ntp2.aliyun.com

# Network configuration
network:
  allowed_subnets:
    - 10.66.0.0/16
    - 192.168.0.0/16

# Template server configuration
template_server:
  host: 10.66.208.237
  hosts_file: /etc/hosts

# Node Exporter configuration
node_exporter:
  version: 1.6.1
  port: 9100
  user: prometheus
  install_path: /opt/node_exporter

# System optimization parameters
system_limits:
  - "prometheus soft nofile 65536"
  - "prometheus hard nofile 65536"
  - "* soft nofile 65536"
  - "* hard nofile 65536"

sysctl_params:
  net.core.somaxconn: 65535
  net.ipv4.tcp_max_syn_backlog: 65535
  vm.max_map_count: 262144

# SELinux configuration
selinux:
  state: permissive
  policy: targeted

# Backup configuration
backup:
  enabled: true
  suffix: ".backup.$(date +%Y%m%d_%H%M%S)"

πŸš€ How to Use?

πŸ› οΈ Foolproof Deployment Guide

1️⃣ Environment Preparation

# Ensure Ansible is installed
ansible --version

# Configure SSH key authentication
ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa
ssh-copy-id root@target_server_IP

2️⃣ Download the Project

# Navigate to the project directory
cd 02_RHEL9_One_Click_Standardized_Configuration

# Add execution permissions to the quick start script
chmod +x quick_start.sh

3️⃣ Configure the Host Inventory

Edit the <span><span>inventory</span></span> file and add your target servers:

[RHEL9_Servers]
Your_Server_IP_Address

[template_servers]
template_server ansible_host=Your_Template_Server_IP

4️⃣ One-Click Execution

# Method 1: Use the quick start script
./quick_start.sh

# Method 2: Directly execute the playbook
ansible-playbook playbook.yml -i inventory -v

5️⃣ Verify Results

# Check user configuration
id admin
sudo -l -U admin

# Check firewall configuration
firewall-cmd --list-all

# Check time synchronization
chronyc sources

# Check monitoring service
curl http://localhost:9100/metrics

🎯 Step-by-Step Execution Guide

If you only want to execute specific functions, you can use tags:

# Only configure user management
ansible-playbook playbook.yml -i inventory --tags user_management

# Only configure firewall
ansible-playbook playbook.yml -i inventory --tags firewall_config

# Only deploy monitoring
ansible-playbook playbook.yml -i inventory --tags node_exporter

πŸ”₯ Core Feature Highlights

βœ… User Management Automation

β€’Automatically create admin userβ€’Configure sudo permissions (no password)β€’Enable session persistenceβ€’Password security settings

βœ… Standardized System Configuration

β€’Hostname verificationβ€’SELinux configuration (permissive mode)β€’System information collection

βœ… Intelligent Firewall Configuration

β€’Batch open specified portsβ€’TCP/UDP dual protocol supportβ€’Configuration persistenceβ€’Service reload

βœ… Standardization of hosts file

β€’Retrieve standard hosts from template serverβ€’Automatically back up original fileβ€’Intelligent merge configurationβ€’Local entry protection

βœ… Precise Time Synchronization Configuration

β€’Install and configure chrony serviceβ€’Aliyun NTP serversβ€’Configuration verificationβ€’Service status check

βœ… Monitoring Deployment Automation

β€’Automatically download node_exporterβ€’Create system userβ€’Configure systemd serviceβ€’Port listening verification

βœ… System Performance Optimization

β€’File descriptor optimizationβ€’Network parameter tuningβ€’Memory mapping optimizationβ€’System limits configuration

βœ… Comprehensive Verification Mechanism

β€’System information verificationβ€’User configuration checkβ€’Network connectivity testβ€’Service status confirmation

πŸ’‘ Tips for Use

🎯 Batch Deployment

# Add multiple servers in the inventory
[RHEL9_Servers]
server1 ansible_host=192.168.1.100
server2 ansible_host=192.168.1.101
server3 ansible_host=192.168.1.102

# Execute in parallel for double efficiency
ansible-playbook playbook.yml -i inventory --forks 10

πŸ”§ Custom Configuration

Edit the <span><span>group_vars/all.yml</span></span> file to adjust according to your environment:

β€’Modify the firewall port listβ€’Change NTP serversβ€’Adjust system optimization parametersβ€’Customize monitoring configuration

πŸ› Troubleshooting

If you encounter issues, check the <span><span>troubleshooting_guide.md</span></span> file, which contains solutions and records for common problems.

🎁 Summary

This RHEL9 one-click standardized configuration solution truly achieves:

β€’πŸš€ One-Click Deployment: From zero to production-ready with just one commandβ€’πŸ”„ Repeatable Execution: Idempotent design, no fear of repeated runsβ€’πŸ“ˆ Batch Processing: Supports multi-host parallel configurationβ€’πŸ”§ Highly Customizable: Variable configuration to adapt to different environmentsβ€’πŸ“Š Comprehensive Verification: Automatically checks configuration results

What are you waiting for? Download this automation configuration solution now and boost your operational efficiency by 10 times!

πŸ‘‰ Do you find the Playbook in the article not detailed enough? Want to see every step with super detailed comments in Chinese, understanding the meaning behind each line of code?

πŸ‘‰ Click on the 【Read the Original】 below to get the Playbook project package with complete comments and syntax highlighting! πŸ‘ˆ

Tags: #Ansible #Automation #RHEL9 #StandardizedConfiguration #OperationalEfficiency

Leave a Comment