=======
Part 1 : Presentation and prerequisites
Part 2 : Basics and first Playbook
Part 3 : Variables
Part 4 : Collections
––
After a long break (and moving to Quebec!), here is the third part of the Ansible serie. This time I will try to do a shorter article by focusing on a single subject: variables!
The code regarding the examples is on GitHub
Variables
Dealing with variables in Ansible is probably one of the most complex aspect of the language. As it is possible to declare them in lot of places (22 to be precise). The list in the documentation specifies the overload order. We won’t use all the 22 places, otherwise our code would be difficult to understand. Now I will expose some examples about how to declare and use variables.
Inventory variables
First example, the ansible_host variable:
|
|
It’s a special one, but still a variable. The same way we can decalre another variable in the inventory file:
|
|
There are some restrictions about the characters we are allowed to use as a variable name: it must start with a letter, can contain a numbers, letters and underscores, but no space.
To be able to use the variable in the Playbook, it should make a reference to a host (or a group of host) in an inventory. In our case we have defined a variable for the host tig, if we want to use if we will have to run the playbook on this host. Here is an example:
|
|
To call a variable you must surround it by double curly braces. It’s the Jinja2 syntax.
You only have to quote the variable if it begins by the reference of it, otherwise you don’t.
In this example, it will work without it:
|
|
I would recommend to quote it anyway, like that you don’t have to ask yourself if you have to do it or not.
We use the debug module to do test, it’s the easy way!
After running the playbook, you should have the following result:
|
|
The previous example was a good way to see how you could use variables and the link between inventory hosts / groups and variables. But it’s important to remind it’s not the right way to deal with variables. You may want to use it some time, but usually there is a better way. We will get to it.
Inside the playbook
Another simple way to set and use a variable is to do it in the playbook itself. Again, this is not ideal, but it help to understand how it works.
We can use our previous example:
|
|
Arrays and dictionaries
We can also use classic arrays or dictionaries this way:
|
|
And use it in the Playbook:
|
|
We also can use an array of dictionaries:
|
|
And run through it:
|
|
The item
keyword represents each element of the array. More information here.
A global variable file
So now that we have overview some practical examples, let’s see how I personnaly recommand to organize the variables in a project.
There is no default place to store variables, but there are better places than others.
We always can create a variable file (anywhere) and import it manually, but there are ways to import it automatically if we place it in the right location:
- groups_vars/
- hosts_vars/
We will place a variable file in those folders. But we also have to name it after a group or a host in the inventory. In our case we will use the implicit group that contains all hosts: all. As it is a group, the file will be: group_vars/all.yml.
So here is our variable:
|
|
Using the variable with InfluxDB
In the previous article we made a Play to install InfluxDB, now we will go further with the database creation. It will be used later to store our vSphere metrics.
Here is the current Play :
|
|
This Play allows us to install InfluxDB and set the service to be started and to start automatically after a reboot.
When if InfluxDB start for the first time, the internal database is created, we will wait until it’s done before creating vSphere DB.
Here the Task that will do the verification:
|
|
It deserves a bit of an explanation here, first we use the uri module which allows us to make an API call (Rest in our case). We set three arguments:
- url to reach
- With Ansible, the module is run on the host, here it is the InfluxDB server so we can just set localhost
- method to use
- body to pass in the API call
More details on this module here.
Then you will have to analyze the JSON response by looking for the default database name (internal). It may take some time to be created, that’s why retry 5 times with 5 seconds in-between.
Then we can create the vSphere database with our variable we set earlier:
|
|
You add those two tasks into the Playbook and you are ready to run it:
|
|
Conclusion
Depending of your Ansible project size and possible evolution, you will rather prefer to limit the place you add variable to 2 or 3.
Personally, I like to organize myself with these rules:
- Inside roles (we will see that soon)
- Link to the inventory groups in group_vars/
- all but not only, I like to split variables inside dedicated group files
- In the inventory file
- Just for some specific variables, like ansible_host
See you next time for an article about Collections!