ADG Оставить заявку
Блог Автоматизация 5 мин чтения

Ansible 2.0 preview: роли, блоки и почему мы наконец перестали бояться 40 хостов

Ansible 2.0 preview переработал систему ролей и добавил блоки задач. Рассказываем как перешли с bash-скриптов на Ansible и что это изменило в работе команды.

Контекст момента

Ansible 2.0 preview выпущен с переработанными roles, блоками задач и улучшенным callback API

На прошлой неделе вышел preview Ansible 2.0. Не финальный релиз, но достаточно функциональный чтобы пощупать что поменялось. А поменялось немало: переработанная система ролей, блоки задач с обработкой ошибок, новый callback API. Это хороший повод написать про то, куда мы вообще пришли с Ansible за последние полгода.

Откуда взялось 40 хостов в одном месте

В начале года написали как перевели провизионинг одного сервера в playbook. С тех пор этот подход распространился на весь парк клиентов на сопровождении. Сейчас под управлением Ansible - под сорок хостов: web-серверы, базы данных, мониторинг, инфраструктура.

До этого жили так: bash-скрипт на сервере, вики-страница с чеклистом, и живая память конкретного инженера. Когда серверов было десять - кое-как работало. Когда стало двадцать, тридцать - начались проблемы. Один хост настроен чуть иначе, потому что полгода назад Вася делал его руками и немного схитрил. Другой хост обновлён, а третий - нет, потому что чеклист обновили в вики, но руками прошлись не везде.

Ansible решил это не магией, а скукой: один инвентарь, один набор плейбуков, ansible-playbook -l all и смотришь что изменится прежде чем применить. Дрейф конфигурации стал видим.

Что изменилось с ролями в 2.0

В Ansible 1.9 роли уже существовали, но были довольно примитивными. В 2.0 preview переработали несколько вещей.

Зависимости ролей стали работать предсказуемее. Раньше если две роли зависели от одной общей роли, та выполнялась дважды. В 2.0 это починили: дублирования нет, общая роль применяется один раз. Звучит как мелочь - на практике это была реальная боль когда роль common делала что-то нежелательное при повторном запуске.

Блоки задач (block:) - это новинка 2.0, которой не было вообще. Теперь можно сгруппировать несколько тасков в блок, навесить на него общий when: и - самое важное - rescue: для обработки ошибок:

- block:
    - name: установить nginx
      yum: name=nginx state=present
    - name: запустить nginx
      service: name=nginx state=started
  rescue:
    - name: откат - удалить nginx
      yum: name=nginx state=absent
  when: ansible_distribution == "CentOS"

Это меняет как пишется логика с откатом. Раньше приходилось городить условия через ignore_errors и register, и в итоге получалась лапша. Блоки делают намерение читаемым.

Callback API переписан, но это больше для тех кто пишет плагины под Ansible. Нас это пока не касается.

Разделение ответственности: кто пишет что

Вот что реально изменилось в работе команды после перехода на роли.

Раньше плейбуки писал один человек - кто разбирался в Ansible лучше других. Остальные или не трогали, или ломали. Роли позволили разделить это по зонам ответственности.

Сетевые настройки - отдельная роль. Там живут конфиги интерфейсов, маршруты, firewall-правила. Человек который занимается сетью, знает эту роль и правит её. Он не лезет в роль postgresql и не должен.

Системная часть - другая роль. NTP, SSH-харденинг, пользователи, Zabbix-агент. Системный администратор отвечает за эту зону.

Приложения - отдельные роли под каждый стек. nginx, PHP, базы данных - каждое в своей роли с переменными под конкретного клиента через group_vars.

На практике это выглядит так: сетевик делает git pull, правит свою роль, запускает --check чтобы посмотреть что изменится, потом применяет. Системщик об этом не знает и его работу это не трогает. До ролей такого разграничения не было - всё было в одном большом плейбуке и любое изменение требовало координации.

Про CentOS 7 и роли

Пару недель назад писали про переход на CentOS 7.1 и про то что systemd ломает старые таски. С ролями это стало чище: в каждой роли есть tasks/main.yml который включает нужный файл в зависимости от дистрибутива:

- include: centos6.yml
  when: ansible_distribution_major_version == "6"

- include: centos7.yml
  when: ansible_distribution_major_version == "7"

Раньше эти ветвления были размазаны по одному большому файлу, и читать его было неприятно. Сейчас каждая версия ОС - отдельный файл внутри роли. Понятнее и проще поддерживать.

Где ещё спотыкаемся

2.0 - preview, и это чувствуется. Несколько модулей поменяли поведение, и плейбуки написанные под 1.9 надо проверять прежде чем переходить. Мы пока держим production на 1.9, 2.0 гоняем на тестовых стендах.

Есть вещи которые в ролях всё ещё неудобны: если роль хочет использовать файл из другой роли - начинаются пути-лабиринты. Ansible не даёт нормального способа сослаться на ресурсы соседней роли. Решается через общие переменные, но это костыль.

Ansible Galaxy с публичными ролями мы смотрим с осторожностью. Большинство ролей написано под авторские представления о структуре системы, и интегрировать их в свой инвентарь - отдельная работа. Проще написать свою на 80 строк чем адаптировать чужую на 400.

Итого

Сорок хостов конфигурируются из одного репозитория. Дрейф конфигурации виден, а не угадывается. Разные части команды работают независимо в своих зонах.

Ansible 2.0 добавляет блоки и чинит зависимости ролей - это приятные улучшения, а не революция. Финального релиза пока нет, ждём. Но направление правильное.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.