Skip to content

Instantly share code, notes, and snippets.

@russellds
Created June 4, 2025 03:34
Show Gist options
  • Save russellds/5f6931274caa3858cd7e90e9c96f2cfb to your computer and use it in GitHub Desktop.
Save russellds/5f6931274caa3858cd7e90e9c96f2cfb to your computer and use it in GitHub Desktop.
RHEL9 Bootstrap

Bootstrapping a Red Hat Enterprise Linux (RHEL) 9 server on-premises for Ansible involves setting up SSH, Python, and a sudo user, tailored to RHEL’s specifics (e.g., dnf package manager, wheel group for sudo). Since this is your first server, I’ll provide a concise, secure, and RHEL-specific process to get it ready for Ansible management, including a shell script to automate the bootstrap. The process assumes you have initial access to the server (e.g., via root or a default user) and are setting it up from a control node (your local machine or another server running Ansible).

RHEL 9 Bootstrap Process for Ansible

Prerequisites

  • RHEL 9 installed: Ensure the server has a base installation with SSH enabled (usually included in RHEL’s default setup).
  • Control node: A machine with Ansible installed (can be your local machine or another server).
  • Network access: The control node must reach the server via SSH (port 22).
  • Initial credentials: Root access or a user with sudo privileges.

Step-by-Step Manual Process

If you prefer manual setup or want to understand each step:

  1. Log in to the Server

    • Access the server as root or the default user (e.g., created during RHEL installation) via SSH:
      ssh root@server_ip
    • If you don’t have root, use a user with sudo privileges.
  2. Set Up SSH Key-Based Authentication

    • On your control node, generate an SSH key pair (if not already done):
      ssh-keygen -t ed25519 -f ~/.ssh/ansible_key -N ""
    • Copy the public key to the server:
      ssh-copy-id -i ~/.ssh/ansible_key root@server_ip
      Or manually add it to /root/.ssh/authorized_keys:
      mkdir -p /root/.ssh
      echo "your-public-key-from-ansible_key.pub" >> /root/.ssh/authorized_keys
      chmod 700 /root/.ssh
      chmod 600 /root/.ssh/authorized_keys
  3. Create an Ansible User

    • Create a dedicated ansible user with sudo privileges:
      adduser ansible
      usermod -aG wheel ansible
    • Copy the SSH key to the ansible user:
      mkdir -p /home/ansible/.ssh
      cp /root/.ssh/authorized_keys /home/ansible/.ssh/
      chown -R ansible:ansible /home/ansible/.ssh
      chmod 700 /home/ansible/.ssh
      chmod 600 /home/ansible/.ssh/authorized_keys
    • Configure sudo to allow passwordless execution (optional but simplifies automation):
      echo "ansible ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/ansible
      chmod 440 /etc/sudoers.d/ansible
  4. Install Python

    • RHEL 9 typically includes Python 3, but verify and install if needed:
      dnf install -y python3 python3-pip
    • Verify Python:
      python3 --version
  5. Secure SSH (Optional but Recommended)

    • Edit /etc/ssh/sshd_config to disable password authentication:
      sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
      sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config
    • Restart SSH:
      systemctl restart sshd
  6. Test SSH Connectivity

    • From the control node, test SSH as the ansible user:
      ssh -i ~/.ssh/ansible_key ansible@server_ip
    • Verify sudo access:
      sudo -l
  7. Set Up Ansible on the Control Node

    • Install Ansible (e.g., on your local machine or control node):
      dnf install -y ansible  # On RHEL-based control node
      # Or via pip for the latest version:
      pip install ansible
    • Create an inventory file (inventory.yml):
      all:
        hosts:
          server1:
            ansible_host: server_ip
            ansible_user: ansible
            ansible_ssh_private_key_file: ~/.ssh/ansible_key
    • Test connectivity:
      ansible -i inventory.yml all -m ping
      A pong response confirms the server is ready.

Automated Bootstrap Script

To streamline the process, use this shell script (bootstrap_rhel9.sh) on the RHEL 9 server. Run it as root or with sudo.

#!/bin/bash
# Ensure script runs as root
if [ "$EUID" -ne 0 ]; then
  echo "Please run as root or with sudo"
  exit 1
fi

# Install Python
dnf install -y python3 python3-pip

# Create ansible user and add to wheel group
adduser ansible
usermod -aG wheel ansible

# Set up SSH for ansible user
mkdir -p /home/ansible/.ssh
chmod 700 /home/ansible/.ssh
touch /home/ansible/.ssh/authorized_keys
chmod 600 /home/ansible/.ssh/authorized_keys
chown -R ansible:ansible /home/ansible/.ssh

# Add SSH public key (replace with your actual key)
echo "your-public-key-here" > /home/ansible/.ssh/authorized_keys

# Configure sudo without password
echo "ansible ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/ansible
chmod 440 /etc/sudoers.d/ansible

# Secure SSH configuration
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config
systemctl restart sshd

echo "Bootstrap complete. Test Ansible connectivity with: ansible -i inventory.yml all -m ping"

Usage

  1. Replace your-public-key-here with the contents of ~/.ssh/ansible_key.pub from your control node.
  2. Copy the script to the server:
    scp bootstrap_rhel9.sh root@server_ip:/tmp/
  3. Log in and run it:
    ssh root@server_ip "bash /tmp/bootstrap_rhel9.sh"
    Or, if you’ve already set up SSH keys for root:
    ssh root@server_ip "bash /tmp/bootstrap_rhel9.sh"

RHEL 9-Specific Notes

  • SELinux: RHEL 9 has SELinux enabled by default in enforcing mode. Ansible works with SELinux, but ensure SSH and Python operations aren’t blocked. If issues arise, check SELinux logs (/var/log/audit/audit.log) or temporarily set SELinux to permissive for debugging:
    setenforce 0
    Revert to enforcing after resolving issues:
    setenforce 1
    Use Ansible’s selinux module in playbooks for permanent changes.
  • Firewall: RHEL 9 uses firewalld. Ensure SSH (port 22) is open:
    firewall-cmd --permanent --add-service=ssh
    firewall-cmd --reload
  • Subscription Manager: Ensure your RHEL 9 system is registered with a valid subscription to access packages:
    subscription-manager register --username <username> --password <password>
    subscription-manager attach --auto
    If not registered, you may need to configure a local repository or use a RHEL Developer Subscription.

Testing with an Ansible Playbook

After bootstrapping, verify with a simple playbook (test_rhel9.yml):

---
- hosts: all
  tasks:
    - name: Ensure Python is installed
      ansible.builtin.dnf:
        name: python3
        state: present
      become: yes
    - name: Create a test file
      ansible.builtin.file:
        path: /tmp/ansible_test
        state: touch
      become: yes

Run it:

ansible-playbook -i inventory.yml test_rhel9.yml

Recommendations

  • Use the script for speed: The provided bootstrap_rhel9.sh automates all steps and is tailored for RHEL 9’s dnf and wheel group.
  • Secure the setup:
    • Disable password-based SSH to reduce attack surface.
    • Use a strong SSH key (Ed25519 preferred).
    • Restrict firewalld to allow only necessary ports (e.g., SSH).
  • Next steps: Once bootstrapped, store your Ansible playbooks in a Git repository for version control and start defining your server configuration (e.g., installing services, configuring files).

If you encounter issues (e.g., SELinux, firewall, or subscription errors), let me know, and I can provide specific troubleshooting steps. Would you like me to customize the script further (e.g., add specific firewall rules or handle SELinux)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment