TT Lab
Get started
Learn Learning paths Courses

Ansible in Practice

Compressing Branches With Conditionals and Loops

Continue in TT Lab

Goal

You fold tasks that kept multiplying through copy and paste into data and a loop, and learn to filter items with a condition.

Why it matters

If there are several nearly identical tasks, a mistake where just one of them differs is bound to happen, and it is hard to find by reading the code. If you reduce the tasks to one, the place to make a mistake also becomes one, and the data looks like a table, so a missing cell stands out. Three things commonly trip people up in practice when using loops. Log exposure — if you loop over a dictionary as is, every value inside it is printed in the log, so loop_control.label is needed. Idempotency — if the loop runs ten times, the damage from non-idempotency is ten times as large. Combinatorial explosion — the product of two lists grows quickly. And when you wait for something with until, put the judgment "if it doesn't work within this time, there is a real problem" into the retry count.

Steps

  1. In /root/ans/loops/site.yml, use loop to create the alpha, beta, and gamma directories under /root/ans/loops/simple/. There must be only one task.
  2. Read app_users from /opt/lab/fixtures/ansible/users.yml and create each item's dir with its mode permission — /root/ans/loops/deploy (0750), /root/ans/loops/metrics (0755), /root/ans/loops/backup (0700).
  3. Add when to the same loop so that a PRIVILEGED file is left only in the directories of items stricter than 0755 — /root/ans/loops/deploy/PRIVILEGED and /root/ans/loops/backup/PRIVILEGED must be created, and /root/ans/loops/metrics/PRIVILEGED must not.
  4. Tidy up the log with the label of loop_control and save the execution output to /root/ans/loops/out/run.txt. The log must show an abbreviated label such as item=deploy and must not show the whole dictionary.
  5. Create a waiting task that uses until/retries/delay, and leave the success result in /root/ans/loops/out/ready.txt with the content ready.
  6. From combinations of environment (dev,stage,prod) × component (app,worker), create 6 files named /root/ans/loops/matrix/<환경>-<컴포넌트>.conf (environment-component), for example /root/ans/loops/matrix/dev-app.conf and /root/ans/loops/matrix/prod-worker.conf. Each file contains the lines env=<환경> and component=<컴포넌트>, where the placeholders stand for the environment and the component.
  7. Gather the 6 .conf files of the matrix with a pattern and copy them into /root/ans/loops/collected/. Do not write the file names one by one.
  8. Create /root/ans/loops/out/loops.json. It holds users (3 entries, each with a boolean privileged) and matrix_files (6). Also save the result of the second run to /root/ans/loops/out/run2.txt, and it must show changed=0.

Notes

Create 3 directories with a list loop

In /root/ans/loops/site.yml, use loop to create the alpha, beta, and gamma directories under /root/ans/loops/simple/. There must be only one task.

Give a list to loop: and refer to each element as item. Do not copy the task.

Loop over a list of dictionaries

Read app_users from /opt/lab/fixtures/ansible/users.yml and create each item's dir with its mode permission — /root/ans/loops/deploy (0750), /root/ans/loops/metrics (0755), /root/ans/loops/backup (0700).

Read app_users from the fixture with vars_files. Access fields like item.name and item.mode.

Process only the items that match a condition

Add when to the same loop so that a PRIVILEGED file is left only in the directories of items stricter than 0755 — /root/ans/loops/deploy/PRIVILEGED and /root/ans/loops/backup/PRIVILEGED must be created, and /root/ans/loops/metrics/PRIVILEGED must not.

When loop and when are used together, the condition is evaluated for each item. Items whose mode is 0755 must be left out.

Tidy up the labels printed in the log

Tidy up the log with the label of loop_control and save the execution output to /root/ans/loops/out/run.txt. The log must show an abbreviated label such as item=deploy and must not show the whole dictionary.

Abbreviate with the label of loop_control. The whole dictionary must not appear in the log.

Retry until a condition becomes true

Create a waiting task that uses until/retries/delay, and leave the success result in /root/ans/loops/out/ready.txt with the content ready.

You need until, retries, and delay together. Leave the success result in a file.

Build all combinations of two lists

From combinations of environment (dev,stage,prod) × component (app,worker), create 6 files named /root/ans/loops/matrix/<환경>-<컴포넌트>.conf (environment-component), for example /root/ans/loops/matrix/dev-app.conf and /root/ans/loops/matrix/prod-worker.conf. Each file contains the lines env=<환경> and component=<컴포넌트>, where the placeholders stand for the environment and the component.

Build the combinations with the product filter. 3 environments × 2 components = 6 files.

Gather files with a pattern

Gather the 6 .conf files of the matrix with a pattern and copy them into /root/ans/loops/collected/. Do not write the file names one by one.

Do not write the file names one by one; get the list with a pattern. The content must be the same as the originals.

Loop result report and rerun check

Create /root/ans/loops/out/loops.json. It holds users (3 entries, each with a boolean privileged) and matrix_files (6). Also save the result of the second run to /root/ans/loops/out/run2.txt, and it must show changed=0.

Organize each user's privileged status and the number of combination files as JSON, and check that the second run shows changed=0.