Introduction
Real RHEL automation often combines package installation, service management, and firewall rules in one convergent playbook.
In this lab, you will install httpd, ensure it is enabled and running, allow HTTP through firewalld, and prove the playbook is idempotent.
Create a RHEL Service Automation Project
In this step, you will create a one-host project for automating package, service, and firewall state on the RHEL 10 VM.
cd /home/labex/project
mkdir -p rhce-ansible/{inventory,playbooks,reports}
cd rhce-ansible
cat > ansible.cfg <<'EOF'
[defaults]
inventory = ./inventory/hosts
host_key_checking = False
retry_files_enabled = False
EOF
cat > inventory/hosts <<'EOF'
[web]
host ansible_connection=local
EOF
The playbook will make real changes to the local RHEL system, so this lab uses one local host alias. That still lets you practice Ansible's package, service, and firewall modules through normal inventory targeting.
Define the Desired Web Service State
In this step, you will store desired state in variables. Keeping package, service, and firewall names in variables makes the playbook easier to adjust. Before running commands in this step, return to the Ansible project directory. This keeps the commands stable even when LabEx runs each step separately.
cd /home/labex/project/rhce-ansible
mkdir -p inventory/group_vars
cat > inventory/group_vars/web.yml <<'EOF'
web_package: httpd
web_service: httpd
firewall_service: http
EOF
Keeping these names in variables makes the playbook read like a policy: install this package, manage this service, and allow this firewalld service. If you later automate a different service, the task structure can stay the same.
cat inventory/group_vars/web.yml
Write the Package Service Firewall Playbook
In this step, you will write a playbook with privilege escalation. It uses package, service, and ansible.posix.firewalld to converge the web stack.
Before running commands in this step, return to the Ansible project directory. This keeps the commands stable even when LabEx runs each step separately.
cd /home/labex/project/rhce-ansible
cat > playbooks/web-stack.yml <<'EOF'
---
- name: Configure a basic web stack
hosts: web
become: true
gather_facts: false
tasks:
- name: Install web package
ansible.builtin.package:
name: "{{ web_package }}"
state: present
- name: Ensure web service is enabled and running
ansible.builtin.service:
name: "{{ web_service }}"
state: started
enabled: true
- name: Allow web traffic through the firewall
ansible.posix.firewalld:
service: "{{ firewall_service }}"
permanent: true
immediate: true
state: enabled
EOF
The three tasks converge related RHEL state. package ensures the RPM is installed, service ensures the systemd unit is running and enabled, and ansible.posix.firewalld opens the HTTP service both immediately and persistently.
ansible-playbook playbooks/web-stack.yml --syntax-check
Run the Web Stack Playbook
In this step, you will run the playbook. Package installation can take longer than file-only labs because it uses the RHEL package manager.
cd /home/labex/project/rhce-ansible
ansible-playbook playbooks/web-stack.yml | tee reports/web-stack-first.txt
The first run may take longer while dnf installs httpd. Read the recap after it finishes, then use the RHEL tools below to confirm the live system state, not just the playbook output.
rpm -q httpd
rpm -q should print the installed httpd package name and version.
systemctl is-active httpd
The service should report active, which confirms the web service is running right now.
sudo firewall-cmd --list-services | tr " " "
" | grep -Fx http
This checks the active firewalld services and looks for exactly http. Opening the firewall is a separate state from installing and starting the service.
Run Again to Confirm Idempotence
In this step, you will run the same playbook again. Once the package, service, and firewall are already correct, the recap should report no changes.
cd /home/labex/project/rhce-ansible
ansible-playbook playbooks/web-stack.yml | tee reports/web-stack-second.txt
The second run should be faster and should not need to repair anything. This is the idempotence check for the combined package, service, and firewall workflow.
grep -E 'host.*changed=0' reports/web-stack-second.txt
Summary
You installed a package, managed a service, opened the firewall, verified the RHEL system state, and proved the playbook converges on a second run.


