Chapter 11: Comprehensive Review
Exercise: Creating playbooks
Write three playbooks: one that installs and configures web servers from a template, with a handler; one that tests the result from workstation and records any failure with a block and rescue; and one that imports the other two. Solutions are hidden under each task. Try each one yourself first.
This lab covers chapters 3 to 7. The project ~/review-playbooks has an ansible.cfg, an inventory with servera and serverb in webservers (and workstation), the template templates/vhost.conf.j2 and the page files/index.html.
Creating playbooks
- Create and run playbooks that perform tasks on managed hosts.
- Use Jinja2 templates, blocks and handlers in playbooks.
Prerequisites: Complete control-node setup and the preceding lessons in this chapter. Run commands as student on workstation unless a step names another machine.
From the project directory, run the relevant home-lab check. For an exercise with several checkpoints, grade each state before changing or removing it:
lab grade review-playbooks
lab grade review-playbooks --checkpoint deployed
lab grade review-playbooks --checkpoint rescuedThe grader reads project files and host state. A passing report covers the listed checks; also perform the task’s independent connection, repeat-run, and reboot checks where requested.
Point the verification at serverb and deliberately stop that service. Prove the same recovery path records the failure.
Record the published result first. The grader checks the original requirements, so a changed name or value may intentionally fail those checks.
Deliver and test the supplied virtual-host site on webservers through site.yml.
dev_deploy.ymlmust leave Apache running and enabled, HTTP allowed persistently, andfiles/index.htmlunder/var/www/vhosts/HOSTNAME/./etc/httpd/conf.d/vhost.confmust come from the supplied host-specific template, root-owned with mode0644. Configuration changes must restart Apache.get_web_content.ymlmust retrieve servera's page from workstation and write the failed result to the project'serror.logif retrieval fails.site.ymlmust deploy before testing. Prove the successful path, a failed request with recovery, and the restored final deployment. Grade the recovered checkpoint before restoring the service.
Reset the servers first: rht-vmctl reset servers on the Ubuntu host.
Install the web server
Create dev_deploy.yml with one play for webservers, with privilege escalation, whose first task installs httpd.
---
- name: Install and configure web servers
hosts: webservers
become: true
tasks:
- name: Install httpd package
ansible.builtin.dnf:
name: httpd
state: presentStart it
Add a task that starts httpd and enables it at boot.
- name: Start httpd service
ansible.builtin.service:
name: httpd
state: started
enabled: trueConfigure it from the template
Add a task that deploys templates/vhost.conf.j2 to /etc/httpd/conf.d/vhost.conf, owned by root, mode 0644, and notifies a handler called Restart httpd.
- name: Deploy configuration template
ansible.builtin.template:
src: templates/vhost.conf.j2
dest: /etc/httpd/conf.d/vhost.conf
owner: root
group: root
mode: '0644'
notify: Restart httpdThe template sets each host's DocumentRoot to /var/www/vhosts/HOSTNAME/, from ansible_facts['hostname'].
Publish the content
Add a task that copies files/index.html into /var/www/vhosts/{{ ansible_facts['hostname'] }} on the managed hosts. The directory must be created if it does not exist.
- name: Copy index.html
ansible.builtin.copy:
src: files/
dest: "/var/www/vhosts/{{ ansible_facts['hostname'] }}/"
owner: root
group: root
mode: '0644'Copying the directory files/ (with its trailing slash) copies its contents and creates the destination directory on the way.
Open the firewall, and add the handler
Add a task that allows http through the firewall, now and permanently, and the Restart httpd handler.
- name: Ensure web server port is open
ansible.posix.firewalld:
state: enabled
permanent: true
immediate: true
service: http
handlers:
- name: Restart httpd
ansible.builtin.service:
name: httpd
state: restartedTest the content, and record a failure
Create get_web_content.yml with a play named Test web content for workstation, with privilege escalation. Its one task, Retrieve web content and write to error log on failure, is a block:
- in the block, a task
Retrieve web contentusesansible.builtin.urito fetchhttp://servera.lab.example.com, returning the content, registered incontent; - in its rescue section, a task
Write to error filewrites the value ofcontentto/home/student/review-playbooks/error.log, creating the file if needed.
---
- name: Test web content
hosts: workstation
become: true
tasks:
- name: Retrieve web content and write to error log on failure
block:
- name: Retrieve web content
ansible.builtin.uri:
url: http://servera.lab.example.com
return_content: true
register: content
rescue:
- name: Write to error file
ansible.builtin.lineinfile:
path: /home/student/review-playbooks/error.log
line: "{{ content }}"
create: trueregister keeps the result even when the task fails, so the rescue task can write the error into the log.
Tie them together
Create site.yml that imports dev_deploy.yml and then get_web_content.yml, and run it. A second run must report no changes.
---
# Deploy web servers
- name: Deploy web servers
ansible.builtin.import_playbook: dev_deploy.yml
# Retrieve web content
- name: Retrieve web content
ansible.builtin.import_playbook: get_web_content.yml[student@workstation review-playbooks]$ ansible-navigator run -m stdout site.yml
PLAY [Install and configure web servers] ***************************************
...output omitted...
TASK [Install httpd package] ***************************************************
changed: [servera.lab.example.com]
changed: [serverb.lab.example.com]
...output omitted...
RUNNING HANDLER [Restart httpd] ************************************************
changed: [servera.lab.example.com]
changed: [serverb.lab.example.com]
PLAY [Test web content] ********************************************************
TASK [Gathering Facts] *********************************************************
ok: [workstation]
TASK [Retrieve web content] ****************************************************
ok: [workstation]
PLAY RECAP *********************************************************************
servera.lab.example.com : ok=7 changed=6 unreachable=0 failed=0 ...
serverb.lab.example.com : ok=7 changed=6 unreachable=0 failed=0 ...
workstation : ok=2 changed=0 unreachable=0 failed=0 ...
[student@workstation review-playbooks]$ curl http://servera.lab.example.com
This is a test page.The page did load, so the rescue did not run and there is no error.log.
See the rescue at work
Stop httpd on servera, run get_web_content.yml again, and read error.log.
[student@workstation review-playbooks]$ ansible servera.lab.example.com -b \
> -m ansible.builtin.service -a 'name=httpd state=stopped'
...output omitted...
[student@workstation review-playbooks]$ ansible-navigator run -m stdout get_web_content.yml
...output omitted...
TASK [Retrieve web content] ****************************************************
fatal: [workstation]: FAILED! => {"changed": false, "content": "", "elapsed": 0, "msg": "Status code was -1 and not [200]: Request failed: <urlopen error [Errno 111] Connection refused>", ...output omitted...}
TASK [Write to error file] *****************************************************
changed: [workstation]
PLAY RECAP *********************************************************************
workstation : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=1 ...
[student@workstation review-playbooks]$ cat error.log
{'content': '', 'redirected': False, 'url': 'http://servera.lab.example.com', 'status': -1, 'elapsed': 0, 'changed': False, 'failed': True, 'msg': 'Status code was -1 and not [200]: Request failed: <urlopen error [Errno 111] Connection refused>'}failed=0 and rescued=1: the failure was handled. At home, run lab grade review-playbooks --checkpoint rescued while the service is stopped. Run site.yml once more to start httpd again, then grade the final state.
Grade and finish
Check your work with lab grade review-playbooks, then put the exercise away with lab finish review-playbooks.