📜 ⬆️ ⬇️

Automate and speed up the process of setting up cloud servers with Ansible. Part 3: Variables and the inventory file

In the first part, we began the study of Ansible, a popular tool for automating the configuration and deployment of IT infrastructure. Ansible has been successfully installed, describes the principles of operation, the basic setting. At the end of the article we showed how to quickly install nginx on multiple servers.

In the second part, we sorted out the output of the playbook, learned how to debug and reuse the 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 maintain many hosts and not write them all 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. In the process of using variables, you can override it many times. Information about servers from inventory can also be used as variables.

There are several ways to define variables in Ansible:

The need to use variables is perfectly demonstrated by the example of installing Apache. The fact is that in different distributions a package with apache is called differently. The difference in configurations of different operating systems is quite common.
For example:
- set_fact package_name=httpd when: ansible_os_family == "Redhat" - set_fact package_name=apache2 when: ansible_os_family == "Debian" 

The task will set the variable package_name to httpd or apache2 depending on the OS family on the server.

Variables can be used to set user values ​​during the playbook execution:
 - 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 its repeated use. If the same variable is used in the playbook set, their use 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 the include files will overload (replace) variables defined at other levels of the hierarchy, except for variables passed via --extra-vars .

Variables in imported files

Let's look at how you can use variables from files imported into the playbook.
Let's create a separate file for installing Apache (~ / 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" 

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 install apache correctly on both rpm distributions and deb using the correct apache package name.



Variables in the playbook

Variables in a 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.

Example of a variable description in a playbook:
 vars: - package_name: "httpd" 


Variables in the 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 you need; you just need to tell the playbook where to find 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 variable package_name directly (after # you can write a comment), and access keys for the InfoboxCloud API are searched in environment variables using the lookup plugin.

In a 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 gathers with 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 the group of machines in inventory.

Plunging into the inventory – file


In the first part, we briefly reviewed a simple inventory – file. Let's take a closer look at it.

Simple inventory (~ / ansible / inventory ):
 ansible.trukhin.com 77.221.144.179 

You can simply write the host names and ip addresses and all servers will be used when running 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 playbook execution group is listed in the “hosts:” playbook section
 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 


Groups of groups in inventory

A very useful feature that allows, for example, to group hosts not only by purpose, but also by location, which is very important for InfoboxCloud (Moscow, Amsterdam). Often there are other tasks where you need to use groups of 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. You can access both the web group and server groups in a specific region from the playbook.

Regular expressions in inventory

If you have a large number of servers, the use of naming conventions (for example 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 previously described methods for setting variables 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 particular host.

Setting host-specific variables:
 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 


Removal of variables in separate files for inventory

You can create variable files for hosts and groups. Folders with these files should be in the same directory as the inventory file. Files of variables related to specific hosts should be saved in the folder host_vars, belonging to specific groups - in the folder group_vars.

An example variable file for web001 host (~ / ansible / host_vars / web001):
 web_port_ssl=443 web_port=80 

An example of a variable file for a db group (~ / ansible / group_vars / db):
 db_port=6380 db_name=redis 

The inventory variables follow hierarchies: 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, you can override the Ansible configuration settings.

Conclusion


The book " Learning Ansible " and of course the official documentation helped a lot in writing the article.

It is convenient to conduct all experiments with Ansible in InfoboxCloud , since there is an opportunity for each virtual server to set the exact amount of resources needed for the task (CPU / Ram / disk independently of each other) or to use autoscaling, and not to choose VM from ready-made templates. When experiments are not conducted - you can simply turn off the VM and pay only the cost of the disk.

If you find an error in the article, the author will gladly correct it. Please write in the LAN or in the mail about it. There you can also ask questions about Ansible for coverage in subsequent articles.

Part 4: working with modules
Part 5: local_action, conditions, cycles and roles

Successful work!

Source: https://habr.com/ru/post/252001/


All Articles