EX294 Sample exam #1
Notice: Ansible is installed as the root
user, so please work on all tasks after elevating to the root
user.
This lab is similar to the one you’ll face in the actual RHCE exam. While the tasks here are not identical, many of the skills practiced here will be used in that exam. This final review will launch 4 servers: Host, WebServer1, DBServer1, and AdminServer1. As there’s no DNS in this environment, /etc/hosts
has been configured for you. References to “all servers” don’t include the Ansible host. The ansible
user's password is the same as the one for cloud_user
.
These are the twelve tasks you'll need to complete in order to prepare for the exam:
- Set up an Ansible inventory.
- Set up SSH keys.
- Set up sudoers.
- Write a playbook to install
httpd
only onWebServer1
. Make sure the service is started and enabled. - Use an ad-hoc command to install tcpdump on AdminServer1
- Use the
LVM
module in a playbook to set up the disk attached toDBServer1
(/dev/xvdg
), then make sure it's formatted with XFS and mounted persistently on/mnt/dbdata
. The disk's size should be 10G. - Create the users
adam
,john
,sara
, andsam
on all servers. - Write a Bash script that queries each server for its Ansible facts, and outputs that information to a file in
/tmp
; there should be one file for each server name. - Using the
ssh.tmpl
sample file in/root
on the Ansible Host to write a template and playbook that will deploy the file on all hosts in the environment. It should turn off Password Authentication on all servers, and ensure X11 forwarding is on for administrative servers only. - Create two custom roles:
web
anddatabase
. - In the
database
role, create a password file that will be copied into thedba
user's home directory. Encrypt the file. Ensure thedatabase
role is deployed correctly. - For the
web
role, ensure that/var/www/html/index.html
contains the Ansible hostname of the server and all IP addresses connected to that server. Ensure thathttpd
is running and enabled, and that the role deploys correctly.
Ok, ready? Here we go.
Learning Objectives
check_circle
Set up /etc/ansible/hosts
keyboard_arrow_up
Our inventory file should look something like this:
[dbservers] dbserver1 [webservers] webserver1 [admins] adminserver1
check_circle
Set up SSH Keys
keyboard_arrow_up
First you need to generate a key with:
ssh-keygen
Then you can copy it over to webserver1
with the command:
ssh-copy-id ansible@webserver1
Repeat this with the other two servers, using the cloud_user
password for the ansible
user.
check_circle
Set up sudoers
keyboard_arrow_up
Log into webserver1
as cloud_user
:
cloud_user@webserver1
Now run sudo visudo
and add the following line to the end of the file:
ansible ALL=(ALL) NOPASSWD: ALL
Run exit
to get out of this server, and then repeat the process for dbserver1
and adminserver1
.
Once that's done, test with:
ssh ansible@webserver1
Once you're in, try a sudo
command:
sudo tail /var/log/messages
Then get out with exit
again, and get ready for the next task.
check_circle
Write a Playbook to Install httpd, but Only on Web Servers
keyboard_arrow_up
Your playbook, httpd.yml
, should look something like this:
--- - name: Install httpd on webservers hosts: webservers # This encompasses everything in the webservers group. # We can also just have a single host name here, like webserver1. become: yes tasks: - yum: name: httpd state: present - service: name: httpd state: started enabled: yes
check_circle
Use an Ad hoc Command to Install tcpdump on AdminServer1
keyboard_arrow_up
The simplest ad-hoc command here would be:
ansible -m yum -a "name=tcpdump state=present" adminserver1 --become
check_circle
Use the LVM Module in a Playbook to Set up the Disk Attached to DBServer1
keyboard_arrow_up
Your playbook, disk.yml
, should look similar to the following:
--- - name: lvol hosts: dbservers # This encompasses everything in the dbservers group. # We can also just have a single host name here, like dbserver1. become: yes tasks: - name: LVG create lvg: vg: RHCE pvs: /dev/xvdg - name: Logical Volume Setup lvol: lv: AppDB2 vg: RHCE size: 10G pvs: /dev/xvdg state: present - name: Format the disk filesystem: dev: /dev/RHCE/AppDB2 fstype: xfs - name: Mount the disk mount: fstype: xfs src: /dev/RHCE/AppDB2 state: mounted path: /mnt/dbdata
Now run it with ansible-playbook disk.yml
check_circle
Create the Users adam, john, sara, and sam on All Servers
keyboard_arrow_up
There are a lot of ways to tackle this problem. One method is to use with_items
. Create and edit users.yml
:
--- - name: Create Users hosts: all become: yes tasks: - name: Create users user: name: "{{ item }}" with_items: - adam - john - sara - sam
Now run it with ansible-playbook users.yml
check_circle
Write a Bash Script That Will Collect the Required Ansible Information
keyboard_arrow_up
We want to get each host's Ansible facts and dump the information into respective text files. So you've got to write a script, facts.sh
, that will query each one and put its relevant info into a text file. The script should look something like the following:
#!/bin/bash for i in webserver1 dbserver1 adminserver1 do ansible -m setup $i > /tmp/$i\_facts done
Make the script executable (chmod +x facts.sh
) and run it with ./facts.sh
. Now, to check, run ls /tmp
, which should show a file that corresponds to each of those three hosts.
check_circle
Create an SSH Configuration File and Distribute It
keyboard_arrow_up
Edit the ssh.tmpl
file sitting in /root
and alter the two relevant lines (starting with PasswordAuthentication
and X11Forwarding
). There are a few lines separating them. They should look similar to this:
PasswordAuthentication {{ PAanswer }} X11Forwarding {{ X11Answer }}
And the playbook, ssh.yml
, to apply the template should look like this:
--- - name: Review Task 9 hosts: all:!admins become: yes vars: PAanswer: "no" X11Answer: "no" tasks: - name: Apply Template template: src: /root/ssh.tmpl dest: /etc/ssh/sshd_config validate: /sbin/sshd -t -f %s - name: Restart SSHD service: name: sshd state: restarted - name: Review Task 9b hosts: admins become: yes vars: PAanswer: "no" X11Answer: "yes" tasks: - name: Apply template template: src: /root/ssh.tmpl dest: /etc/ssh/sshd_config validate: /sbin/sshd -t -f %s - name: Restart SSHD service: name: sshd state: restarted
Now run it with ansible-playbook ssh.yml
.
check_circle
Create the Two Roles
keyboard_arrow_up
The commands to create custom roles are:
ansible-galaxy init web ansible-galaxy init database
check_circle
Configure the database Role and Encrypt the Password File
keyboard_arrow_up
First, get into the files
subdirectory of the database
directory:
cd database/files
Create a password
file that contains the following:
This is a password
Encrypt it with this:
ansible-vault encrypt password
Enter a password that you won't forget. To check your work, run cat password
and make sure that the file is in fact encrypted.
Now get into the tasks
directory:
cd ../tasks
Edit main.yml
. It should look like this when you're done:
--- # tasks file for database - name: Ensure user is created user: name: dba - name: Copy password file copy: src: password dest: /home/dba
Now go back to your home directory (with cd
) and create db.yml
. It should look like this when you're done:
--- - hosts: dbservers roles: - database
Now run it with ansible-playbook db.yml --become --ask-vault-pass
. Enter the password you set in the ansible-vault encrypt password
command you ran earlier, and this should work.
check_circle
Configure the web Role and Ensure It Deploys Correctly
keyboard_arrow_up
Get into the web
directory (cd web
), then edit tasks.yml
. It should look like this when we're finished:
--- # tasks file for web # - name: Populate index.html lineinfile: path: /var/www/html/index.html create: yes line: "{{ inventory_hostname }} {{ansible_facts['all_ipv4_addresses'] }}" - name: Install httpd yum: name: httpd state: present - name: Start httpd service: name: httpd state: started enabled: yes
Now go back to your home directory (with cd
) and write a quick role deployment routine (web.yml
). It should look like this:
--- - hosts: webservers roles: - web
Run the playbook with ansible-playbook web.yml --become
. To test if it all went well, run curl webserver1
. We should get back the name of the server and relevant IP addresses (what we asked for in the ansible_facts['all_ipv4_addresses
part of the web/tasks.yml
playbook.