Workshop Exercise - Using Variables

Read this in other languages:
uk English, japan日本語, brazil Portugues do Brasil, france Française,Español Español.

Table of Contents


Ansible supports variables to store values that can be used in Playbooks. Variables can be defined in a variety of places and have a clear precedence. Ansible substitutes the variable with its value when a task is executed.

This exercise covers variables, specifically


Intro to Variables

Variables are referenced in Ansible Playbooks by placing the variable name in double curly braces:

Here comes a variable {{ variable1 }}

Variables and their values can be defined in various places: the inventory, additional files, on the command line, etc.

The recommended practice to provide variables in the inventory is to define them in files located in two directories named host_vars and group_vars:


Host variables take precedence over group variables (more about precedence can be found in the docs).

Step 1 - Create Variable Files

For understanding and practice let’s do a lab. Following up on the theme “Let’s build a web server. Or two. Or even more…​”, you will change the index.html to show the development environment (dev/prod) a server is deployed in.

On the ansible control host, as the student<X> user, create the directories to hold the variable definitions in ~/ansible-files/:

[student<X>@ansible-1 ansible-files]$ mkdir host_vars group_vars

Now create two files containing variable definitions. We’ll define a variable named stage which will point to different environments, dev or prod:

stage: dev
stage: prod

What is this about?

Step 2 - Create web.html Files

Now create two files in ~/ansible-files/files/:

One called prod_web.html with the following content:

<h1>This is a production webserver, take care!</h1>

And the other called dev_web.html with the following content:

<h1>This is a development webserver, have fun!</h1>

Step 3 - Create the Playbook

Now you need a Playbook that copies the prod or dev web.html file - according to the “stage” variable.

Create a new Playbook called deploy_index_html.yml in the ~/ansible-files/ directory.


Note how the variable “stage” is used in the name of the file to copy.

- name: Copy web.html
  hosts: web
  become: true
  - name: copy web.html
      src: "{{ stage }}_web.html"
      dest: /var/www/html/index.html
[student<X>@ansible-1 ansible-files]$ ansible-playbook deploy_index_html.yml

Step 4 - Test the Result

The Ansible Playbook copies different files as index.html to the hosts, use curl to test it.

For node1:

[student<X>@ansible-1 ansible-files]$ curl http://node1
<h1>This is a development webserver, have fun!</h1>

For node2:

[student<X>@ansible-1 ansible-files]$ curl http://node2
<h1>This is a production webserver, take care!</h1>

For node3:

[student<X>@ansible-1 ansible-files]$ curl http://node3
<h1>This is a development webserver, have fun!</h1>


If by now you think: There has to be a smarter way to change content in files…​ you are absolutely right. This lab was done to introduce variables, you are about to learn about templates in one of the next chapters.

Step 5 - Ansible Facts

Ansible facts are variables that are automatically discovered by Ansible from a managed host. Remember the “Gathering Facts” task listed in the output of each ansible-playbook execution? At that moment the facts are gathered for each managed nodes. Facts can also be pulled by the setup module. They contain useful information stored into variables that administrators can reuse.

To get an idea what facts Ansible collects by default, on your control node as your student user run:

[student<X>@ansible-1 ansible-files]$ ansible node1 -m setup

This might be a bit too much, you can use filters to limit the output to certain facts, the expression is shell-style wildcard:

[student<X>@ansible-1 ansible-files]$ ansible node1 -m setup -a 'filter=ansible_eth0'

Or what about only looking for memory related facts:

[student<X>@ansible-1 ansible-files]$ ansible node1 -m setup -a 'filter=ansible_*_mb'

Step 6 - Challenge Lab: Facts


Use grep to find the fact, then apply a filter to only print this fact.


Solution below!

[student<X>@ansible-1 ansible-files]$ ansible node1 -m setup|grep distribution
[student<X>@ansible-1 ansible-files]$ ansible node1 -m setup -a 'filter=ansible_distribution' -o

Step 7 - Using Facts in Playbooks

Facts can be used in a Playbook like variables, using the proper naming, of course. Create this Playbook as facts.yml in the ~/ansible-files/ directory:

- name: Output facts within a playbook
  hosts: all
  - name: Prints Ansible facts
      msg: The default IPv4 address of {{ ansible_fqdn }} is {{ ansible_default_ipv4.address }}


The “debug” module is handy for e.g. debugging variables or expressions.

Execute it to see how the facts are printed:

[student<X>@ansible-1 ansible-files]$ ansible-playbook facts.yml

PLAY [Output facts within a playbook] ******************************************

TASK [Gathering Facts] *********************************************************
ok: [node3]
ok: [node2]
ok: [node1]
ok: [ansible-1]

TASK [Prints Ansible facts] ****************************************************
ok: [node1] =>
  msg: The default IPv4 address of node1 is
ok: [node2] =>
  msg: The default IPv4 address of node2 is
ok: [node3] =>
  msg: The default IPv4 address of node3 is
ok: [ansible-1] =>
  msg: The default IPv4 address of ansible is

PLAY RECAP *********************************************************************
ansible-1                  : ok=2    changed=0    unreachable=0    failed=0
node1                      : ok=2    changed=0    unreachable=0    failed=0
node2                      : ok=2    changed=0    unreachable=0    failed=0
node3                      : ok=2    changed=0    unreachable=0    failed=0


Previous Exercise - Next Exercise

Click here to return to the Ansible for Red Hat Enterprise Linux Workshop