
We automate and speed up the process of setting up cloud servers with Ansible. Part 3: Variables and inventory file
In the first part, we started exploring Ansible, a popular tool for automating the configuration and deployment of IT infrastructure. Ansible has been successfully installed, the principles of operation, basic configuration are described. At the end of the article, we showed how to quickly install nginx on several servers.
In the second part, we figured out the output of a playbook, learned how to debug and reuse Ansible scripts.

In this part, you will learn how to write a single Ansible playbook for different operating systems (for example, with rpm and deb), how to serve many hosts and not write all of them in inventory, how to group servers by InfoboxCloud regions and much more.
Variables are used to store values that can be used in a playbook. During use, variables can be redefined many times. Server information from inventory can also be used as variables.
There are several ways to define variables in Ansible:
The need to use variables is excellently demonstrated by the Apache installation example. The fact is that in different distributions, the package with apache is called differently. The difference in the configurations of different operating systems is quite common.
For instance:
The task sets the package_name variable to httpd or apache2 depending on the OS family on the server.
Variables can be used to set user values during the execution of a playbook:
It is convenient to save a list of values into variables for reuse. If the same variable is used in many playbooks, using them will reduce the complexity of the scripts.
All variables in Ansible must begin with a letter. You can use letters, numbers, and underscores in the name.
Variables defined in include files will overload (replace) variables defined at other levels of the hierarchy, except for variables passed through --extra-vars .
Let's look at how you can use variables from files imported into a playbook.
Let's create a separate Apache installation task file (~ / ansible / playbooks / tasks / pkg_apache_install.yml ):
We include it in the Apache installation file and verify that the service is running (~ / ansible / setup_apache.yml ):
As we can see, in the setup_apache.yml file we successfully use the variable defined in the included file. This playbook will correctly install apache on both rpm distributions and deb using the correct package name with apache.

Variables in the playbook are set using the vars: keyword . Variables are set as variable_name: value. Variables will overload other variables that are set in the global file or in inventory.
An example of a variable description in a playbook:
Variables in Ansible can be set in a separate file, which allows you to separate data from the playbook. You can create as many variable files as necessary, you just need to tell the playbook where to look for them. The format for defining variables in a file is similar to the format for defining variables in a Playbook.
~ / ansible / common / vars / global.yml
In this example, we set the package_name variable directly (after # you can write a comment), and we look for access keys for the InfoboxCloud API in the environment variables using the lookup plugin.
In the playbook, the path to the variable files is set via vars_files:
You can use any fact as a variable that is collected at gather_facts. To get a list of all the facts for a specific group of machines, use the command:
, where experiments is the name of a group of machines in inventory.
In the first part, we briefly looked at a simple inventory file. Let's look at it more closely.
Simple inventory (~ / ansible / inventory ):
You can simply record the hostnames and ip addresses and all servers will be used when playing the playbook with this inventory file.
We also saw the use of groups earlier:
The group for execution of the playbook is indicated in the "hosts:" section of the playbook
If you want to use a specific host, you can transfer it to the hosts section.
If you want to use all the hosts of all groups - you can use
A very useful feature that allows, for example, to group hosts not only by purpose, but also by region, which is very important for InfoboxCloud (Moscow, Amsterdam). Often there are other tasks where you need to use group groups.
In this example, the web my group includes servers in Moscow and Amsterdam. From the playbook, you can access both the web group and server groups in a specific region.
If you have a large number of servers, using naming conventions (eg web001, web002 ... web00N) will make it easier to specify them in inventory. You can use regular expressions in the inventory file:
where web [001: 200] will correspond to web 001, web002, web003, web004, ..., web199, web200 for the web group;
db [001: 020] will correspond to db001, db002, db003 ..., db019, db020 for the db group.
192.168.2. [1:30] will correspond to 192.168.2.1, 192.168.2.2, 192.168.2.3 for the balancer group.
The methods for setting variables discussed earlier applied them immediately to all hosts in inventory. Sometimes it may be necessary to use specific variables for a specific group of hosts or a specific host.
Setting variables for specific hosts:
Setting variables for a group of hosts (web):
You can create variable files for hosts and for groups. Folders with these files should be in the same directory as the inventory file. Files of variables related to specific hosts must be saved in the host_vars folder related to specific groups - to the group_vars folder.
An example variable file for the web001 host (~ / ansible / host_vars / web001):
Example variable file for a db group (~ / ansible / group_vars / db):
Inventory variables follow a hierarchy: the variables in the global file overload any host variables, group variables, and variables in the inventory file. Host variables overload group variables, and in turn group variables overload inventory file variables.
Through ansible.cfg can override Ansible configuration.
The writing of the article was greatly helped by the book Learning Ansible and of course the official documentation .
All experiments with Ansible are conveniently carried out in InfoboxCloud , since it is possible for each virtual server to set exactly the amount of resources that is necessary for the task (CPU / Ram / disk independently of each other) or use autoscaling, rather than choosing a VM from ready-made templates. When experiments are not carried out - you can just turn off the VM and pay only the cost of the disk.
If you find a mistake in the article, the author will gladly correct it. Please write to the PM or e-mail about it. There you can ask questions about Ansible for coverage in subsequent articles.
Part 4: working with modules
Part 5: local_action, conditions, loops and roles
Success!
In the second part, we figured out the output of a playbook, learned how to debug and reuse Ansible scripts.

In this part, you will learn how to write a single Ansible playbook for different operating systems (for example, with rpm and deb), how to serve many hosts and not write all of them in inventory, how to group servers by InfoboxCloud regions and much more.
Variables in Ansible
Variables are used to store values that can be used in a playbook. During use, variables can be redefined many times. Server information from inventory can also be used as variables.
There are several ways to define variables in Ansible:
- variable file transfer
- defining variables in a playbook
- transfer to ansible-playbook using the -e / --extra-vars command
- definition of variables in inventory file
The need to use variables is excellently demonstrated by the Apache installation example. The fact is that in different distributions, the package with apache is called differently. The difference in the configurations of different operating systems is quite common.
For instance:
- set_fact package_name=httpd
when: ansible_os_family == "Redhat"
- set_fact package_name=apache2
when: ansible_os_family == "Debian"
The task sets the package_name variable to httpd or apache2 depending on the OS family on the server.
Variables can be used to set user values during the execution of a playbook:
- name: Package to install
pause: prompt="Provide the package name which you want to install "
register: package_name
It is convenient to save a list of values into variables for reuse. If the same variable is used in many playbooks, using them will reduce the complexity of the scripts.
All variables in Ansible must begin with a letter. You can use letters, numbers, and underscores in the name.
Variables defined in include files will overload (replace) variables defined at other levels of the hierarchy, except for variables passed through --extra-vars .
Variables in Imported Files
Let's look at how you can use variables from files imported into a playbook.
Let's create a separate Apache installation task file (~ / ansible / playbooks / tasks / pkg_apache_install.yml ):
- set_fact: package_name=httpd
when: ansible_os_family == "Redhat"
- set_fact: package_name=apache2
when: ansible_os_family == "Debian"
- name: Install httpd package
yum: name=httpd state=latest
sudo: yes
when: ansible_os_family == "Redhat"
- name: Install apache2 package
apt: name=apache2 state=latest
sudo: yes
when: ansible_os_family == "Debian"
We include it in the Apache installation file and verify that the service is running (~ / ansible / setup_apache.yml ):
---
- hosts: experiments
remote_user: root
tasks:
- include: tasks/pkg_apache_install.yml
- name: Check apache service
service: name={{ package_name }} state=started
sudo: yes
As we can see, in the setup_apache.yml file we successfully use the variable defined in the included file. This playbook will correctly install apache on both rpm distributions and deb using the correct package name with apache.

Variables in a playbook
Variables in the playbook are set using the vars: keyword . Variables are set as variable_name: value. Variables will overload other variables that are set in the global file or in inventory.
An example of a variable description in a playbook:
vars:
- package_name: "httpd"
Variables in a Global File
Variables in Ansible can be set in a separate file, which allows you to separate data from the playbook. You can create as many variable files as necessary, you just need to tell the playbook where to look for them. The format for defining variables in a file is similar to the format for defining variables in a Playbook.
~ / ansible / common / vars / global.yml
---
package_name: "httpd" #Apache
#Enviroment variables
proxy_env:
INFOBOXCLOUD_API_KEY: "{{ lookup('env', 'INFOBOXCLOUD_API_KEY') }}"
INFOBOXCLOUD_LOGIN: "{{ ('env', 'INFOBOXCLOUD_LOGIN') }}"
In this example, we set the package_name variable directly (after # you can write a comment), and we look for access keys for the InfoboxCloud API in the environment variables using the lookup plugin.
In the playbook, the path to the variable files is set via vars_files:
vars_files:
- var1.yml
- var2.yml
Using facts as variables
You can use any fact as a variable that is collected at gather_facts. To get a list of all the facts for a specific group of machines, use the command:
ansible experiments -i inventory -m setup
, where experiments is the name of a group of machines in inventory.
Diving into the inventory file
In the first part, we briefly looked at a simple inventory file. Let's look at it more closely.
Simple inventory (~ / ansible / inventory ):
ansible.trukhin.com
77.221.144.179
You can simply record the hostnames and ip addresses and all servers will be used when playing the playbook with this inventory file.
Groups in inventory
We also saw the use of groups earlier:
[my]
ansible.trukhin.com
ansible2.trukhin.com
[corp]
ansible.sandbox.infoboxcloud.ru
ansible2.sandbox.infoboxcloud.ru
The group for execution of the playbook is indicated in the "hosts:" section of the playbook
hosts: my
If you want to use a specific host, you can transfer it to the hosts section.
hosts: ansible.trukhin.com
If you want to use all the hosts of all groups - you can use
hosts: all
Group Groups in inventory
A very useful feature that allows, for example, to group hosts not only by purpose, but also by region, which is very important for InfoboxCloud (Moscow, Amsterdam). Often there are other tasks where you need to use group groups.
[msk]
webMSK.trukhin.com
dbMSK.trukhin.com
[ams]
webAMS.trukhin.com
dbAMS.trukhin.com
[web:children]
msk
ams
In this example, the web my group includes servers in Moscow and Amsterdam. From the playbook, you can access both the web group and server groups in a specific region.
Regular expressions in inventory
If you have a large number of servers, using naming conventions (eg web001, web002 ... web00N) will make it easier to specify them in inventory. You can use regular expressions in the inventory file:
[web]
web[001:200]
[db]
db[001:020]
[balancer]
192.168.2.[1:3]
where web [001: 200] will correspond to web 001, web002, web003, web004, ..., web199, web200 for the web group;
db [001: 020] will correspond to db001, db002, db003 ..., db019, db020 for the db group.
192.168.2. [1:30] will correspond to 192.168.2.1, 192.168.2.2, 192.168.2.3 for the balancer group.
Variables in inventory file
The methods for setting variables discussed earlier applied them immediately to all hosts in inventory. Sometimes it may be necessary to use specific variables for a specific group of hosts or a specific host.
Setting variables for specific hosts:
ansible.trukhin.com
web001
db001 db_name=mysql
192.168.2.1 db_name=redis db_port=6380
Setting variables for a group of hosts (web):
[web]
web[001:010]
[db]
db[001:002]
[web:vars]
web_port=443
Removing variables into separate files for inventory
You can create variable files for hosts and for groups. Folders with these files should be in the same directory as the inventory file. Files of variables related to specific hosts must be saved in the host_vars folder related to specific groups - to the group_vars folder.
An example variable file for the web001 host (~ / ansible / host_vars / web001):
web_port_ssl=443
web_port=80
Example variable file for a db group (~ / ansible / group_vars / db):
db_port=6380
db_name=redis
Inventory variables follow a hierarchy: the variables in the global file overload any host variables, group variables, and variables in the inventory file. Host variables overload group variables, and in turn group variables overload inventory file variables.
Through ansible.cfg can override Ansible configuration.
Conclusion
The writing of the article was greatly helped by the book Learning Ansible and of course the official documentation .
All experiments with Ansible are conveniently carried out in InfoboxCloud , since it is possible for each virtual server to set exactly the amount of resources that is necessary for the task (CPU / Ram / disk independently of each other) or use autoscaling, rather than choosing a VM from ready-made templates. When experiments are not carried out - you can just turn off the VM and pay only the cost of the disk.
If you find a mistake in the article, the author will gladly correct it. Please write to the PM or e-mail about it. There you can ask questions about Ansible for coverage in subsequent articles.
Part 4: working with modules
Part 5: local_action, conditions, loops and roles
Success!