TT Lab
Get started
Learn Learning paths Courses

Ansible in Practice

Build the precedence table from measurements, not from the docs

Continue in TT Lab

Goal

You learn to plant a variable of the same name in twelve places one at a time, measure for yourself which one wins, and leave the result as a ranking table your team can read.

Why it matters

Reports like "I definitely wrote it in group_vars, but a different value shows up" do not appear as errors. The playbook succeeds, the files are created, and only the content is different. Neither syntax checks nor linters catch it. The only thing that can catch it is measuring "what does this name resolve to, at this spot, right now?" That is why this lab measures instead of transcribing a list from the documentation. Someone who has measured it once knows what to suspect first next time without memorizing the table. And the conclusion you will reach at the end is not the table — a design that reduces the places is stronger than knowing the table.

Steps

  1. List web1 and web2 in /root/ans/prec/inventory/hosts.ini (ansible_host=127.0.0.1, ansible_port=2222, ansible_user=root), and create the measuring role in /root/ans/prec/roles/probe/. Put svc_tier: role-defaults and probe_out in defaults/main.yml, and fill tasks/main.yml with two tasks: one that shows WINNER={{ svc_tier }} with debug and one that writes the same value to the probe_out path. Run this role against web1 with /root/ans/prec/p01.yml and leave /root/ans/prec/out/01.txt.
  2. Create /root/ans/prec/inv-vars/ as a directory inventory. List the web group (web1, web2) and the db group (db1) in hosts.yml, and plant svc_tier as inv-all in group_vars/all.yml, inv-web in group_vars/web.yml, and inv-host in host_vars/web2.yml. Measure all three hosts with /root/ans/prec/p02.yml and leave /root/ans/prec/out/02-<호스트>.txt (with the host name in place of the placeholder).
  3. Create /root/ans/prec/p03.yml, plant svc_tier: play-vars in the play vars:, and measure web1. Use the inv-vars of step 2 as the inventory and leave the result in /root/ans/prec/out/03.txt.
  4. Write svc_tier: vars-file in /root/ans/prec/vars/tier.yml, and make /root/ans/prec/p04.yml read that file with vars_files: while leaving play-vars in the play vars: exactly as in step 3. The result is /root/ans/prec/out/04.txt.
  5. Create a second measuring role in /root/ans/prec/roles/probe_locked/. Put svc_tier: role-vars in vars/main.yml (put only probe_out in defaults), and write tasks/main.yml the same as probe. Have /root/ans/prec/p05.yml keep the same two places as in step 4 and call this role, leaving /root/ans/prec/out/05.txt.
  6. Create /root/ans/prec/p06.yml. The play reads tier.yml with vars_files: and attaches vars: {svc_tier: block-vars} to a block. The first task in the block calls the probe_locked role and leaves /root/ans/prec/out/06-block.txt, and the second task attaches svc_tier: task-vars to its own vars: and writes the value to /root/ans/prec/out/06-task.txt.
  7. Create /root/ans/prec/p07.yml. First set svc_tier: set-fact with set_fact, then have a task with task-vars attached in its task vars: write the value to /root/ans/prec/out/07-setfact.txt, and finally call the probe_locked role passing svc_tier: role-param and leave /root/ans/prec/out/07-roleparam.txt.
  8. Put base_limits and svc_limits as {cpu: "1", memory: 1Gi} in /root/ans/prec/vars/limits.yml, and make /root/ans/prec/p08.yml write the command-line value to /root/ans/prec/out/08.txt when run with -e svc_tier=extra-vars. In the same playbook, leave the result of giving svc_limits: {memory: 2Gi} through task vars: and the result merged with combine in /root/ans/prec/out/08-hash.json under the two keys replaced and combined, and write the measurement results of the twelve places as a table in /root/ans/prec/out/rank.md.

Notes

The bottom place — role defaults

List web1 and web2 in /root/ans/prec/inventory/hosts.ini (ansible_host=127.0.0.1, ansible_port=2222, ansible_user=root), and create the measuring role in /root/ans/prec/roles/probe/. Put svc_tier: role-defaults and probe_out in defaults/main.yml, and fill tasks/main.yml with two tasks: one that shows WINNER={{ svc_tier }} with debug and one that writes the same value to the probe_out path. Run this role against web1 with /root/ans/prec/p01.yml and leave /root/ans/prec/out/01.txt.

This role is the gauge you use throughout this lab. Whichever place the value comes from, the role only has to write down "the value it sees right now." The result file path must differ for each play, so take that as a variable too.

The three places inside the inventory

Create /root/ans/prec/inv-vars/ as a directory inventory. List the web group (web1, web2) and the db group (db1) in hosts.yml, and plant svc_tier as inv-all in group_vars/all.yml, inv-web in group_vars/web.yml, and inv-host in host_vars/web2.yml. Measure all three hosts with /root/ans/prec/p02.yml and leave /root/ans/prec/out/02-<호스트>.txt (with the host name in place of the placeholder).

Inside a directory inventory, some extensions are ignored. If you see no hosts at all, suspect the file name first. To put the host in the result file name, you can use the path itself as a template.

Play vars override the inventory

Create /root/ans/prec/p03.yml, plant svc_tier: play-vars in the play vars:, and measure web1. Use the inv-vars of step 2 as the inventory and leave the result in /root/ans/prec/out/03.txt.

The purpose is to see whether this place wins even though the inventory already has a value. Keep using the role as is and write only a new play.

The unexpected place — vars_files

Write svc_tier: vars-file in /root/ans/prec/vars/tier.yml, and make /root/ans/prec/p04.yml read that file with vars_files: while leaving play-vars in the play vars: exactly as in step 3. The result is /root/ans/prec/out/04.txt.

This is a place where what is written below beats what is written above. Leave both places in so the ranking shows, and do not delete the play vars.

The place that is hard to override from outside — role vars

Create a second measuring role in /root/ans/prec/roles/probe_locked/. Put svc_tier: role-vars in vars/main.yml (put only probe_out in defaults), and write tasks/main.yml the same as probe. Have /root/ans/prec/p05.yml keep the same two places as in step 4 and call this role, leaving /root/ans/prec/out/05.txt.

Even inside the same role directory, defaults and vars have opposite characters. One is at the very bottom and the other is far above. That is why you create a new role separately — probe stays as the gauge that measures the bottom place.

The narrower, the higher — block and task

Create /root/ans/prec/p06.yml. The play reads tier.yml with vars_files: and attaches vars: {svc_tier: block-vars} to a block. The first task in the block calls the probe_locked role and leaves /root/ans/prec/out/06-block.txt, and the second task attaches svc_tier: task-vars to its own vars: and writes the value to /root/ans/prec/out/06-task.txt.

When you call a role inside a block, the block variables are layered on top of the role vars. The second task may write the file directly without going through a role — what you are measuring is the place, not the role.

A value created during execution and a parameter passed to a role

Create /root/ans/prec/p07.yml. First set svc_tier: set-fact with set_fact, then have a task with task-vars attached in its task vars: write the value to /root/ans/prec/out/07-setfact.txt, and finally call the probe_locked role passing svc_tier: role-param and leave /root/ans/prec/out/07-roleparam.txt.

A value set during execution is higher than the places written in advance. But there is one more above it — the value passed when calling a role.

The command line, the dictionary, and the ranking table

Put base_limits and svc_limits as {cpu: "1", memory: 1Gi} in /root/ans/prec/vars/limits.yml, and make /root/ans/prec/p08.yml write the command-line value to /root/ans/prec/out/08.txt when run with -e svc_tier=extra-vars. In the same playbook, leave the result of giving svc_limits: {memory: 2Gi} through task vars: and the result merged with combine in /root/ans/prec/out/08-hash.json under the two keys replaced and combined, and write the measurement results of the twelve places as a table in /root/ans/prec/out/rank.md.

To see whether the command-line value really wins, the other places must also be left in the play. In the table, write one line per place starting from the lowest, and in each line write the value measured at that place — the outputs of the earlier steps are your evidence.