Abstract
| Goal | Perform complex tasks with loops, variables, conditions, roles, and templates. |
| Objectives |
|
| Sections |
|
| Lab |
Parameterizing Automation |
After completing this section, you should be able to:
Manage variables in Ansible projects.
Explain variable precedence.
Variable names must start with a letter and may only contain letters, numbers, and underscores.
The following are valid Ansible variable names:
network
Net7Work
net_work
The following are not valid Ansible variable names:
net-work
7network
net@work
Where and how variables are defined affects their scope and precedence.
| Description | Scope |
|---|---|
Extra variables, set on the command line: -e name=value | global |
"vars_files" variables, set in the vars_files block in the play | play |
Play variables, set in the vars block in the play | play |
| Host facts, typically gathered when play starts | host |
Host variables, set in host_vars/host.yml | host |
Group variables, set in group_vars/group.yml | host |
Role variables, set in roles/ | role |
This is a simplified view of the relative precedence of different kinds of variables.
There are many more types.
Extra variables override vars_files variables, which override play variables, which override host facts, and so forth.
Ansible variable substitution uses the Jinja2 templating system. Variable names enclosed in curly braces are replaced during evaluation with values.
---
- name: trace the path from source (remote host) to trace_me
hosts: cs01
gather_facts: no
vars:
trace_me: 172.25.250.254
tasks:
- name: trace the path from {{ inventory_hostname }} to {{ trace_me }}
ios_command:
commands:
- traceroute {{ trace_me }}
register: path
- name: show the path from {{ inventory_hostname }} to {{ trace_me }}
debug:
msg: "{{ path }}"Ordinarily, YAML syntax does not care whether strings are quoted or not. The double braces used by Jinja2, though, are similar enough to a YAML construct for notating mappings to confuse the YAML parser when the variable is the first element of a value.
debug:
msg: {{ output_from_show_command }}
^ here
We could be wrong, but this one looks like it might be an issue with
missing quotes. Always quote template expression brackets when they
start a value. For instance:
with_items:
- {{ foo }}
Should be written as:
with_items:
- "{{ foo }}"If the value starts with a brace, quote the string. Avoid unwarranted quoting, which could cause quotes to be interpreted as data.
The connection modules used to connect to networking devices run Ansible's built-in, Python-based, fact-gathering system on the control node (localhost).
You see that this is the case if you run an ad hoc command using the setup module: the data returned refers to the control node (localhost), not the network device.
[user@host ~]$ansible -m setupnetwork-device-host-inventory-identifier
When network devices are targeted by plays, turn off Ansible's built-in fact gathering. This disables fact gathering in a play:
- hosts: network-devices gather_facts: no
Facts are available for networking devices by way of platform specific *os_facts modules, such as ios_facts, iosxr_facts, nxos_facts, vyos_facts, junos_facts, and so forth.
Ansible provides some predefined variables that are automatically set. Some of the better known magic variables are listed below. For the full list, see http://docs.ansible.com/ansible/playbooks_variables.html.
| Variable name | Description |
|---|---|
hostvars | Contains the variables for managed hosts, and can be used to get the values for another managed host's variables. It does not include the managed host's facts if they have not been gathered yet for that host. |
group_names | Lists all groups the current managed host is in. |
groups | Lists all groups and hosts in the inventory. |
inventory_hostname | Contains the host name for the current managed host as configured in the inventory. This may be different from the host name reported by facts for various reasons. |
The debug module prints messages while plays are executing.
It can be useful for debugging variables or expressions.
- debug:
msg: >
"{{ansible_net_hostname}} is {{ansible_net_model}}
running {{ansible_net_version}}"
The debug module could be used, for instance, to see values assumed by magic variables in a particular context in playbooks created for this purpose.
- debug:
msg: "{{ role_names }} and {{ vars }}"
The register keyword is used in the context of a playbook task.
It saves the result of a task to a variable.
Like facts, registered variables have host scope.
---
- name: >
play for ios devices
that uses commands
to examine indicators
hosts: ios
gather_facts: no
tasks:
- name: look at indicators
ios_command:
commands:
- sh ver | include uptime
- sh ip domain
- sh clock
- sh ip name-server
- sh proc mem | include Total
register: results
- name: show results
debug:
var: results.stdoutPLAY [play for ios devices that uses commands to examine indicators] *******
TASK [look at indicators] **************************************************
ok: [cs01]
TASK [show results] ********************************************************
ok: [cs01] => {
"results.stdout": [
"cs01 uptime is 3 hours, 12 minutes",
"lab.example.com",
"*01:09:01.866 UTC Sun Jun 3 2018",
"255.255.255.255",
"Processor Pool Total: 2202704640 Used: 250994304 Free:
1951710336\n lsmpi_io Pool Total: 6295128 Used: 6294296 Free:
832\n 257260704 Total"
]
}
PLAY RECAP *****************************************************************!
cs01 : ok=2 changed=0 unreachable=0 failed=0
You are probably already familiar with the CLI for a given network OS, but *os_facts modules provide easy access to important facts.
This example is for the ios_facts module, where interesting facts show up listed under # hardware.
$ansible-doc ios_facts | sed -n '/^# hardware/,/^$/p'# hardwareansible_net_filesystems:description: All file system names available on the device returned: when hardware is configured type: listansible_net_memfree_mb:description: The available free memory on the remote device in Mb returned: when hardware is configured type: intansible_net_memtotal_mb:description: The total memory on the remote device in Mb returned: when hardware is configured type: int
The *os_facts modules handle variable registration for you.
This example uses the hardware subset that you learned about from ansible-doc ios_facts.
---
- name: >
play for ios devices
that uses ios_facts
hosts: ios
gather_facts: no
tasks:
- name: look at some facts
ios_facts:
gather_subset:
- hardware
- name: show results
debug:
msg:
- "filesystems: {{ ansible_net_filesystems }}"
- "free mem MB: {{ ansible_net_memfree_mb }}"
- "mem total MB: {{ ansible_net_memtotal_mb }}"PLAY [play for ios devices that uses ios_facts] ****
TASK [look at some facts] **************************
ok: [cs01]
TASK [show results] ********************************
ok: [cs01] => {
"msg": [
"filesystems: [u'bootflash:']",
"free mem MB: 1905270",
"mem total MB: 2151078"
]
}
PLAY RECAP *****************************************
cs01 : ok=2 changed=0 unreachable=0 failed=0