Reader small image

You're reading from  Mastering Ansible, 4th Edition - Fourth Edition

Product typeBook
Published inDec 2021
PublisherPackt
ISBN-139781801818780
Edition4th Edition
Right arrow
Authors (2):
James Freeman
James Freeman
author image
James Freeman

James Freeman is an accomplished IT professional with over 25 years' experience in the technology industry. He has more than a decade of first-hand experience in solving real-world enterprise problems in production environments using Ansible, open source, and AWS. As part of this work, he frequently introduces Ansible as a new technology to businesses and CTOs for the first time. In addition, he has co-authored five books and one video training course on Ansible, facilitated bespoke Ansible workshops and training sessions, and presented at both international conferences and meetups on Ansible.
Read more about James Freeman

Jesse Keating
Jesse Keating
author image
Jesse Keating

Jesse Keating is an accomplished Ansible user, contributor, and presenter. He has been an active member of the Linux and open source community for over 15 years. He has firsthand experience involving a variety of IT activities, software development, and large-scale system administration. He has presented at numerous conferences and meetups, and has written many articles on a variety of topics.
Read more about Jesse Keating

View More author details
Right arrow

Variable types and location

Variables are a key component of the Ansible design. Variables allow for dynamic play content and reusable plays across different sets of an inventory. Anything beyond the most basic 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 one of the keys to mastering Ansible.

Variable types

Before diving into the precedence of variables, first, we must understand the various types and subtypes of variables available to Ansible, their locations, 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 can 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 by simply 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, you can use {{ hostvars['examplehost']['foobar'] }}. These variables have global scope.

The second major variable type is role variables. These are variables that are specific to a role and are utilized by the role tasks. However, it should be noted that once a role has been added to a playbook, its variables are generally accessible throughout the rest of the playbook, including from within other roles. In most simple playbooks, this won't matter, as the roles are typically run one at a time. But it is worth remembering this as the playbook structure becomes more complex; otherwise, unexpected behavior could result from variables being set within a different role!

These variables are often supplied as a role default, that is, they 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 more depth in a later chapter. These variables apply to all hosts on which the role is executed 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 that has been 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 they can be used as such, which also means they have a global scope after the point in which they were discovered or defined. Variables of this type can be discovered via gather_facts and fact modules (that is, modules that do not alter state but instead 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 
  ansible.builtin.pause: 
    prompt: "Please enter your name" 
  register: opname 

The extra variables, or the extra-vars type, 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 piece of 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.

Magic variables

In addition to the previously listed variable types, Ansible offers a set of variables that deserve their own special mention – magic variables. These are variables that are always set when a playbook is run without them having to be explicitly created. Their names are always reserved and should not be used for other variables.

Magic variables are used to provide information about the current playbook run to the playbooks themselves and are extremely useful as Ansible environments become larger and more complex. For example, if one of your plays needs information about which groups the current host is in, the group_names magic variable returns a list of them. Similarly, if you need to configure the hostname for a service using Ansible, the inventory_hostname magic variable will return the current hostname as it is defined in the inventory. A simple example of this is as follows:

---
- name: demonstrate magic variables
  hosts: all
  gather_facts: false
  tasks:
    - name: tell us which host we are on
      ansible.builtin.debug:
        var: inventory_hostname
    - name: tell us which groups we are in
      ansible.builtin.debug:
        var: group_names

As with everything in the Ansible project, magic variables are well documented, and you can find a full list of them and what they contain in the official Ansible documentation at https://docs.ansible.com/ansible/latest/reference_appendices/special_variables.html. A practical example of the use of magic variables is this: imagine, for example, setting up the hostnames on a new set of Linux servers from a blank template. The inventory_hostname magic variable provides us with the hostname we need directly from the inventory, without the need for another source of data (or, for example, a connection to the CMDB). Similarly, accessing groups_names allows us to define which plays should be run on a given host within a single playbook – perhaps, for example, installing NGINX if the host is in the webservers group. In this way, Ansible code can be made more versatile and efficient; hence, these variables deserve a special mention.

Previous PageNext Page
You have been reading a chapter from
Mastering Ansible, 4th Edition - Fourth Edition
Published in: Dec 2021Publisher: PacktISBN-13: 9781801818780
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Authors (2)

author image
James Freeman

James Freeman is an accomplished IT professional with over 25 years' experience in the technology industry. He has more than a decade of first-hand experience in solving real-world enterprise problems in production environments using Ansible, open source, and AWS. As part of this work, he frequently introduces Ansible as a new technology to businesses and CTOs for the first time. In addition, he has co-authored five books and one video training course on Ansible, facilitated bespoke Ansible workshops and training sessions, and presented at both international conferences and meetups on Ansible.
Read more about James Freeman

author image
Jesse Keating

Jesse Keating is an accomplished Ansible user, contributor, and presenter. He has been an active member of the Linux and open source community for over 15 years. He has firsthand experience involving a variety of IT activities, software development, and large-scale system administration. He has presented at numerous conferences and meetups, and has written many articles on a variety of topics.
Read more about Jesse Keating