Chapter 11: Comprehensive Review
Exercise: Deploying Ansible
Set up workstation as a control node for servera and serverb, then write, fix and extend small playbooks that use variables, facts and loops. Solutions are hidden under each task. Try each one yourself first.
This lab covers chapters 2 to 5 and 9. Your project directory is ~/review-deploy; lab start puts two playbooks in it, packages.yml and verify_user.yml. You write everything else.
Deploying Ansible
- Install and configure Ansible.
- Create, modify and troubleshoot 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-deployThe 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.
Add a third disposable user through the existing list, then verify all accounts without duplicating the task.
Record the published result first. The grader checks the original requirements, so a changed name or value may intentionally fail those checks.
Prepare and use a reproducible control-node project for servera and serverb.
- The project must have a discoverable inventory and configuration, with the privileged connections appropriate to the environment (root in the home walkthrough). Use the runtime appropriate to your environment.
users.ymlmust provisionjoeandsamthrough one list-driven task.packages.ymlmust install the packages described in the exercise,httpdandmariadb-server, plusredisonly on hosts with more than 10 MiB of swap.- Repair
verify_user.ymlso it checks forsamwithout creating that account and records the result in/home/student/verify.txt. Confirm both hosts and repeat the playbooks.
Reset the servers first: rht-vmctl reset servers on the Ubuntu host. ansible-navigator is already installed on workstation (section 1.6), and the home lab runs without an execution environment, so the first task's EE steps do not apply.
Install the control node tools
Install automation content navigator on workstation; the repository that contains it is already configured.
[student@workstation ~]$ sudo dnf install ansible-navigator
...output omitted...
Complete!Nothing to install: check that it is there.
[student@workstation ~]$ ansible-navigator --version
ansible-navigator 26.9.0Inventory and configuration
In ~/review-deploy, create an inventory with a group dev containing servera.lab.example.com and serverb.lab.example.com, and an ansible.cfg that uses it.
[dev]
servera.lab.example.com
serverb.lab.example.com[defaults]
inventory=./inventoryIn a classroom, ansible-navigator runs the playbooks inside an execution environment, which connects to the managed hosts as root. The home lab runs them directly on workstation, as student, who cannot add users. Add remote_user=root to [defaults] to get the same behaviour; section 1.6 installed student's key for root on every server.
[defaults]
inventory=./inventory
remote_user=rootThe execution environment
Create ansible-navigator.yml so that navigator uses the image utility.lab.example.com/ee-supported-rhel8:latest, and pulls it only if it is missing. Log in to the private automation hub on utility.lab.example.com (user admin, password redhat), then run ansible-navigator once to pull the image.
---
ansible-navigator:
execution-environment:
image: utility.lab.example.com/ee-supported-rhel8:latest
pull:
policy: missing[student@workstation review-deploy]$ podman login utility.lab.example.com
Username: admin
Password: redhat
Login Succeeded!
[student@workstation review-deploy]$ ansible-navigator
...output omitted...
Execution environment image name: utility.lab.example.com/ee-supported-rhel8:latest
Execution environment pull policy: missing
Execution environment pull needed: True
...output omitted...Skip this task: the home lab has no private automation hub and runs without an execution environment, which your ~/.ansible-navigator.yml already says.
Two users with one task
Write users.yml with one play for dev that adds the users joe and sam, with a single task. Run it.
---
- name: Add users
hosts: dev
tasks:
- name: Add the users joe and sam
ansible.builtin.user:
name: "{{ item }}"
loop:
- joe
- sam[student@workstation review-deploy]$ ansible-navigator run -m stdout users.yml
PLAY [Add users] ***************************************************************
TASK [Gathering Facts] *********************************************************
ok: [servera.lab.example.com]
ok: [serverb.lab.example.com]
TASK [Add the users joe and sam] ***********************************************
changed: [serverb.lab.example.com] => (item=joe)
changed: [servera.lab.example.com] => (item=joe)
changed: [serverb.lab.example.com] => (item=sam)
changed: [servera.lab.example.com] => (item=sam)
PLAY RECAP *********************************************************************
servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0 ...
serverb.lab.example.com : ok=2 changed=1 unreachable=0 failed=0 ...In the home lab without remote_user=root, every item fails with useradd: Permission denied: the playbook connected as student.
Packages from a variable
Look at packages.yml. In its play, define a variable packages with the list httpd and mariadb-server. Run it.
---
- name: Install packages
hosts: dev
vars:
packages:
- httpd
- mariadb-server
tasks:
- name: Install the required packages
ansible.builtin.dnf:
name: "{{ packages }}"
state: latest[student@workstation review-deploy]$ ansible-navigator run -m stdout packages.yml
...output omitted...
TASK [Install the required packages] *******************************************
changed: [servera.lab.example.com]
changed: [serverb.lab.example.com]
...output omitted...A package that depends on a fact
Add a task to packages.yml that installs redis only if the host has more than 10 MB of swap space. Run the playbook again.
- name: Install redis
ansible.builtin.dnf:
name: redis
state: latest
when: ansible_facts['swaptotal_mb'] > 10[student@workstation review-deploy]$ ansible-navigator run -m stdout packages.yml
...output omitted...
TASK [Install redis] ***********************************************************
skipping: [servera.lab.example.com]
skipping: [serverb.lab.example.com]
...output omitted...
[student@workstation review-deploy]$ ansible dev -m ansible.builtin.setup -a 'filter=ansible_swaptotal_mb'
servera.lab.example.com | SUCCESS => {
"ansible_facts": {
"ansible_swaptotal_mb": 0,
...output omitted...The home-lab servers have no swap, so both skip the task. In a classroom where one server has swap, that one installs redis.
Fix verify_user.yml
verify_user.yml should check, without creating it, that the user sam exists, and then write a line to /home/student/verify.txt. Run it with --check and fix what it reports, until a check run passes. Then run it normally.
[student@workstation review-deploy]$ ansible-navigator run -m stdout verify_user.yml --check
ERROR! couldn't resolve module/action 'ansible.buildin.user'. This often indicates a misspelling, missing collection, or incorrect module path.
The error appears to be in '/home/student/review-deploy/verify_user.yml': line 6, column 7, but may
be elsewhere in the file depending on the exact syntax problem.
...output omitted...The module name is misspelled: ansible.buildin.user should be ansible.builtin.user. Fix it and check again:
[student@workstation review-deploy]$ ansible-navigator run -m stdout verify_user.yml --check
...output omitted...
TASK [Output sam user status to file] ******************************************
fatal: [serverb.lab.example.com]: FAILED! => {"changed": false, "msg": "Unsupported parameters for (ansible.builtin.lineinfile) module: when. Supported parameters include: attributes, backrefs, backup, create, firstmatch, group, insertafter, insertbefore, line, ...output omitted..."}
...output omitted...when is indented as if it were an option of lineinfile. It is a task keyword, so it belongs at the level of the module name:
---
- name: Verify the sam user was created
hosts: dev
tasks:
- name: Verify the sam user exists
ansible.builtin.user:
name: sam
check_mode: true
register: sam_check
- name: Sam was created
ansible.builtin.debug:
msg: "Sam was created"
when: sam_check['changed'] == false
- name: Output sam user status to file
ansible.builtin.lineinfile:
path: /home/student/verify.txt
line: "Sam was created"
create: true
when: sam_check['changed'] == false[student@workstation review-deploy]$ ansible-navigator run -m stdout verify_user.yml
...output omitted...
TASK [Sam was created] *********************************************************
ok: [servera.lab.example.com] => {
"msg": "Sam was created"
}
...output omitted...
TASK [Output sam user status to file] ******************************************
changed: [servera.lab.example.com]
changed: [serverb.lab.example.com]
PLAY RECAP *********************************************************************
servera.lab.example.com : ok=4 changed=1 unreachable=0 failed=0 ...
serverb.lab.example.com : ok=4 changed=1 unreachable=0 failed=0 ...check_mode: true on the user task means it can never create sam: if it would have to, it reports changed, and that is the test.
Grade and finish
Check your work with lab grade review-deploy, then put the exercise away with lab finish review-deploy.