Looking at Ansible’s documentation on variable precedence makes my head spin a bit: there are many sources for variable data. ;-)
I’m repeating the rules here to avoid us having to flip back and forth:
- Variables loaded from YAML files mentioned in
vars_files
in a playbook. vars
as defined in the playbook.- facts, whether built in or custom, or variables assigned from the
register
keyword. - variables passed to parameterized task include statements.
- Host variables from inventory.
- Group variables from inventory, in order of least specific group to most specific.
I’m finding it difficult to get this into a decent diagram, so take this with a pinch or two of salt, please. I’ve also omitted a few sources of variables for “clarity”:
The further down we get in the diagram, the higher the precedence, i.e. variables declared further down overwrite values defined above.
The documentation states:
if you want to set a default value for something you wish to override somewhere else, the best place to set such a default is in a group variable.
and I agree: I can then override a variable on a per-host basis by creating a host_vars/hostname
file for example. (See also Michael DeHaan’s comment below.)
Register variables
In version 0.7 Ansible can store the output of a given command in a variable which I use later on in templates, say. The register keyword names the variable.
---
- hosts: 127.0.0.1
connection: local
vars:
- person: Jane Jolie
- filename: v1.j2
vars_files:
- vars.yml
tasks:
- name: Quien soy?
action: command /usr/bin/whoami
register: myname
- name: Run jpprog.sh
action: command ./jpprog.sh
register: v
- name: Populate template
action: template src={{filename}} dest=/tmp/out
This playbook runs two commands: the first stores its output in a variable called myname,
and the second in a variable v. The result of whoami is a single string which is
made available to the template as variablename.stdout
. The result of jpprog.sh is a
JSON object represented as a string:
{
"number": 18,
"name": "john"
}
The template follows:
-> I am {{ myname.stdout }}
{% set t = v.stdout|from_json %}
JSON struct T: {{ t }}
name = {{ t.name }}
number = {{ t['number'] }}
and the output is:
-> I am jpm
JSON struct T: {u'number': 18, u'name': u'john'}
name = john
number = 18
I thought extracting JSON from a command could be pretty useful and contributed a small patch earlier. Basically this is just a different way of obtaining facts: instead of writing a module we use register variables.