Автоматизируем и ускоряем процесс настройки облачных серверов с Ansible. Часть 3: Переменные и файл inventory

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

Во второй части мы разобрались в выводе 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_ansible_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 для освещения в последующих статьях. Ссылки на следующие статьи будут добавлены в конец этой статьи, поэтому можно просто сохранить ее на будущее.

Успешной работы!

0 комментариев

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.