Accessing Ansible Variables with Jinja2 Loops

Referencing variables in your templates is a great way to keep your Ansible playbook logic separate from your data. When a variable value changes, you simply reflect that change in your variables file instead of having to make any changes to your actual template.

The concept above will work fine for you if you are just referencing a few variables whose values rarely change. But what if you are creating custom templates for applications that contain both the variable names and values? In addition to that, what if those variable names along with the actual number of variables are constantly changing (imagine a template for a web application that is under heavy development)? You may soon realize that constantly trying to update your templates to reflect these changes is a tedious process.

Fortunately, there is a solution to this problem, and it comes in the form of a Jinja2 for loop. In this post, we are going to take a look at a few examples of Jinja2 for loops. The first example will be a solution to the problem I described above while the rest of the examples will simply show you how to loop through different structures. Let's get started!

If your variables file contains a dictionary that looks like this:

common_vars:
  customer_variable_1: custom_value_1
  customer_variable_2: custom_value_2
  customer_variable_3: custom_value_3

You can loop through it like this:

{% for k, v in common_vars.iteritems() %}
testing {{ k }}={{ v }}
{% endfor %}

By doing this, you would end up with the following template:

  testing customer_variable_1=custom_value_1
  testing customer_variable_2=custom_value_2
  testing customer_variable_3=custom_value_3

Not too bad, right? Now, regardless of how many variables there are and how they are named, you can make all your changes directly in your variables file without having to touch your template.

Having examined the previous example, let's move to a simpler scenario. Imagine your variables file contains a dictionary that has two lists of dictionaries in it:

people:

  - name: John
    role: Linux Admin

  - name: Ben
    role: Windows Admin

You would loop through such a structure as follows:

{% for x in people %}
{{ x.name }} is a {{ x.role }}
{% endfor %}

The previous loop would render the following template:

John is a Linux Admin
Ben is a Windows Admin

You can use the concept from the previous example to configure a template with database servers and their URLs. The practical applications of this type of loop can vary greatly from environment to environment.

Let's move to our final (and probably easiest) example. It requires us to loop through a list as follows:

distros:
  - Ubuntu
  - CentOS
  - Fedora

You can loop through it like this:

{% for i in distros %}
{{ i }} is Linux distribution
{% endfor %}

This ends up rendering the following template:

Ubuntu is a Linux distribution
CentOS is a Linux distribution
Fedora is a Linux distribution

As for practical applications, I'll leave this last one up for you to play around with ; )

These are just a few ways that I have used Jinja2 loops to access variables in my Ansible playbooks. I hope you have found this post useful.