You are on page 1of 12

EX294

Q#1: Install and configure Ansible


Install and configure Ansible on the control node named workstation.lab.example.com as described below:

Install required packages.Create a static manifest file named /home/devops/ansible/inventory to meet the following
requirements:
 node1 is a member of the dev host group
 node2 is a member of the test host group
 node3 and node4 are members of the prod host group
 node5 is a member of the balancers host group
 The prod group is a member of the webservers host group

Create a configuration file named /home/devops/ansible/ansible.cfg to meet the following requirements:


 The host manifest file is /home/devops/ansible/inventory
 The locations of the characters used in the playbook include /home/devop/ansible/roles.

Solution:

sudo yum install -y ansible


mkdir -p /home/devops/ansible/roles
cd /home/devops/ansible
vim /home/devops/ansible/inventory
[dev]
servera.lab.example.com
[test]
servera.lab.example.com
[prod]
serverc.lab.example.com
[balancers]
serverd.lab.example.com
[webservers:children]
prod
vim ansible.cfg
[defaults]
inventory = /home/devops/ansible/inventory
roles_path = /home/devops/ansible/roles:/usr/share/ansible/roles
remote_user = devops
vault_password_file=/home/devops/ansible/secret.txt
[privilege_escalation]
become=True
become_method=sudo
become_user=root
become_ask_pass=False
Q#2: Create and run temporary Ansible commands
As a system administrator, you need to install software on the managed nodes.
As described in the text, create a shell script named /home/devops/ansible/adhoc.sh , which will use the ansible
temporary command to install the yum repository on each managed:

Repository 1:
 The name of the repository is EX294_BASE
 Described as EX294 base software
 The base URL is http://content.example.com/rhel8.0/x86_64/dvd/BaseOS
 GPG signature check is enabled
 The GPG key URL is http://content.example.com/rhel8.0/x86_64/dvdRPM-GPG-KEY-redhat-release
 The repository is enabled

Repository 2:
 The name of the repository is EX294_STREAM
 Described as EX294 stream software
 The base URL is http://content.example.com/rhel8.0/x86_64/dvd/AppStream
 GPG signature check is enabled
 The GPG key URL is http://content.example.com/rhel8.0/x86_64/dvd/RPM-GPG-KEY-redhat-release
 The repository is enabled

Solution:

vim /home/devops/ansible/adhoc.sh
#!/bin/bash
ansible all -m yum_repository -a \
'name="EX294_BASE" \
description="EX294 base software" \
baseurl="http://content.example.com/rhel8.0/x86_64/dvd/BaseOS" \
gpgcheck=yes \
gpgkey="http://content.example.com/rhel8.0/x86_64/dvd/RPM-GPG-KEY-redhat-release" \
enabled=yes'

ansible all -m yum_repository -a \


'name="EX294_STREAM" \
description="EX294 stream software" \
baseurl="http://content.example.com/rhel8.0/x86_64/dvd/AppStream" \
gpgcheck=yes \
gpgkey="http://content.example.com/rhel8.0/x86_64/dvd/RPM-GPG-KEY-redhat-release" \
enabled=yes'
chmod +x /home/devops/ansible/adhoc.sh
source /home/devops/ansible/adhoc.sh

Q#3: Install packages


Create a playbook named /home/devops/ansible/packages.yml:
 Install php and mariadb packages to hosts in dev, test, and prod host groups
 Install the RPM Development Tools package group on the host in the dev host group
 Update all packages on the hosts in the dev host group to the latest version
Solution:

vim /home/devops/ansible/packages.yml
--
- name: Install packages
hosts: dev,test,prod
tasks:
- name: Install the latest version
yum:
name: "{{ item }}"
state: latest
loop:
- php
- mariadb
- name: Install the '@RPM Development Tools' package group
yum:
name: "@RPM Development Tools"
state: present
when: "'dev' in group_names"
- name: Upgrade all packages
yum:
name: '*'
state: latest
when: "'dev' in group_names"

ansible-playbook --syntax-check /home/devops/ansible/packages.yml
ansible-playbook /home/devops/ansible/packages.yml

Q#4: Use RHEL system roles


Install the RHEL system role package and create a playbook /home/devops/ansible/timesync.yml that meets the
following
conditions:
 Run on all managed nodes
 Use timesync role
 Configure this role to use the currently active NTP provider
 Configure this role to use the time server 172.25.254.254
 Configure the role to enable iburst parameters

Solution:

sudo yum -y install rhel-system-roles


vim /home/devops/ansible/vim ansible.cfg
roles_path= /home/devops/ansible/roles:/usr/share/ansible/roles
ansible-galaxy list
vim /home/devops/ansible/timesync.yml
---
- hosts: all
vars:
timesync_ntp_servers:
- hostname: 172.25.254.254
iburst: yes
roles:
- rhel-system-roles.timesync

ansible-playbook --syntax-check /home/devops/ansible/timesync.yml
ansible-playbook /home/devops/ansible/timesync.yml

Q#5: Create a role and use it


Create a role named apache in /home/devops/ansible/roles according to the following requirements:
 httpd package is installed, set to enable and start at system startup
 The firewall is enabled and running, and uses rules that allow access to the web server
 The template file index.html.j2 already exists and is used to create the file /var/www/html/index.html with the
following output:
Welcome to HOSTNAME on IPADDRESS where HOSTNAME is the fully qualified domain name of the
managed node and IPADDRESS is The IP address of the management node.
• Create playbook /home/devops/ansible/apache.yml, using the role of apache, in the webservers host group.

Solution:

cd /home/devops/ansible/roles
ansible-galaxy init apache
cd /home/devops/ansible
ansible-galaxy list
vim /home/devops/ansible/roles/apache/tasks/main.yml
---
# tasks file for apache
- name: install the latest version of Apache
yum:
name: httpd
state: latest
- name: Start service httpd, if not started
service:
name: httpd
state: started
enabled: yes
- name: Allow access to httpd
firewalld:
service: http
permanent: yes
state: enabled
immediate: yes
- name: Template a file
template:
src: index.html.j2
dest: /var/www/html/index.html

vim /home/devops/ansible/roles/apache/templates/index.html.j2
Welcome to {{ ansible_fqdn }} on {{ ansible_default_ipv4.address }}
vim /home/devops/ansible/apache.yml

---
- name: Use role apache
hosts: webservers
roles:
- apache
ansible-playbook --syntax-check /home/devops/ansible/apache.yml
ansible-playbook /home/devops/ansible/apache.yml

Q#6: Generate hosts file


Download an initial template file from http://materials.example.com/hosts.j2 to /home/devops/ansible
Complete the template so that it can be used to generate the following files: for each inventory host, there is a line of
content in the same format as /etc/hosts.
Create a playbook named /home/devops/ansible/hosts.yml, which will use this template to generate the file
/etc/myhosts on the hosts in the dev host group.
After the playbook runs, the file /etc/myhosts on the hosts in the dev host group should contain a line for each
managed host:
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6

172.25.250.10 node1.lab.example.com node1


172.25.250.11 node2.lab.example.com node2
172.25.250.12 node3.lab.example.com node3
172.25.250.13 node4.lab.example.com node4
172.25.250.14 node5.lab.example.com node5
Note: The display order of the list host names is not important.
Solution:

cd /home/devops/ansible
wget http://materials.example.com/hosts.j2
vim /home/devops/ansible/hosts.j2
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain

{% for host in groups['all'] %}


{{ hostvars[host]['ansible_facts']['default_ipv4']['address']}} {{ hostvars[host]['ansible_facts']['fqdn'] }} {{
hostvars[host]
['ansible_facts']['hostname'] }}
{% endfor %}

vim /home/devops/ansible/hosts.yml
---
- name: Generating hosts file
hosts: all
tasks:
- name: Template a file to /etc/myhosts
template:
src: /home/devops/ansible/hosts.j2
dest: /etc/myhosts
when: '"dev" in group_names'

ansible-playbook --syntax-check /home/devops/ansible/hosts.yml
ansible-playbook /home/devops/ansible/hosts.yml
ansible dev -m command -a ‘cat /etc/myhosts’
Q#7: Modify file content
Create a playbook named /home/devops/ansible/issue.yml as described below:
• The playbook will run on all inventory hosts
• The playbook will replace the contents of /etc/issue with the line of text shown below:
◦ On hosts in the dev hostgroup, this line of text reads: Development
◦ On the hosts in the test hostgroup, this line of text is displayed as: Test
◦ On the hosts in the prod hostgroup, this line of text reads: Production

Solution

cd /home/devops/ansible
vim /home/devops/ansible/issue.yml
---
- name: Modifying content as required
hosts: all
tasks:
- name: Copy content for dev hostgroup
copy:
content: 'Development'
dest: /etc/issue
when: "inventory_hostname in groups.dev"
- name: Copy content for test hostgroup
copy:
content: 'Test'
dest: /etc/issue
when: "inventory_hostname in groups.test"
- name: Copy content for prod hostgroup
copy:
content: 'Production'
dest: /etc/issue
when: "inventory_hostname in groups.prod"

ansible-playbook --syntax-check /home/devops/ansible/issue.yml
ansible-playbook /home/devops/ansible/issue.yml
ansible dev,test,prod -m command -a 'cat /etc/issue'

Q#8: Create a web content directory


Create a playbook named /home/devops/ansible/webcontent.yml as described below:
This playbook runs on the managed node in the dev hostgroup
• Create a directory /webdev that meets the following requirements:
◦ Owner is webdev group
• Permission overview:
◦ owner=read+write+execute , group=read+write+execute ,others=read+execute
• With special permissions: set group ID
• Use symbolic links to link /var/www/html/webdev to /webdev
• Create the file /webdev/index.html, which contains the single-line file shown below:
◦ Development
• Browsing this directory on a host in the dev host group (for example, http://servera.lab.example.com/webdev/) will
produce the following output:
◦ Development
Solution:

cd /home/devops/ansible
vim /home/devops/ansible/webcontent.yml
---
- name: Creating web content directory
hosts: dev
tasks:
- name: Creating group webdev
group:
name: webdev
- name: Create a directory if it does not exist
file:
path: /webdev
state: directory
group: webdev
mode: '2775'
- name: Create a symbolic link
file:
src: /webdev
dest: /var/www/html/webdev
state: link
- name: Copy using inline content
copy:
content: “Development \n”
dest: /webdev/index.html
setype: httpd_sys_content_t

ansible-playbook --syntax-check /home/devops/ansible/webcontent.yml
ansible-playbook /home/devops/ansible/webcontent.yml
curl http://servera.lab.example.com/webdev/

Q#9: Generate hardware report


Create a playbook named /home/devops/ansible/hwreport.yml, which will generate an output file /root/hwreport.txt
with the
following information on all
managed nodes:
• List host name
• Total memory size in MB
• BIOS version
• The size of the disk device vda
• The size of the disk device vdb
• Each line in the output file contains a key=value pair. Your playbook should:
• Download the file from http://content.example.com/materials/hwreport.empty and save it as /root/hwreport.txt
• Use the correct value to change to /root/hwreport.txt
• If the hardware item does not exist, the relevant value should be set to NONE

Solution:

cd /home/devops/ansible
vim /home/devops/ansible/hwreport.yml
---
- name: Generating hardware report accordinly
hosts: all
vars:
hw_all:
- hw_name: HOSTNAME
hw_cont: "{{ inventory_hostname | default('NONE', true) }}"
- hw_name: MEMORY
hw_cont: "{{ ansible_memtotal_mb | default('NONE', true) }}"
- hw_name: BIOS_VERSION
hw_cont: "{{ ansible_bios_version | default('NONE', true) }}"
- hw_name: DISK_SIZE_VDA
hw_cont: "{{ ansible_devices.vda.size | default('NONE', true) }}"
- hw_name: DISK_SIZE_VDB
hw_cont: "{{ ansible_devices.vdb.size | default('NONE', true) }}"
tasks:
- name: Downloading empty hwreport file from materils
get_url:
url: http://materials.example.com/hwreport.empty
dest: /root/hwreport.txt
- name: Update hwreport as required
lineinfile:
path: /root/hwreport.txt
regexp: "^{{ item.hw_name }}="
line: "{{ item.hw_name }}={{ item.hw_cont }}"
loop: "{{ hw_all }}"

ansible-playbook --syntax-check /home/devops/ansible/hwreport.yml
ansible-playbook /home/devops/ansible/hwreport.yml
ansible all -m command -a 'cat /root/hwreport.txt'

Q#10: Create a password store


Create an Ansible library to store user passwords as described below:
• The library name is /home/devops/ansible/locker.yml
• The library contains two variables with the following names:
• pw_developer, value is Imadev
• pw_manager, the value is Imamgr
• The password used to encrypt and decrypt the library is ratankot
• The password is stored in the file /home/devops/ansible/secret.txt

Solution:

vim /home/devops/ansible/ansible.cfg
vault_password_file = /home/devops/ansible/secret.txt
vim /home/devops/ansible/locker.yml
---
pw_developer: Imadev
pw_manager: Imamgr
...
echo ratankot > /home/devops/ansible/secret.txt
ansible-vault encrypt /home/devops/ansible/locker.yml
Q#11: Create user accounts
Download the list of users to be created from http://materials.example.com.com/user_list.yml and save it to
/home/devops/ansible
In this exam, use the password library /home/devops/ansible/locker.yml created in another location. Create a
playbook
named /home/devops/ansible/users.yml to create user accounts as follows:
• Users whose job description is developer should:
◦ Create on managed nodes in the dev and test hostgroup
◦ Assign a password from the pw_developer variable
◦ User should be a member of the supplementary group devops
• Users whose job description is manager should:
◦ Create on the managed node in the prod hostgroup
◦ Assign a password from the pw_manager variable
◦ User shoud be a member of the supplementary group opsmgr
• The password is in SHA512 hash format.
• Your playbook should be able to use the library password file /home/devops/ansible/secret.txt created elsewhere in
this exam to run normally.

Solution:

cd /home/devops/ansible
wget http://materials.example.com./user_list.yml
cat / home/devops/ansible/user_list.yml
vim /home/devops/ansible/users.yml
---
- name: Creating users using variables
hosts: all
vars_files:
- /home/devops/ansible/locker.yml
- /home/devops/ansible/user_list.yml
tasks:
- name: Ensuring devops group is present
group:
name: devops
when: “’dev’ in group_names or ‘test’ in group_names”
- name: Adding users with developer group
user:
name: "{{ item.username }}"
password: "{{ pw_developer | password_hash('sha512', 'mysecretsalt') }}"
groups: devops
loop: "{{ users }}"
when: item.comment == "developer" and (inventory_hostname in groups.dev or inventory_hostname in groups.test)
- name: Ensure opsmgr group is present
group:
name: opsmgr
when: “’prod’ in group_names”
- name: Adding users for manager group
user:
name: "{{ item.username }}"
password: "{{ pw_manager | password_hash('sha512', 'mysecretsalt') }}"
groups: opsmgr
loop: "{{ users }}"
when: item.comment == "manager" and inventory_hostname in groups.prod

ansible-playbook --syntax-check /home/devops/ansible/users.yml
ansible-playbook /home/devops/ansible/users.yml
ansible dev,test -m command -a 'id alice'
ansible dev,test -m command -a 'id vincent'
ansible prod -m command -a 'tail /etc/passwd'
ssh patrick@serverc
ssh alice@servera

Q#12: Update the key of Ansible library


Update the key of the existing Ansible library as described below:
Download the Ansible library from http://content.example.com/salaries.yml to /home/devops/ansible
• The current library password is 111
• The new library password is 123
• The library remains encrypted with the new password.

Solution:

cd /home/devops/ansible
wget http://materials.example.com/salaries.yml
ansible-vault rekey --ask-vault-pass salaries.yml
ansible-vault view salaries.yml

Q#13: Create and use logical volumes


Create a playbook named /home/devops/ansible/lv.yml, which will run on all managed nodes to perform the
following
tasks:
Create a logical volume that meets the following requirements:
 The logical volume is created in the research volume group
 The logical volume name is data
 The logical volume size is 1500 MiB
 Use the ext4 file system to format logical volumes
 If the requested logical volume size cannot be created, the error message Could not create logical volume of that
size should be displayed and the size 800 MiB should be used instead.
 If the volume group research does not exist, the error message Volume group done not exist should be displayed .
 Do not mount logical volumes in any way.

Solution:

---
- name: Create and use logical volumes
hosts: all
tasks:
- block:
- name: Create a logical volume of 1500m
lvol:
vg: research
lv: data
size: 1500
- name: Use ext4 file system to format logical volumes
filesystem:
fstype: ext4
device: /dev/research/data
rescue:
- name: Display error message
debug:
msg: Could not create logical volume of that size
- name: Create logical volume of 800m
lvol:
vg: research
lv: data
size: 800
when: ansible_lvm['vgs']['research'] is defined
ignore_errors: yes
- name: Use ext4 file system to format logical volumes
filesystem:
fstype: ext4
device: /dev/research/data
when: ansible_lvm['lvs']['data'] is defined
ignore_errors: yes
always:
- name: Display error message
debug:
msg: Volume group does not exist
when: ansible_lvm['vgs']['research'] is undefined
...

Q#14 Install roles using ansible galaxy


Download and install ansible galaxy role into the /home/devops/ansible/roles directory using requirement.yml.
 http://classroom.example.com/content/courses/EX294/ansible2.8/materials/EX294/haproxy.tar role name
as balancer.
 http://classroom.example.com/content/courses/EX294/ansible2.8/materials/EX294/phpinfo.tar role name as
phpinfo.

Solution:

vim /home/devops/ansible/roles/requirement.yml
---
- src: http://classroom.example.com/content/courses/EX294/ansible2.8/materials/EX294/haproxy.tar
name: balancer
- src: http://classroom.example.com/content/courses/EX294/ansible2.8/materials/EX294/phpinfo.tar
name: phpinfo
ansible-galaxy install -r roles/requirement.yml -p roles
ansible-galaxy list

Q#15 Use ansible galaxy roles.


Create a playbook named /home/devops/ansible/roles.yml, according to the following requirements:
 Playbook runs on hosts in balancers host group and will use balancer role.
 This role configures a service to balance the load of web server requests among hosts in the webserver host
group.
 Browsing the host in balancer host group (eg: http://node5.example.com/) will produce following output:
 Welcome to node3.example.com to 172.24.22.8
Reloading the browser will generate the output of other server.
Welcome to node4.example.com to 172.24.22.9
 The play book contains a play that run on hosts in the webserver host group will use role phpinfo role.
 Browsing the webservers hosts it shows the following output:
Hello PHP world from node3.example.com
Hello PHP world from node4.example.com

Solution:

vim /home/devops/ansible/roles.yml
---
- name: Install the balancer role
hosts: balancers
vars:
webservers:
- id: node3.example.com
host: 172.24.22.8
- id: node4.example.com
host: 172.24.22.9
roles:
- balancer
- name: Install the phpinfo role
hosts: webservers
roles:
- phpinfo
….

You might also like