Chapter 3: Implementing an Ansible Playbook
Exercise: Implementing multiple plays
You will write intranet.yml, a playbook with two plays. The first configures servera as an intranet web server with root privileges. The second runs unprivileged on localhost and checks that the site answers.
The project ~/playbook-multi already has an ansible.cfg and an inventory that defines servera.lab.example.com.
A playbook with two plays: Plays run in order. The first configures servera with root privileges; the second runs on localhost (inside the execution environment) to test the result.
Implementing multiple plays
- Build and run a playbook with two plays.
- Enable privilege escalation for one play and disable it for another.
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 playbook-multiThe 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.
Make the verification require a specific phrase in the returned page as well as HTTP 200.
Record the published result first. The grader checks the original requirements, so a changed name or value may intentionally fail those checks.
Deliver an intranet site on servera and verify it in the same run. Save your work in intranet.yml.
- The host must have current
httpdandfirewalldpackages, with both services running and enabled. /var/www/html/index.htmlmust containWelcome to the example.com intranet!and HTTP must be allowed now and after reboot.- A separate, unprivileged play on localhost must confirm an HTTP 200 response and retrieve the content.
- Show that the verification runs after deployment and that a repeat run has no unexpected changes.
Start the first play
In ~/playbook-multi, create intranet.yml with the document marker and a play named Enable intranet services for servera.lab.example.com, with privilege escalation on and an empty task list to fill in.
---
- name: Enable intranet services
hosts: servera.lab.example.com
become: true
tasks:Install the latest httpd and firewalld
One ansible.builtin.dnf task can handle both packages: give name a list.
- name: Latest version of httpd and firewalld installed
ansible.builtin.dnf:
name:
- httpd
- firewalld
state: latestThe task starts at four spaces, the module at six, its arguments at eight, and the package list items at ten.
Deploy a test page
Use ansible.builtin.copy with inline content rather than a source file.
- name: Test html page is installed
ansible.builtin.copy:
content: "Welcome to the example.com intranet!\n"
dest: /var/www/html/index.htmlStart firewalld and open HTTP
Two tasks: make sure firewalld is enabled and running, then allow the http service permanently and immediately.
- name: Firewall enabled and running
ansible.builtin.service:
name: firewalld
enabled: true
state: started
- name: Firewall permits access to httpd service
ansible.posix.firewalld:
service: http
permanent: true
state: enabled
immediate: trueNote that firewalld comes from the ansible.posix collection, not ansible.builtin.
Start the web server
- name: Web server enabled and running
ansible.builtin.service:
name: httpd
enabled: true
state: startedAdd the test play
Start a second play at the left margin (no indentation). It targets localhost, which with navigator is the execution environment (on the home lab, where no container is used, it is workstation itself), and does not need privilege escalation.
- name: Test intranet web server
hosts: localhost
become: false
tasks:
- name: Connect to intranet web server
ansible.builtin.uri:
url: http://servera.lab.example.com
return_content: true
status_code: 200return_content: true adds the server's response to the task result, and status_code: 200 makes the task fail if the page does not load.
---
- name: Enable intranet services
hosts: servera.lab.example.com
become: true
tasks:
- name: Latest version of httpd and firewalld installed
ansible.builtin.dnf:
name:
- httpd
- firewalld
state: latest
- name: Test html page is installed
ansible.builtin.copy:
content: "Welcome to the example.com intranet!\n"
dest: /var/www/html/index.html
- name: Firewall enabled and running
ansible.builtin.service:
name: firewalld
enabled: true
state: started
- name: Firewall permits access to httpd service
ansible.posix.firewalld:
service: http
permanent: true
state: enabled
immediate: true
- name: Web server enabled and running
ansible.builtin.service:
name: httpd
enabled: true
state: started
- name: Test intranet web server
hosts: localhost
become: false
tasks:
- name: Connect to intranet web server
ansible.builtin.uri:
url: http://servera.lab.example.com
return_content: true
status_code: 200Check the syntax
[student@workstation playbook-multi]$ ansible-navigator run \
> -m stdout intranet.yml --syntax-check
playbook: /home/student/playbook-multi/intranet.ymlRun it and read the recap
[student@workstation playbook-multi]$ ansible-navigator run -m stdout intranet.yml
PLAY [Enable intranet services] ************************************************
...output omitted...
PLAY [Test intranet web server] ************************************************
...output omitted...
PLAY RECAP *********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 ...
servera.lab.example.com : ok=6 changed=5 unreachable=0 failed=0 ...Both plays appear in order, and each host gets its own line in the recap.
Confirm from the workstation
[student@workstation playbook-multi]$ curl http://servera.lab.example.com
Welcome to the example.com intranet!Finish
Check your work with lab grade playbook-multi, then put the exercise away with lab finish playbook-multi.