Optimize the execution of plays and tasks in a playbook by selectively escalating privileges, configuring when tasks run, optimizing it for speed, and adding tags to specify that selected parts of it should run.
Outcomes
Change privilege escalation to a more secure configuration.
Add task hooks and handlers to alter the task behavior.
Tag tasks to control their execution.
As the student user on the workstation machine, use the lab command to prepare your system for this exercise.
This command initializes the remote Git repository that you need for this lab.
When you are ready to push your changes to the remote repository, use Student@123 as the Git password.
[student@workstation ~]$ lab start task-review
Procedure 6.5. Instructions
Clone the https://git.lab.example.com/student/task-review.git repository to the /home/student/git-repos directory and then create the exercise branch.
From a terminal, create the /home/student/git-repos directory if it does not already exist, and then change into it.
[student@workstation ~]$mkdir -p ~/git-repos/[student@workstation ~]$cd ~/git-repos/
Clone the repository and then change to the /home/student/git-repos/task-review/ directory.
[student@workstation git-repos]$git clone \>https://git.lab.example.com/student/task-review.gitCloning into 'task-review'... ...output omitted... [student@workstation git-repos]$cd task-review/
Create the exercise branch and check it out.
[student@workstation task-review]$ git checkout -b exercise
Switched to a new branch 'exercise'Modify the ansible.cfg file so that privilege escalation is disabled by default.
Because all the tasks in the firewall, haproxy, apache, and webapp roles require privilege escalation, enable privilege escalation at the play level in the deploy_apache.yml, deploy_haproxy.yml, and deploy_webapp.yml playbooks.
Edit the ansible.cfg file to remove the become=true entry from the privilege_escalation block, use become=false in the privilege_escalation block, or remove the entire [privilege_escalation] block from the ansible.cfg file.
If you choose the last option, then the file contains the following content:
[defaults] inventory=inventory.yml remote_user=devops
Enable privilege escalation for the play in the deploy_apache.yml playbook.
Add the become: true line to the play.
---
- name: Ensure Apache is deployed
hosts: web_servers
force_handlers: true
gather_facts: false
become: true
roles:
# The "apache" role has a dependency on the "firewall" role.
# The "firewall" role requires the "firewall_rules" variable.
- role: apacheEnable privilege escalation for the play in the deploy_haproxy.yml playbook.
Add the line become: true to the play.
---
- name: Ensure HAProxy is deployed
hosts: lb_servers
force_handlers: true
gather_facts: false
become: true
roles:
# The "haproxy" role has a dependency on the "firewall" role.
# The "firewall" role requires the "firewall_rules" variable.
- role: haproxyEnable privilege escalation for the play in the deploy_webapp.yml playbook.
Add the line become: true to the play.
---
- name: Ensure Web App is deployed
hosts: web_servers
gather_facts: false
become: true
vars:
- webapp_version: v1.0
roles:
- role: webappIn the deploy_haproxy.yml playbook, add a copy task that runs before any other task in the play.
That task must write the text Playbook site.yml ready to start to the /tmp/site.ready file on the servers in the lb_servers group.
Edit the deploy_haproxy.yml file.
In the play in that file, add a pre_tasks block consisting of a copy task that creates a /tmp/site.ready file containing the text Playbook site.yml ready to start.
If desired, then you can add a newline character to the end of the text string.
The modified file contains the following content:
--- - name: Ensure HAProxy is deployed hosts: lb_servers force_handlers: true gather_facts: false become: truepre_tasks:- name: Setting the maintenance messageansible.builtin.copy:dest: /tmp/site.readycontent: "Playbook site.yml ready to start\n"roles: # The "haproxy" role has a dependency on the "firewall" role. # The "firewall" role requires the "firewall_rules" variable. - role: haproxy
Add a handler to the haproxy role that writes the message Reloaded to the /tmp/haproxy.status file.
Notify the handler if the task that uses the template module in the haproxy role reports that the state of the system changed.
Use haproxy filehandler as the name of the handler.
Edit the roles/haproxy/handlers/main.yml file and add the handler that copies the text to the file.
If desired, then you can add a newline character to the end of the text string.
The modified file contains the following content:
---
# handlers file for haproxy
- name: restart haproxy
ansible.builtin.service:
name: haproxy
state: restarted
- name: reload haproxy
ansible.builtin.service:
name: haproxy
state: reloaded
- name: haproxy filehandler
ansible.builtin.copy:
dest: /tmp/haproxy.status
content: "Reloaded\n"Edit the roles/haproxy/tasks/main.yml file and modify the Ensure haproxy configuration is set task so that it notifies the haproxy filehandler handler if the task reports that it changed the current system.
Because the modified task notifies two handlers, the existing reload haproxy handler must be moved to a separate line.
The modified file contains the following content:
---
# tasks file for haproxy
- name: Ensure haproxy packages are present
ansible.builtin.yum:
name:
- haproxy
- socat
state: present
- name: Ensure haproxy is started and enabled
ansible.builtin.service:
name: haproxy
state: started
enabled: true
- name: Ensure haproxy configuration is set
ansible.builtin.template:
src: haproxy.cfg.j2
dest: /etc/haproxy/haproxy.cfg
owner: root
group: root
mode: 0644
notify:
- reload haproxy
- haproxy filehandlerAdd the apache_installer tag to the yum task in the apache role.
Edit the roles/apache/tasks/main.yml file and add the apache_installer tag to the yum task.
The modified file contains the following content:
---
# tasks file for apache
- name: Ensure httpd packages are installed
ansible.builtin.yum:
name: "{{ item }}"
state: present
loop:
- httpd
- php
- git
- php-mysqlnd
tags: apache_installer
- name: Ensure SELinux allows httpd connections to a remote database
ansible.posix.seboolean:
name: httpd_can_network_connect_db
state: true
persistent: true
- name: Ensure httpd service is started and enabled
ansible.builtin.service:
name: httpd
state: started
enabled: trueEnable the timer and profile_tasks callback plug-ins for the playbook.
The two plug-ins are part of the ansible.posix collection.
If desired, then you can specify the FQCNs for the callback plug-ins.
Use automation content navigator to run the site.yml playbook in stdout mode.
Analyze the output to find the task that uses the most time.
Run the site.yml playbook in stdout mode.
Your output looks similar to the following.
[student@workstation task-review]$ansible-navigator run site.yml -m stdout...output omitted... PLAY RECAP ********************************************************************* servera.lab.example.com : ok=8 changed=8 unreachable=0 failed=0 ... serverb.lab.example.com : ok=5 changed=4 unreachable=0 failed=0 ... serverc.lab.example.com : ok=5 changed=4 unreachable=0 failed=0 ... Playbook run took 0 days, 0 hours, 0 minutes, 50 seconds Monday 07 November 2022 21:27:18 +0000 (0:00:00.788) 0:00:50.513 ******* ===============================================================================apache : Ensure httpd packages are installed --------------------------- 25.32shaproxy : Ensure haproxy packages are present --------------------------- 4.55s haproxy : reload haproxy ------------------------------------------------ 3.81s haproxy : haproxy filehandler ------------------------------------------- 3.60s firewall : reload firewalld --------------------------------------------- 2.25s ...output omitted...
The previous output sorted the tasks based on how long it took for each task to complete. The following task took the most time:
apache : Ensure httpd packages are installed --------------------------- 25.32s
Refactor the most expensive task to make it more efficient.
When done, run the cleanup_apache.yml playbook to clean up the web servers so that you can compare the results.
To verify the changes, run the site.yml playbook with an appropriate tag so that you only run the modified task.
Identify the file containing the Ensure httpd packages are installed task.
The -R option performs a recursive search and the -l option restricts the output to only show the file name.
In addition to the roles/apache/tasks/main.yml file, your output displays one or more site-artifact files.
[student@workstation task-review]$ grep -Rl 'Ensure httpd packages are installed'
roles/apache/tasks/main.yml
...output omitted...Edit the roles/apache/tasks/main.yml task file to remove the loop from the yum task and instead install all the packages in one transaction.
The modified file contains the following content:
---
# tasks file for apache
- name: Ensure httpd packages are installed
ansible.builtin.yum:
name:
- httpd
- php
- git
- php-mysqlnd
state: present
tags: apache_installer
- name: Ensure SELinux allows httpd connections to a remote database
ansible.posix.seboolean:
name: httpd_can_network_connect_db
state: true
persistent: true
- name: Ensure httpd service is started and enabled
ansible.builtin.service:
name: httpd
state: started
enabled: trueRun the cleanup_apache.yml playbook to clean up the web servers.
[student@workstation task-review]$ansible-navigator run cleanup_apache.yml \>-m stdout...output omitted...
Use automation content navigator to run the site.yml playbook with the apache_installer tag in stdout mode.
Verify that the Ensure httpd packages are installed task takes less time to complete.
[student@workstation task-review]$ansible-navigator run site.yml \>--tags apache_installer -m stdout...output omitted... PLAY RECAP ********************************************************************* serverb.lab.example.com : ok=1 changed=1 unreachable=0 failed=0 ... serverc.lab.example.com : ok=1 changed=1 unreachable=0 failed=0 ... Playbook run took 0 days, 0 hours, 0 minutes, 15 seconds Monday 07 November 2022 21:56:20 +0000 (0:00:14.971) 0:00:15.060 ******* =============================================================================== apache : Ensure httpd packages are installed --------------------------- 14.97s
Commit and push your changes to the remote Git repository.
Add the changed files, commit the changes, and push them to the Git repository.
If prompted, then use Student@123 as the Git password.
[student@workstation task-review]$git add .[student@workstation task-review]$git commit -m "Lab updates"[exercise 0a55370] Lab updates 7 files changed, 19 insertions(+), 10 deletions(-) [student@workstation task-review]$git push -u origin exercisePassword for 'https://student@git.lab.example.com':Student@123...output omitted...