В первой части мы начали изучение Ansible, популярного инструмента для автоматизации настройки и развертывания ИТ-инфраструктуры. Ansible был успешно установлен, описаны принципы работы, базовая настройка. В завершении статьи мы показали как быстро установить nginx на несколько серверов.
Во второй части мы разобрались в выводе playbook, научились отлаживать и повторно использовать скрипты Ansible.

В этой части вы узнаете, как писать единый Ansible playbook для разных ОС (например с rpm и deb), как обслуживать множество хостов и не писать их все в inventory, как сгруппировать сервера по регионам InfoboxCloud и многое другое.
Переменные используются для хранения значений, которые могут применяться в playbook. В процессе использования переменные можно переопределять множество раз. Информация о серверах из inventory также может использоваться как переменные.
Есть несколько способов определения переменных в Ansible:
Необходимость использования переменных отлично демонстрирует пример с установкой Apache. Дело в том, что в разных дистрибутивах пакет с apache называется по-разному. Разница в конфигурациях разных ОС встречается достаточно часто.
Например:
Задача установит в переменную package_name значение httpd или apache2 в зависимости от семейства ОС на сервере.
Переменные можно использовать для установки значений пользователя в процессе исполнения playbook:
В переменные удобно сохранить список значений для его многократного использования. Если одна и та же переменная используется во множестве playbook – их использование уменьшит сложность скриптов.
Все переменные в Ansible должны начинаться с буквы. В имени можно использовать буквы, цифры и подчеркивания.
Переменные, определенные в include файлах будут перегружать (заменять) переменные, определенные на других уровнях иерархии, кроме переменных, переданных через --extra-vars.
Давайте рассмотрим, как можно использовать переменные из импортированных в playbook файлов.
Сделаем отдельный файл задачи по установке Apache (~/ansible/playbooks/tasks/pkg_apache_install.yml):
Включим его в файл установки Apache и проверки, что сервис запущен (~/ansible/setup_apache.yml):
Как мы видим, в файле setup_apache.yml мы успешно используем переменную, определенную во включенном файле. Данный playbook будет правильно устанавливать apache и на rpm дистрибутивы и на deb, используя правильное имя пакета с apache.

Переменные в playbook устанавливаются с помощью ключевого слова vars:. Переменные устанавливаются в виде имя_переменной: значение. Переменные перегрузят другие переменные, которые установлены в глобальном файле или в inventory.
Пример описания переменной в playbook:
Переменные в Ansible можно задавать в отдельном файле, что позволяет отделить данные от playbook. Можно создавать столько файлов переменных, сколько необходимо, нужно только сказать playbook где их искать. Формат определения переменных в файле похож на формат определения переменных в Playbook.
~/ansible/common/vars/global.yml
В данном примере мы задаем переменную package_name напрямую (после # можно написать комментарий), а ключи доступа для InfoboxCloud API ищем в переменных окружения с помощью плагина lookup.
В playbook путь к файлам переменных задается через vars_files:
Вы можете использовать любой факт как переменную, который собирается при gather_facts. Для получения списка всех фактов для конкретной группы машин используйте команду:
, где experiments – название группы машин в inventory.
В первой части мы кратко рассматривали простой inventory–файл. Давайте посмотрим на него внимательнее.
Простой inventory (~/ansible/inventory):
Можно просто записать имена хостов и ip адреса и будут использоваться все сервера при исполнении playbook с этим файлом inventory.
Использование групп мы также уже видели ранее:
Группа для исполнения playbook указывается в разделе «hosts:» playbook
Если вы хотите использовать конкретный хост — можно в раздел hosts передать его.
Если вы хотите использовать все хосты всех групп — можно использовать
Очень полезная функция, позволяющая, например, сгруппировать хосты не только по назначению, но и по региону размещения, что очень актуально для InfoboxCloud (Москва, Амстердам). Нередко бывают и другие задачи, где нужно использовать группы групп.
В этом примере в группу web my входят сервера в Москве и Амстердаме. Можно из playbook обращаться как к группе web, так и к группам серверов в конкретном регионе.
Если у вас есть большое количество серверов, использование соглашений о наименовании (например web001, web002… web00N) позволит проще указывать их в inventory. Можно использовать регулярные выражения в inventory файле:
, где web[001:200] будет соответствовать web 001, web002, web003, web004, ..., web199, web200 для группы web;
db[001:020] будет соответствовать db001, db002, db003 ..., db019, db020 для группы db.
192.168.2.[1:30] будет соответствовать 192.168.2.1, 192.168.2.2, 192.168.2.3 для группы balancer.
Рассмотренные ранее способы установки переменных применяли их сразу ко всем хостам в inventory. Иногда может потребоваться использование специфических переменных для конкретной группы хостов или конкретного хоста.
Установка переменных для конкретных хостов:
Установка переменных для группы хостов (web):
Можно создавать файлы переменных для хостов и для групп. Папки с этими файлами должны быть в одной директории с файлом inventory. Файлы переменных, относящиеся к конкретным хостам, нужно сохранять в папку host_vars, относящиеся к конкретным группам — в папку group_vars.
Пример файла переменных для хоста web001 (~/ansible/host_vars/web001):
Пример файла переменных для группы db (~/ansible/group_vars/db):
Переменные inventory следуют иерархии: переменные в глобальном файле перегружают любые хост-переменные, групповые переменные и переменные в файле inventory. Хост-переменные перегружают групповые переменные, а в свою очередь групповые переменные перегружают переменные файла inventory.
Через ansible.cfg можно переопределить параметры конфигурации Ansible.
В написании статьи очень помогла книга "Learning Ansible" и конечно официальная документация.
Все эксперименты с Ansible удобно проводить в InfoboxCloud, так как имеется возможность для каждого виртуального сервера установить именно то количество ресурсов, которое необходимо для задачи (CPU/Ram/диск независимо друг от друга) или использовать автомасштабирование, а не выбирать VM из готовых шаблонов. Когда эксперименты не проводятся — можно просто выключить VM и оплачивать только стоимость диска.
Если вы обнаружили ошибку в статье, автор ее с удовольствием исправит. Пожалуйста напишите в ЛС или на почту о ней. Туда же можно задавать вопросы по Ansible для освещения в последующих статьях.
Часть 4: работаем с модулями
Часть 5: local_action, условия, циклы и роли
Успешной работы!
Во второй части мы разобрались в выводе playbook, научились отлаживать и повторно использовать скрипты Ansible.

В этой части вы узнаете, как писать единый Ansible playbook для разных ОС (например с rpm и deb), как обслуживать множество хостов и не писать их все в inventory, как сгруппировать сервера по регионам InfoboxCloud и многое другое.
Переменные в Ansible
Переменные используются для хранения значений, которые могут применяться в playbook. В процессе использования переменные можно переопределять множество раз. Информация о серверах из inventory также может использоваться как переменные.
Есть несколько способов определения переменных в Ansible:
- передача файла переменных
- определение переменных в playbook
- передача в ansible-playbook, используя команду -e / --extra-vars
- определение переменных в файле inventory
Необходимость использования переменных отлично демонстрирует пример с установкой Apache. Дело в том, что в разных дистрибутивах пакет с apache называется по-разному. Разница в конфигурациях разных ОС встречается достаточно часто.
Например:
- set_fact package_name=httpd
when: ansible_os_family == "Redhat"
- set_fact package_name=apache2
when: ansible_os_family == "Debian"
Задача установит в переменную package_name значение httpd или apache2 в зависимости от семейства ОС на сервере.
Переменные можно использовать для установки значений пользователя в процессе исполнения playbook:
- name: Package to install
pause: prompt="Provide the package name which you want to install "
register: package_name
В переменные удобно сохранить список значений для его многократного использования. Если одна и та же переменная используется во множестве playbook – их использование уменьшит сложность скриптов.
Все переменные в Ansible должны начинаться с буквы. В имени можно использовать буквы, цифры и подчеркивания.
Переменные, определенные в include файлах будут перегружать (заменять) переменные, определенные на других уровнях иерархии, кроме переменных, переданных через --extra-vars.
Переменные в импортированных файлах
Давайте рассмотрим, как можно использовать переменные из импортированных в playbook файлов.
Сделаем отдельный файл задачи по установке 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"
Включим его в файл установки Apache и проверки, что сервис запущен (~/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
Как мы видим, в файле setup_apache.yml мы успешно используем переменную, определенную во включенном файле. Данный playbook будет правильно устанавливать apache и на rpm дистрибутивы и на deb, используя правильное имя пакета с apache.

Переменные в playbook
Переменные в playbook устанавливаются с помощью ключевого слова vars:. Переменные устанавливаются в виде имя_переменной: значение. Переменные перегрузят другие переменные, которые установлены в глобальном файле или в inventory.
Пример описания переменной в playbook:
vars:
- package_name: "httpd"
Переменные в глобальном файле
Переменные в Ansible можно задавать в отдельном файле, что позволяет отделить данные от playbook. Можно создавать столько файлов переменных, сколько необходимо, нужно только сказать playbook где их искать. Формат определения переменных в файле похож на формат определения переменных в 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') }}"
В данном примере мы задаем переменную package_name напрямую (после # можно написать комментарий), а ключи доступа для InfoboxCloud API ищем в переменных окружения с помощью плагина lookup.
В playbook путь к файлам переменных задается через vars_files:
vars_files:
- var1.yml
- var2.yml
Использование фактов как переменных
Вы можете использовать любой факт как переменную, который собирается при gather_facts. Для получения списка всех фактов для конкретной группы машин используйте команду:
ansible experiments -i inventory -m setup
, где experiments – название группы машин в inventory.
Погружаемся в inventory–файл
В первой части мы кратко рассматривали простой inventory–файл. Давайте посмотрим на него внимательнее.
Простой inventory (~/ansible/inventory):
ansible.trukhin.com
77.221.144.179
Можно просто записать имена хостов и ip адреса и будут использоваться все сервера при исполнении playbook с этим файлом inventory.
Группы в inventory
Использование групп мы также уже видели ранее:
[my]
ansible.trukhin.com
ansible2.trukhin.com
[corp]
ansible.sandbox.infoboxcloud.ru
ansible2.sandbox.infoboxcloud.ru
Группа для исполнения playbook указывается в разделе «hosts:» playbook
hosts: my
Если вы хотите использовать конкретный хост — можно в раздел hosts передать его.
hosts: ansible.trukhin.com
Если вы хотите использовать все хосты всех групп — можно использовать
hosts: all
Группы групп в inventory
Очень полезная функция, позволяющая, например, сгруппировать хосты не только по назначению, но и по региону размещения, что очень актуально для InfoboxCloud (Москва, Амстердам). Нередко бывают и другие задачи, где нужно использовать группы групп.
[msk]
webMSK.trukhin.com
dbMSK.trukhin.com
[ams]
webAMS.trukhin.com
dbAMS.trukhin.com
[web:children]
msk
ams
В этом примере в группу web my входят сервера в Москве и Амстердаме. Можно из playbook обращаться как к группе web, так и к группам серверов в конкретном регионе.
Регулярные выражения в inventory
Если у вас есть большое количество серверов, использование соглашений о наименовании (например web001, web002… web00N) позволит проще указывать их в inventory. Можно использовать регулярные выражения в inventory файле:
[web]
web[001:200]
[db]
db[001:020]
[balancer]
192.168.2.[1:3]
, где web[001:200] будет соответствовать web 001, web002, web003, web004, ..., web199, web200 для группы web;
db[001:020] будет соответствовать db001, db002, db003 ..., db019, db020 для группы db.
192.168.2.[1:30] будет соответствовать 192.168.2.1, 192.168.2.2, 192.168.2.3 для группы balancer.
Переменные в inventory–файле
Рассмотренные ранее способы установки переменных применяли их сразу ко всем хостам в inventory. Иногда может потребоваться использование специфических переменных для конкретной группы хостов или конкретного хоста.
Установка переменных для конкретных хостов:
ansible.trukhin.com
web001
db001 db_name=mysql
192.168.2.1 db_name=redis db_port=6380
Установка переменных для группы хостов (web):
[web]
web[001:010]
[db]
db[001:002]
[web:vars]
web_port=443
Вынос переменных в отдельные файлы для inventory
Можно создавать файлы переменных для хостов и для групп. Папки с этими файлами должны быть в одной директории с файлом inventory. Файлы переменных, относящиеся к конкретным хостам, нужно сохранять в папку host_vars, относящиеся к конкретным группам — в папку group_vars.
Пример файла переменных для хоста web001 (~/ansible/host_vars/web001):
web_port_ssl=443
web_port=80
Пример файла переменных для группы db (~/ansible/group_vars/db):
db_port=6380
db_name=redis
Переменные inventory следуют иерархии: переменные в глобальном файле перегружают любые хост-переменные, групповые переменные и переменные в файле inventory. Хост-переменные перегружают групповые переменные, а в свою очередь групповые переменные перегружают переменные файла inventory.
Через ansible.cfg можно переопределить параметры конфигурации Ansible.
Заключение
В написании статьи очень помогла книга "Learning Ansible" и конечно официальная документация.
Все эксперименты с Ansible удобно проводить в InfoboxCloud, так как имеется возможность для каждого виртуального сервера установить именно то количество ресурсов, которое необходимо для задачи (CPU/Ram/диск независимо друг от друга) или использовать автомасштабирование, а не выбирать VM из готовых шаблонов. Когда эксперименты не проводятся — можно просто выключить VM и оплачивать только стоимость диска.
Если вы обнаружили ошибку в статье, автор ее с удовольствием исправит. Пожалуйста напишите в ЛС или на почту о ней. Туда же можно задавать вопросы по Ansible для освещения в последующих статьях.
Часть 4: работаем с модулями
Часть 5: local_action, условия, циклы и роли
Успешной работы!