Ansible is an open-source IT automation tool developed by Red Hat that allows managing server configuration, application deployment, and task automation using human-readable YAML playbooks. Unlike Chef or Puppet (which require agents installed on managed nodes), Ansible is agentless — it connects to managed servers via SSH and executes tasks using Python, with no permanent agent process running. This makes Ansible particularly suited to RHEL environments where minimising installed software and attack surface is important. Ansible on RHEL 9 is available directly from Red Hat’s repositories and is the recommended automation tool in Red Hat’s ecosystem. This guide covers installing Ansible on RHEL 9, configuring an inventory, running ad-hoc commands, and writing basic playbooks.
Prerequisites
- RHEL 9 control node (where Ansible runs)
- SSH access to managed nodes (target servers)
- Python 3.9+ on managed nodes (RHEL 9 default)
Step 1 — Install Ansible
# Enable the EPEL and Ansible AppStream
dnf install -y epel-release
dnf install -y ansible-core
# Or install the full Ansible package (more modules)
dnf install -y ansible
ansible --version
Step 2 — Configure Inventory
# /etc/ansible/hosts (or create a project-specific inventory)
# /srv/ansible/inventory.ini
[webservers]
web1.example.com ansible_user=admin
web2.example.com ansible_user=admin
[databases]
db1.example.com ansible_user=admin ansible_port=2222
[production:children]
webservers
databases
[all:vars]
ansible_python_interpreter=/usr/bin/python3
Step 3 — Run Ad-Hoc Commands
# Test connectivity to all hosts
ansible all -i inventory.ini -m ping
# Run a command on all web servers
ansible webservers -i inventory.ini -m command -a "uptime"
# Install a package on all hosts (requires sudo)
ansible all -i inventory.ini -m dnf -a "name=nginx state=present" -b
# Gather facts about a host
ansible web1.example.com -i inventory.ini -m setup | grep ansible_os
Step 4 — Write a Basic Playbook
# /srv/ansible/webserver.yml
---
- name: Configure web servers
hosts: webservers
become: true # Use sudo
vars:
http_port: 80
server_name: "{{ inventory_hostname }}"
tasks:
- name: Install Nginx
dnf:
name: nginx
state: present
- name: Ensure Nginx is running and enabled
systemd:
name: nginx
state: started
enabled: true
- name: Open HTTP port in firewall
firewalld:
service: http
permanent: true
state: enabled
immediate: true
- name: Deploy index.html from template
template:
src: templates/index.html.j2
dest: /var/www/html/index.html
owner: nginx
group: nginx
mode: '0644'
ansible-playbook -i inventory.ini webserver.yml
Conclusion
Ansible on RHEL 9 provides idempotent server configuration management that can be run repeatedly without changing a correctly-configured system. The most critical Ansible concept is idempotency: each task should check the current state and only make changes when necessary — the dnf module only installs a package if it is not already present, and the systemd module only starts a service if it is not already running. This makes Ansible playbooks safe to re-run at any time as a configuration convergence check, not just as a one-time setup script.
Next steps: How to Write Ansible Playbooks for Server Automation on RHEL 9, How to Install Terraform on RHEL 9, and How to Install Jenkins on RHEL 9.