TT Lab
Get started
Learn Learning paths Courses

RHEL-Family Administration

Actually Change RHEL With Ansible

Continue in TT Lab

This lab runs on a real RHEL-family system

AlmaLinux 9 is running inside the VM. systemd runs as PID 1, SELinux is Enforcing, and firewalld is alive. Playbooks really change the system, and the grader reads the result directly from the system.

The earlier Ansible course ran in a Pod and went only as far as syntax checking. Here, if you do not configure it, it really gets blocked.

It takes about 2 minutes to start.

Goal

You go once around what the RHCE exam really asks. Users, services, SELinux, the firewall, templates, and idempotence.

Why it matters

The RHCE (EX294) does not ask "do you know Ansible syntax". It asks whether you can bring a system into the desired state. So most of the points lost come not from syntax but from things like these.

The last one is especially important. A playbook that is not idempotent is a playbook that changes something every time you run it. Then you cannot know "what did this run change", and the handler restarts the service every time, causing unnecessary interruptions.

Steps

  1. In /root/rhce/inventory.ini, put this host in a [webservers] group, and also create /root/rhce/ansible.cfg. ansible webservers -m ping must succeed.
  2. With /root/rhce/users.yml, create a webadmin group and users alice and bob (shell /bin/bash, supplementary group webadmin). Use a loop.
  3. With /root/rhce/service.yml, install httpd and satisfy both started and enabled. curl http://127.0.0.1/ must be 200.
  4. With /root/rhce/selinux.yml, turn on the httpd_can_network_connect boolean permanently and attach the httpd_sys_content_t context to /srv/web.
  5. With /root/rhce/firewall.yml, open the http service in the firewall. It must satisfy both runtime and permanent.
  6. Make a page that includes the hostname with /root/rhce/templates/index.html.j2 and deploy it with /root/rhce/template.yml. Use a handler that restarts httpd only when something changes.
  7. Create /root/rhce/site.yml, which calls all of the above. Then deliberately disturb the state (stop the service, delete a file, delete an account), run it twice, and write the changed counts to /root/rhce/idempotent.txt as changed_first=·changed_second=. The first must be greater than 0 and the second must be 0. If you measure without disturbing, it is 0 from the first run, so you cannot tell "it became 0 because it fixed things" from "it did nothing to begin with".
  8. In /root/rhce/report.md, write three lines, selinux=Enforcing, idempotent=yes, and playbooks=<개수> (playbooks= followed by the number of playbooks), along with an explanation.

Notes

Inventory and configuration file

In /root/rhce/inventory.ini, put this host in a [webservers] group, and also create /root/rhce/ansible.cfg. ansible webservers -m ping must succeed.

You take this VM itself as the target. If you use ansible_connection=local, it works right away without SSH. If you put the inventory path in ansible.cfg, you do not have to give -i every time.

Creating users and groups

With /root/rhce/users.yml, create a webadmin group and users alice and bob (shell /bin/bash, supplementary group webadmin). Use a loop.

Run ansible.builtin.group first, and then ansible.builtin.user with a loop. If you create the users while the group does not exist, it fails.

A service must satisfy two things

With /root/rhce/service.yml, install httpd and satisfy both started and enabled. curl http://127.0.0.1/ must be 200.

state: started is for now and enabled: true is for after a reboot. They are different stories and are what people most often leave out in the exam.

SELinux is on and really blocks

With /root/rhce/selinux.yml, turn on the httpd_can_network_connect boolean permanently and attach the httpd_sys_content_t context to /srv/web.

For the boolean, use persistent: true with ansible.posix.seboolean, and for the file context, use restorecon after community.general.sefcontext.

Runtime and permanent are different

With /root/rhce/firewall.yml, open the http service in the firewall. It must satisfy both runtime and permanent.

permanent: true applies to the configuration file and immediate: true applies to the firewall running now. You have to give both to be complete.

Restart only when something changes

Make a page that includes the hostname with /root/rhce/templates/index.html.j2 and deploy it with /root/rhce/template.yml. Use a handler that restarts httpd only when something changes.

Attach notify to the template task and put the restart in the handlers section. The handler runs only when that task is changed.

The second run must be quiet

Create /root/rhce/site.yml, which calls all of the above. Then deliberately disturb the state (stop the service, delete a file, delete an account), run it twice, and write the changed counts to /root/rhce/idempotent.txt as changed_first=·changed_second=. The first must be greater than 0 and the second must be 0. If you measure without disturbing, it is 0 from the first run, so you cannot tell "it became 0 because it fixed things" from "it did nothing to begin with".

In site.yml, call the earlier playbooks with import_playbook and run it twice. If the second run's changed is not 0, find that task.

What you learned

In /root/rhce/report.md, write three lines, selinux=Enforcing, idempotent=yes, and playbooks=<개수> (playbooks= followed by the number of playbooks), along with an explanation.

Along with the three lines selinux=, idempotent=, and playbooks=, summarize the places where points are lost in the exam.