Chapter 5: Implementing Task Control
Exercise: Loops and conditional tasks
You will install MariaDB with a looping task, then add a condition so the installation only happens on Red Hat Enterprise Linux, and run it against a second group.
The inventory in ~/control-flow has two groups:
[database_dev]
servera.lab.example.com
[database_prod]
serverb.lab.example.comWriting loops and conditional tasks
- Implement conditionals with the when keyword.
- Iterate a task with loop, together with conditionals.
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 control-flowThe 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 host whose OS does not match the condition. Ensure later service tasks do not assume a skipped package was installed.
Record the published result first. The grader checks the original requirements, so a changed name or value may intentionally fail those checks.
Configure MariaDB from the mariadb_packages list in playbook.yml.
- On
database_dev, installmariadb-serverandpython3-PyMySQLthrough individual loop items, then start and enable MariaDB. - Extend the exercise to
database_prod: installation must happen only on the intended distribution. In the classroom that is Red Hat Enterprise Linux; at home use the RedHat OS family so Rocky hosts are included. - Prove which hosts ran or skipped the installation and check service state. A skipped installation does not install dependencies for a later service task.
Move into the project directory
[student@workstation ~]$ cd ~/control-flow
[student@workstation control-flow]$ cat inventoryStart the play with a list variable
Create playbook.yml with a play, MariaDB server is running, for database_dev. Define mariadb_packages as a list containing mariadb-server and python3-PyMySQL.
---
- name: MariaDB server is running
hosts: database_dev
vars:
mariadb_packages:
- mariadb-server
- python3-PyMySQLInstall the packages with a loop
Add a task that installs each package in mariadb_packages, one loop item at a time.
tasks:
- name: MariaDB packages are installed
ansible.builtin.dnf:
name: "{{ item }}"
state: present
loop: "{{ mariadb_packages }}"Start the service
- name: Start MariaDB service
ansible.builtin.service:
name: mariadb
state: started
enabled: trueRun it and read the per-item output
[student@workstation control-flow]$ ansible-navigator run -m stdout playbook.yml
...output omitted...
TASK [MariaDB packages are installed] ******************************************
changed: [servera.lab.example.com] => (item=mariadb-server)
changed: [servera.lab.example.com] => (item=python3-PyMySQL)
TASK [Start MariaDB service] ***************************************************
changed: [servera.lab.example.com]
PLAY RECAP *********************************************************************
servera.lab.example.com : ok=3 changed=2 unreachable=0 failed=0 ...Each loop item gets its own line, tagged (item=...).
Add a condition and target production
Change the play to target database_prod, and make the install task run only when the host's distribution is Red Hat Enterprise Linux.
- name: MariaDB server is running
hosts: database_prod
...output omitted...
- name: MariaDB packages are installed
ansible.builtin.dnf:
name: "{{ item }}"
state: present
loop: "{{ mariadb_packages }}"
when: ansible_facts['distribution'] == "RedHat"serverb runs Rocky Linux at home, so with "RedHat" the condition is false and both items are skipped. Write when: ansible_facts['distribution'] == "Rocky" to get the output in the next task. Then try it once with "RedHat" on purpose: seeing skipping: for each item is the other half of this exercise.
Run it again
[student@workstation control-flow]$ ansible-navigator run -m stdout playbook.yml
...output omitted...
TASK [MariaDB packages are installed] ******************************************
ok: [serverb.lab.example.com] => (item=mariadb-server)
ok: [serverb.lab.example.com] => (item=python3-PyMySQL)
...output omitted...
PLAY RECAP *********************************************************************
serverb.lab.example.com : ok=3 changed=0 unreachable=0 failed=0 ...The shown recap is a repeat run after production is configured. Its first run can report changes. In the classroom serverb runs RHEL, so the condition is true and the task runs. On a host where the condition is false, each item shows skipping: instead:
TASK [MariaDB packages are installed] ******************************************
skipping: [serverb.lab.example.com] => (item=mariadb-server)
skipping: [serverb.lab.example.com] => (item=python3-PyMySQL)Finish
Check your work with lab grade control-flow, then put the exercise away with lab finish control-flow.