Variables are a key component of the Ansible design. Variables allow for dynamic play content and reusable plays across different sets of inventory. Anything beyond the very basics of Ansible use will utilize variables. Understanding the different variable types and where they can be located, as well as learning how to access external data or prompt users to populate variable data, is the key to mastering Ansible.
Before diving into the precedence of variables, we must first understand the various types and subtypes of variables available to Ansible, their location, and where they are valid for use.
The first major variable type is inventory
variables. These are the variables that Ansible gets by way of the inventory. These can be defined as variables that are specific to host_vars
to individual hosts or applicable to entire groups as group_vars
. These variables can be written directly into the inventory file, delivered by the dynamic inventory plugin, or loaded from the host_vars/<host>
or group_vars/<group>
directories.
These types of variables might be used to define Ansible behavior when dealing with these hosts, or site-specific data related to the applications that these hosts run. Whether a variable comes from host_vars
or group_vars
, it will be assigned to a host's hostvars
, and it can be accessed from the playbooks and template files. Accessing a host's own variables can be done just by referencing the name, such as {{ foobar }}
, and accessing another host's variables can be accomplished by accessing hostvars
. For example, to access the foobar
variable for examplehost: {{ hostvars['examplehost']['foobar'] }}
. These variables have global scope.
The second major variable type is role variables. These are variables specific to a role that are utilized by the role tasks and have scope only within the role that they are defined in, which is to say that they can only be used within the role. These variables are often supplied as a role default, and are meant to provide a default value for the variable, but can easily be overridden when applying the role. When roles are referenced, it is possible to supply variable data at the same time, either by overriding role defaults or creating wholly new data. We'll cover roles in-depth in later chapters. These variables apply to all hosts within the role and can be accessed directly, much like a host's own hostvars
.
The third major variable type is play variables. These variables are defined in the control keys of a play, either directly by the vars
key or sourced from external files via the vars_files
key. Additionally, the play can interactively prompt the user for variable data using vars_prompt
. These variables are to be used within the scope of the play and in any tasks or included tasks of the play. The variables apply to all hosts within the play and can be referenced as if they are hostvars
.
The fourth variable type is task
variables. Task variables are made from data discovered while executing tasks or in the fact gathering phase of a play. These variables are host-specific and are added to the host's hostvars
and can be used as such, which also means they have global scope after the point at which they were discovered or defined. Variables of this type can be discovered via gather_facts
and fact modules (modules that do not alter state but rather return data), populated from task return data via the register
task key, or defined directly by a task making use of the set_fact
or add_host
modules. Data can also be interactively obtained from the operator using the prompt
argument to the pause
module and registering the result:
- name: get the operators name pause: prompt: "Please enter your name" register: opname
There is one last variable type, the extra variables, or extra-vars
type. These are variables supplied on the command line when executing ansible-playbook
via --extra-vars
. Variable data can be supplied as a list of key=value
pairs, a quoted JSON data, or a reference to a YAML-formatted file with variable data defined within:
--extra-vars "foo=bar owner=fred" --extra-vars '{"services":["nova-api","nova-conductor"]}' --extra-vars @/path/to/data.yaml
Extra variables are considered global variables. They apply to every host and have scope throughout the entire playbook.
Data for role variables, play variables, and task variables can also come from external sources. Ansible provides a mechanism to access and evaluate data from the
control machine (the machine running ansible-playbook
). The mechanism is called a lookup plugin, and a number of them come with Ansible. These plugins can be used to lookup or access data by reading files, generate and locally store passwords on the Ansible host for later reuse, evaluate environment variables, pipe data in from executables, access data in the Redis
or etcd
systems, render data from template files, query dnstxt
records, and more. The syntax is as follows:
lookup('<plugin_name>', 'plugin_argument')
for example, to use the mastery
value from etcd
in a debug task:
- name: show data from etcd debug: msg="{{ lookup('etcd', 'mastery') }}"
Lookups are evaluated when the task referencing them is executed, which allows for dynamic data discovery. To reuse a particular lookup in multiple tasks and reevaluate it each time, a playbook variable can be defined with a lookup value. Each time the playbook variable is referenced the lookup will be executed, potentially providing different values over time.