TT Lab
Get started
Learn Learning paths Courses

Ansible Fundamentals

Variable Precedence and Working With Facts

Continue in TT Lab

Goal

You separate values from the code, place them in several locations, and check for yourself which one wins. You also handle values obtained during the run through facts and register.

Why it matters

The answer to the question "I changed the variable but it doesn't take effect" is almost always precedence. Ansible accepts variables of the same name in several places, and even when they conflict, it raises no error and quietly uses the stronger one. This property is convenient but makes debugging hard. So you need a design sense of putting values that may be overridden in a weak place (a role's defaults) and values that must be kept in a strong place. Command-line -e beats everything but is recorded nowhere, so if you used it during incident response, you must bring it back into the code. Otherwise the next deployment quietly wipes that value out.

Steps

  1. Create /root/ans/vars/site.yml and, in the play's vars:, define app_name: checkout. Write that value to /root/ans/vars/out/app_name.txt.
  2. In /root/ans/vars/vars/common.yml, put app_port: 9090 and load it with vars_files. Write the value to /root/ans/vars/out/app_port.txt.
  3. In /root/ans/inventory/group_vars/web.yml put node_role: frontend, and in /root/ans/inventory/host_vars/web1.yml put node_role: canary. The two directories must be in the same place as the /root/ans/inventory/hosts.ini you made in the first lab to be read automatically. It must show as frontend on web2 and as canary on web1.
  4. Run a command, receive the result with register, and then save only the standard output to /root/ans/vars/out/uptime.txt.
  5. Turn on gather_facts and save JSON containing the host name, architecture, and system from the collected facts to /root/ans/vars/out/facts.json.
  6. Run with -e app_port=9999 and save that value to /root/ans/vars/out/precedence.txt. The app_port.txt you made in step 2 must still be 9090.
  7. Use set_fact to build a value that joins app_name and app_port, and save it to /root/ans/vars/out/endpoint.txt in the form checkout:9090.
  8. Create /root/ans/vars/out/summary.json. It must have four keys: app (=checkout), port (=9090), role (the value of web1's host variable), and host (the host name from the collected facts).

Notes

Define and use a play variable

Create /root/ans/vars/site.yml and, in the play's vars:, define app_name: checkout. Write that value to /root/ans/vars/out/app_name.txt.

Put the value under the play's vars: and reference it with Jinja2 in the content of the copy module.

Split out a variable file

In /root/ans/vars/vars/common.yml, put app_port: 9090 and load it with vars_files. Write the value to /root/ans/vars/out/app_port.txt.

vars_files: is a list of paths. As values grow in number, it is customary to detach them from the play.

Create group variables and host variables

In /root/ans/inventory/group_vars/web.yml put node_role: frontend, and in /root/ans/inventory/host_vars/web1.yml put node_role: canary. The two directories must be in the same place as the /root/ans/inventory/hosts.ini you made in the first lab to be read automatically. It must show as frontend on web2 and as canary on web1.

The directory name is the rule. The file name under group_vars is the group name, and under host_vars it is the host name.

Store a command result in a variable

Run a command, receive the result with register, and then save only the standard output to /root/ans/vars/out/uptime.txt.

What you receive with register is an object. Put only its standard output in the file.

Collect facts and save them as JSON

Turn on gather_facts and save JSON containing the host name, architecture, and system from the collected facts to /root/ans/vars/out/facts.json.

Turn on gather_facts, pick part of ansible_facts, and write it as JSON. The to_nice_json filter helps.

Override with a command-line variable

Run with -e app_port=9999 and save that value to /root/ans/vars/out/precedence.txt. The app_port.txt you made in step 2 must still be 9090.

The value passed with -e is the strongest. Do not overwrite the file you saved in the earlier step; leave it under a different name.

Combine values with set_fact

Use set_fact to build a value that joins app_name and app_port, and save it to /root/ans/vars/out/endpoint.txt in the form checkout:9090.

Build a new value that joins the two variables and write it to the file. The format is 이름:포트 (name, a colon, then port).

Build a summary combining variables, facts, and host variables

Create /root/ans/vars/out/summary.json. It must have four keys: app (=checkout), port (=9090), role (the value of web1's host variable), and host (the host name from the collected facts).

Build JSON with four keys (app, port, role, host). role comes from web1's host variable, and host comes from the collected facts.