Vars
A variable could be, for example:
- device information that is collected as a fact and then used in the template.
- you can write the received output of the command to variables.
- the variable can be specified manually in the playbook
Variable names
Ansible has certain restrictions on the format of variable names:
- Variables can consist of letters, numbers and the _ symbol
- Variables must start with a letter
In addition, you can create dictionaries with variables (in YAML format):
SWITCH1:
IP: 192.168.1.12/24
Gateway: 192.168.1.1
There are two ways to access variables in a dictionary:
SWITCH1[‘IP’]
SWITCH1.IP
But when using the second option, there may be problems if the name of the key matches a reserved word (method or attribute) in Python or Ansible.
Where to define variables
Variables can be created:
- in inventory file
- in playbook
- in special files for group/device
- in separate files that are added to the playbook via include (as in Jinja2)
- in roles that are then used
- it is even possible to pass variables when calling playbook
It is also possible to use the facts that have been collected about the device as variables.
Variables in the inventory file
[cisco-routers]
192.168.0.1
192.168.0.2
192.168.0.3
[cisco-switches]
192.168.0.100
[cisco-routers:vars]
ntp_server=192.168.25.10
log_server=192.168.25.100
The variables ntp_server and log_server refer to the cisco-routers group and can be used, for example, when generating a configuration based on a template.
Variables in playbook
Variables can be set directly in the playbook. This can be convenient because the variables are in the same place as all the actions.
For example, you can set the ntp_server and log_server variables in the playbook like this:
---
- name: Run show commands on routers
hosts: cisco-routers
gather_facts: false
vars:
ntp_server: 192.168.25.10
log_server: 192.168.25.100
tasks:
- name: run sh ip int br
raw: sh ip int br | ex unass
- name: run sh ip route
raw: sh ip route
Variables in special files for the group/devices
Ansible allows you to store group/device variables in special files:
- For device groups, the variables must be in the group_vars directory, in files named after the group name. You can create an all file in the group_vars directory, which will contain variables that apply to all groups.
- For specific devices, the variables must be in the host_vars directory, in files that match the host name or address.
- All variable files must be in YAML format. The file extension can be: yml, yaml, json or no extension
- The group_vars and host_vars directories must be in the same directory as the playbook, or they can be inside the inventory directory (the former is more common). If the directories and files are named correctly and located in the specified directories, Ansible will recognize the files itself and will use the variables
For example, if the myinventory inventory file looks like this:
[cisco-routers]
192.168.0.1
192.168.0.2
192.168.0.3
[cisco-switches]
192.168.0.100
You can create a directory structure like this:
├── group_vars _
│ ├── all.yml |
│ ├── cisco-routers.yml | Directory with variables for device groups
│ └── cisco-switches.yml _|
|
├── host_vars _
│ ├── 192.168.0.1 |
│ ├── 192.168.0.2 |
│ ├── 192.168.0.3 | Directory with variables for devices
│ └── 192.168.0.100 _|
|
└── myinventory | Inventory file
Below is an example of the contents of variable files for groups of devices and for individual hosts. group_vars/all.yml (this file contains default values that apply to all devices):
---
cli:
host: "{{ inventory_hostname }}"
username: "cisco"
password: "password"
authorize: yes
auth_pass: "cisco"
The cli dictionary is created in the group_vars/all.yml file. This dictionary lists the arguments that must be given to work with network equipment through built-in Ansible modules.
inventory_hostname is a special variable that points to the host that Ansible is performing actions on.
The syntax {{ inventory_hostname }} is variable substitution. The Jinja format is used.
group_vars/cisco-routers.yml
---
ntp_server: 192.168.25.10
log_server: 192.168.25.100
users:
user1: pass1
user2: pass2
user3: pass3
group_vars/cisco-switches.yml
---
vlans:
- 2
- 3
The group_vars/cisco-switches.yml file contains the vlans variable with a list of VLANs.
Files with variables for hosts are of the same type, and only addresses and names change in them:
File host_vars/192.168.0.1
---
hostname: r1
mgmnt_loopback: 100
mgmnt_ip: 10.0.0.1
ospf_ints:
- 192.168.0.1
- 10.0.0.1
- 10.255.1.1
File host_vars/192.168.0.2
---
hostname: r2
mgmnt_loopback: 100
mgmnt_ip: 10.0.0.2
ospf_ints:
- 192.168.0.2
- 10.0.0.2
- 10.255.2.2
File host_vars/192.168.0.3
---
hostname: r3
mgmnt_loopback: 100
mgmnt_ip: 10.0.0.3
ospf_ints:
- 192.168.0.3
- 10.0.0.3
- 10.255.3.3
Variables precedence in ansible
Most often, there is only one variable with a specific name. But sometimes you may need to create a variable in different places, and then you need to understand in what order Ansible overwrites the variables.
Variable precedence (last values override previous ones):
- variable values in roles(tasks in roles will see their own values. Tasks that are defined outside of the role will see the latest values of the role variables)
- variables in the inventory file
- variables for a group of hosts in the inventory file
- variables for hosts in the inventory file
- variables in the group_vars directory
- variables in the host_vars directory
- host facts
- script variables (play)
- script variables that are requested via vars_prompt
- variables that are passed to the script via vars_files
- variables received via the register parameter
- set_facts
- variables from role and placed via include
- block variables (overwrite other block-only values)
- task variables (overwrite other values for task only)
- variables that are passed when calling the playbook via the –extra-vars parameter (always the highest priority)