RHCE Mock Exam 3

Third full mock exam. Note that `node2` is in two groups (test and balancers). The control node is bare and the managed nodes are freshly installed (`devops` / `devops` only). Provided: `~/ansible/user_list.yml`, `~/ansible/hosts.j2` and the vault file `~/ansible/bonus.yml`. Exam rules (as on EX294): 4 hours; you work as `student` on control; every playbook lives in `/home/student/ansible` and must run with `ansible-navigator run` (or ansible-playbook) from there; the nodes are only managed through Ansible after the initial access setup (root password on the nodes: `redhat`, the `devops` password is `devops`); docs are local only (`ansible-doc`, `ansible-navigator doc`, `/usr/share/doc/rhel-system-roles`). Tasks are marked on the end state of the nodes and files, and the grader re-runs your playbooks, so they must be idempotent. Lab notes: web nodes run SELinux permissive at runtime here; collection tarballs are at `http://utility/collections/`, role tarballs at `http://utility/roles/`.

Tasks

  1. Install and configure Ansible on control. ansible-navigator is installed. Create ~/ansible/inventory with the groups: dev = node1; test = node2; prod = node3, node4; balancers = node2; and webservers whose child group is prod. Create ~/ansible/ansible.cfg: that inventory, remote user devops, privilege escalation with sudo by default (no password prompt), roles path ~/ansible/roles (plus /usr/share/ansible/roles), collections path ~/ansible/collections (plus /usr/share/ansible/collections). Create ~/ansible/ansible-navigator.yml using the image utility.lab.example.com/ee-supported-rhel10:latest, pull policy never, mode stdout.
  2. Generate an SSH key pair for student and copy it to devops on all four nodes; on every node devops may run any command with sudo without a password (file in /etc/sudoers.d). ansible all -m ping must succeed.
  3. Create the executable shell script ~/ansible/adhoc.sh that uses ad-hoc Ansible commands (module yumrepository) to configure two repositories on all managed nodes, then run it: - rhelbase: description RHEL 10 BaseOS, baseurl https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi10/10/x8664/baseos/os - rhelapps: description RHEL 10 AppStream, baseurl https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi10/10/x8664/appstream/os Both with GPG checking enabled, gpgkey file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release, and enabled.
  4. Create ~/ansible/collections/requirements.yml that installs these collections from http://utility/collections/ and install them into ~/ansible/collections: ansible.posix, community.general, containers.podman.
  5. Create ~/ansible/roles/requirements.yml and use it to install into ~/ansible/roles: the role http://utility/roles/frontend.tar.gz under the name frontend, and http://utility/roles/phpstatus.tar.gz under the name phpstatus.
  6. Create your own role httpdsite in ~/ansible/roles: it installs and starts (and enables) httpd and firewalld, allows the http service in firewalld (permanent and running), and deploys /var/www/html/index.html from a template with the content node3.lab.example.com - 172.18.0.5 - WebAsha. Apply it to the webservers group with ~/ansible/site.yml.
  7. Write ~/ansible/site-roles.yml that applies the installed roles: phpstatus on webservers and frontend on balancers. Afterwards curl http://node2/status.php from control must show PHP status page on <a webserver followed by the PHP info page.
  8. Write ~/ansible/time.yml that uses the RHEL system role redhat.rhelsystemroles.timesync so that all managed nodes synchronise time with utility.lab.example.com using iburst.
  9. Write ~/ansible/pkgs.yml: install nmap-ncat on dev; install vsftpd on test; install tmux on prod — only on those groups.
  10. Write ~/ansible/lvm.yml for all nodes: create the logical volume archive of 1500 MiB in volume group storage. If the VG is too small, print Could not create a logical volume of that size and create it with 500 MiB instead. If the VG does not exist, print Volume group does not exist. Format the LV with xfs. Do not create anything on hosts without the VG.
  11. Complete the provided template ~/ansible/hosts.j2 (keep its first lines) so that it adds one line per managed node: <IPv4 address <FQDN <short hostname. Write ~/ansible/hosts.yml that generates /etc/myhosts from it on the prod hosts only.
  12. Write ~/ansible/motd.yml that replaces the content of /etc/motd: on dev with Dev box, on test with QA box, on prod with Production server (single line each).
  13. Write ~/ansible/content.yml for dev and test: group contentteam; directory /content owned by group contentteam with mode 2775 (setgid); /content/index.html containing Shared content; a symbolic link /var/www/html/content → /content; the SELinux type httpdsyscontentt on the directory and its content, persistently.
  14. Write ~/ansible/report.yml that downloads http://utility/report.empty to /root/report.txt on all nodes and fills in each line: HOST = inventory hostname, MEMORY = total memory in MB, VCPUS = number of vCPUs, BIOS = BIOS version, DISKSIZEVDB = size of disk vdb. Use NONE for any value a host does not have (e.g. a missing disk).
  15. Create the vault password file ~/ansible/vault.pass containing exam294pass and the vault-encrypted ~/ansible/secrets.yml defining developerpw: Develop2026 and managerpw: Manage2026. Write ~/ansible/people.yml using the provided ~/ansible/userlist.yml: users whose job is developer exist on dev and test with their uid, supplementary group developers and password developerpw; users whose job is manager exist on prod with group admins and password managerpw. Passwords are SHA-512 hashes.
  16. Rekey the provided vault file ~/ansible/bonus.yml (current password bonus-old) to the new password BonusNew2026.
  17. Write ~/ansible/jobs.yml: on dev and test, a cron job named daily check for user devops that runs logger "WebAsha daily" every day at 09:00. Nothing on prod.
  18. Make sure your playbooks are idempotent: running motd.yml and content.yml again must report changed=0 and no failures. (The grader re-runs every playbook.)