RHCE Mock Exam 2
Second full mock exam, different layout and values. 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/payroll.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
- Install and configure Ansible on control. ansible-navigator is installed. Create ~/ansible/inventory with the groups: dev = node2; test = node1; prod = node4; balancers = node3; 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.
- 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.
- Create the executable shell script ~/ansible/yum-repos.sh that uses ad-hoc Ansible commands (module yumrepository) to configure two repositories on all managed nodes, then run it: - BaseOS: description Base OS packages, baseurl https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi10/10/x8664/baseos/os - AppStream: description Application Stream packages, 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.
- Create ~/ansible/collections/requirements.yml that installs these collections from http://utility/collections/ and install them into ~/ansible/collections: ansible.posix, community.general, community.crypto.
- Create ~/ansible/roles/requirements.yml and use it to install into ~/ansible/roles: the role http://utility/roles/haproxy-lb.tar.gz under the name loadbalancer, and http://utility/roles/php-site.tar.gz under the name phpsite.
- Create your own role webserver 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 Served by node4.lab.example.com (172.18.0.6). Apply it to the webservers group with ~/ansible/webserver.yml.
- Write ~/ansible/lb.yml that applies the installed roles: phpsite on webservers and loadbalancer on balancers. Afterwards curl http://node3/info.php from control must show PHP site running on <a webserver followed by the PHP info page.
- Write ~/ansible/ntp.yml that uses the RHEL system role redhat.rhelsystemroles.timesync so that all managed nodes synchronise time with utility.lab.example.com using iburst.
- Write ~/ansible/software.yml: install vsftpd on dev; install tmux on test; install zsh and nmap-ncat on prod — only on those groups.
- Write ~/ansible/storage.yml for all nodes: create the logical volume backup of 1200 MiB in volume group vgdata. If the VG is too small, print Could not create a logical volume of that size and create it with 700 MiB instead. If the VG does not exist, print Volume group does not exist. Format the LV with xfs and mount it persistently on /srv/backup. Do not create anything on hosts without the VG.
- 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 test hosts only.
- Write ~/ansible/banner.yml that replaces the content of /etc/issue: on dev with Development environment, on test with Testing environment, on prod with Production environment (single line each).
- Write ~/ansible/webtest.yml for test: group webtest; directory /webtest owned by group webtest with mode 2775 (setgid); /webtest/index.html containing Testing; a symbolic link /var/www/html/webtest → /webtest; the SELinux type httpdsyscontentt on the directory and its content, persistently.
- Write ~/ansible/hardware.yml that downloads http://utility/hardware.empty to /root/hardware.txt on all nodes and fills in each line: HOSTNAME = inventory hostname, MEMORYMB = total memory in MB, CPUCOUNT = number of vCPUs, BIOSVERSION = BIOS version, VDBSIZE = size of disk vdb. Use NONE for any value a host does not have (e.g. a missing disk).
- Create the vault password file ~/ansible/vaultpass.txt containing redhat294vault and the vault-encrypted ~/ansible/passwords.yml defining devpw: DevPass294 and mgrpw: MgrPass294. Write ~/ansible/accounts.yml using the provided ~/ansible/userlist.yml: users whose job is developer exist on dev and test with their uid, supplementary group devs and password devpw; users whose job is manager exist on prod with group managers and password mgrpw. Passwords are SHA-512 hashes.
- Rekey the provided vault file ~/ansible/payroll.yml (current password payroll2025) to the new password Payroll2026new.
- Write ~/ansible/schedule.yml: on prod only, a root cron job named nightly report that runs logger "nightly report" at 02:30 Monday to Friday.
- Make sure your playbooks are idempotent: running banner.yml and webtest.yml again must report changed=0 and no failures. (The grader re-runs every playbook.)