Эффективная разработка и сопровождение Ansible-ролей

в 11:35, , рубрики: Ansible, devops, Блог компании Конференции Олега Бунина (Онтико), системное администрирование

Ansible — система, которая решает различные задачи автоматизации, включая конфигурирование, резервное копирование и деплой проектов. Систему приятно использовать для написания сценариев автоматизации от простого окружения до крупного проекта. В сценариях важную роль играют playbooks и роли — структурированные playbooks.

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

Как раз об этом расшифровка доклада Александра Харкевича на DevOps Conf Russia. В докладе: разработка Ansible-ролей через CI, механизм разработки публичных ролей и публичных ролей с тестовыми прогонами в приватной инфраструктуре. А еще в докладе нет вывода.


О спикере: Александр Харкевич (kharkevich) старший системный инженер в компании EPAM Systems.

Начнем с краткого обзора.

Про Ansible

Ansible — система для управления конфигурациями. Написана на Python, шаблонизируется Junja, а в качестве DSL используется YAML. Управляется через Ansible Tower — WebUI для управления и мониторинга работы системы.

Ansible появилась в 2012 году, через 3 года Red Hat купил проект целиком, а еще через два года представила AWX — Project Open Source-версию Ansible Tower.

Установка

Чтобы использовать Ansible, нужно сделать две простые вещи.

На первом этапе составить файл инвентаризации в случае статической инфраструктуры.

Эффективная разработка и сопровождение Ansible-ролей - 1

На втором — написать Playbook, который приведет систему в ожидаемое состояние.

Эффективная разработка и сопровождение Ansible-ролей - 2

Часто у нас возникает непреодолимое желание написать автоматизацию, которую можно переиспользовать еще раз. Автоматизация — хорошее желание, и ребята из Ansible придумали классную концепцию — роль.

Роль

Это структурированная сущность, которая приведет систему в ожидаемое состояние с возможностью переиспользовать автоматизацию.

Эффективная разработка и сопровождение Ansible-ролей - 3

Например, мы можем написать роль для Oracle Java: возьмем Playbook, поставим роль и применим ее к целевой системе. На выходе получим установленную Java.

Эффективная разработка и сопровождение Ansible-ролей - 4

Как мы представляли работу с ролями

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

Мы думали, что будем писать красивые и умные роли…

Эффективная разработка и сопровождение Ansible-ролей - 6

Но жизнь оказалась сложнее.

Как оказалось на самом деле

Когда над написанием роли или ее улучшением работает больше, чем один человек, то все пишут в одно место и возникают неприятные сюрпризы: роль ведет себя не так, как изначально задумывалось автором.

Хорошо, когда она применяется до конца, но это не всегда случается. Иногда роль успешно исполняется, но на целевой системе это сказывается совсем не так, как хотелось изначально.
Эффективная разработка и сопровождение Ansible-ролей - 7

В результате возникают ужасные конструкции, попытки перенести bash в Ansible и подать все это под соусом configuration management. Мы столкнулись с этим явлением и взгрустнули.

Эффективная разработка и сопровождение Ansible-ролей - 8

Подумав, мы обнаружили, что в нашем configuration management есть некое подобие кода, а значит, практики, которые применимы к управлению кодом в Systems Development Life Cycle, применимы и в Ansible.

  • Cобрать лучшие практики.
  • Применить статический анализ, линты.
  • Протестировать.
  • Зарелизить, завести в Release management.

Мы решили реализовать практики у себя и сразу пошли искать подходящие инструменты.

Инструменты

С точки зрения систем контроля версий и непрерывной интеграции есть десяток доступных решений, и развесистый зоопарк по тестированию.

Эффективная разработка и сопровождение Ansible-ролей - 9

С точки зрения release management в Ansible не так уж и много решений: тегировать в Git, либо тегировать в Git и выкладывать в Galaxy.

По инструментам тестирования много подходов, каждый использует то, что нравится. Популярны решения с использованием KitchenCI, InSpec, Serverspec.

У нас душа не лежала брать Ansible написанный на Python, и примешивать к нему инструменты из мира Ruby. Поэтому, выкинув всё неродное миру Python, мы получили следующую картину.

Эффективная разработка и сопровождение Ansible-ролей - 10

Мы используем:

  • Для управления конфигурацией — GitHub и GitLab. Прямо одновременно в GitHub смотрит GitLab. Зачем так сделали, расскажу позже.
  • Для CI мы взяли Travis для публичной части и GitLab Runner для приватной части.
  • Тестируем Molecule.
  • Релизимся в GitHub и складываем в Ansible Galaxy.

Наш цикл разработки с этими инструментами стал выглядеть веселее.
Эффективная разработка и сопровождение Ansible-ролей - 11

Molecule

Данный инструмент помогает полноценно протестировать ansible-роль. Для этого у него все есть:

  • Интеграция с YAML lint и Ansible lint для проверки ролей на соответствие нашим требованиям.
  • Инфраструктура тестирования для прогона функциональных тестов.
  • Molecule drivers — это то, куда Molecule разворачивает наш тестовый стенд. Поддерживается все: Azure, Delegated, Docker, EC2, GCE, LXC, LXD, Openstack, Vagrant.
  • Еще есть полезная и простая вещь — делегирование. Это значит, что Molecule не отвечает за разворачивание тестового стенда и написать Playbook для поднятия тестового стенда должен разработчик. Если у тебя суперприватное облако, то делегируй создание и удаление тестовых машин, а Molecule само добавит все внутрь.

Эффективная разработка и сопровождение Ansible-ролей - 12

Тестовая матрица

Рассмотрим тестовую матрицу по шагам. Всего шагов 11, но буду краток.

№ 1. Lint

Прогоняются YAML lint и Ansible lint, и что-нибудь находят.

Эффективная разработка и сопровождение Ansible-ролей - 13

В примере выше lint ругается на то, что shell нужно не просто вызывать в Ansible, а фиксировать его, привязывая к чему-то.

№ 2. Destroy

Molecule избавляется от всего, что осталось после предыдущих тестов.

Бывают случаи, когда прошел прогон, развернулся полигон и тестирование завершилось. Стенд должен в конце почиститься, но вмешались непреодолимые силы и чистки не было. Для таких ситуаций Molecule прогоняет destroy и чистит среду от остатков.

Эффективная разработка и сопровождение Ansible-ролей - 14

№ 3. Dependency

Берем файлик requirements.yml и добавляем зависимости нашей роли от других ролей. Например, отсылку к тому, что роль не взлетит без установленной на системе Java:

---
    - src: lean_delivery.java
     version: 1.4

Molecule это понимает и исполнит сценарий:

  • сходит в Galaxy или в Git;
  • сообразит, что нужно решать зависимости;
  • сходит в Galaxy еще раз;
  • скачает;
  • развернет.

Эффективная разработка и сопровождение Ansible-ролей - 15

№ 4. Syntax

Следующий шаг — проверка синтаксиса. но не вашей роли, а тестовой Playbook, которую вы добавляете в Molecule. На этом шаге тоже бывают ошибки связанные с синтаксисом.

На слайде видно, что ansible-роль называется ‘kibana’, а в тестовой Playbook — ansible-role-kibana. Система говорит: «Все бы хорошо и здесь можно создавать, но я так делать не буду, потому что имена не совпадают!»

Эффективная разработка и сопровождение Ansible-ролей - 16

№ 5. Create

На этом этапе указываем драйвер, с помощью которого разворачивается тестовый полигон. Укажете Google — он поднимет в Google Cloud тестовые машинки.

Мы можем в файле molecule.yml прописать, что мы хотим. Посмотрим как это выглядит на примере для Docker.

Эффективная разработка и сопровождение Ansible-ролей - 17

  • Я указываю изображения, которые нужно подтянуть.
  • Указываю, как их сгруппировать, чтобы сформировался инвентаризационный файл.

Я хочу иметь два изображения: один для RHEL-подобного, второй для Debian-подобного, чтобы быть уверенным в том, что во время тестового прогона все будет хорошо и с RHEL, и с Debian.

№ 6. Prepare

Это шаг предварительной подготовки среды выполнения тестов.

Вроде бы все поднялось, но иногда нужно выполнить какие-нибудь дополнительные настройки. В случае тестирования внутри приподнятого Docker в Debian или Ubuntu, требуется поставить второй Python, что часто бывает.

№ 7. Converge

Этап первого большого прогона роли внутрь instance, чтобы убедиться, что она добегает до конца, прогоняется, и Ansible подтверждает, что все хорошо.

Эффективная разработка и сопровождение Ansible-ролей - 18

  • Molecule обращается к Ansible.
  • Ansible деплоит на тестовый полигон.
  • Пробегает.
  • Все нормально!

№ 8. Idempotence

Проверка на идемпотентность простая и выглядит так.

Эффективная разработка и сопровождение Ansible-ролей - 19

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

В результате мы понимаем, что наша роль не действует деструктивно.

Этот этап у ребят, с которыми я работаю, вызвал боль. Они пытались пойти обходными путями, чтобы победить проверку на идемпотентность. У Molecule можно управлять этапами, которые она проходит, и первое, что они сделали — отключили проверку на идемпотентность.

Эффективная разработка и сопровождение Ansible-ролей - 20

Мы ловили отключения и били за это по рукам, но инженеры умные и пошли глубже. Разработчики решили говорить, что этот шаг в Ansible ничего не меняет.

Хотя на самом деле здесь появится какая-то команда. Ansible прямо возьмет и
будет перезаписывать файл, но при этом все выглядит идемпотентно.

Эффективная разработка и сопровождение Ansible-ролей - 21

Когда эту хитрость тоже отловили, картинка стала выглядеть так.

Эффективная разработка и сопровождение Ansible-ролей - 22

Хорошо — сценарий пробежал под именем default, и он идемпотентный.

№ 9. Side_effect

На следующем этапе накладываются побочные эффекты. Это делать необязательно, но удобно, когда вы тестируете сложные развесистые роли, зависимые друг от друга.

Например, поднимаете ELK stack, затем Elasticsearch в кластере. На этапе side_effect добавляете тестовых данных и удаляете пару узлов из кластера. Тестовый полигон готов для функциональных тестов, которые происходят на следующем этапе.

№ 10. Verify

Тестируем инфраструктуру.

Эффективная разработка и сопровождение Ansible-ролей - 23

Выше пример очень простого теста. Мы проверяем, что у нас пакет Docker Community Edition в случае Ubuntu установлен, у него нужная версия, и сервис запущен.

На этом этапе запуска функциональных тестов можно все сильно усложнить.

Наверно, лучшим примером будет, в случае ELK stack, если на каких-то тестовых данных сделаем запрос в Elasticsearch, и так как тестовые данные нам известны, то он нам ответит. Мы не будем проверять, что все установленные компоненты собраны, а посмотрим, что Elasticsearch поднят, работает и выдает на поиске именно то, что нужно.

Эффективная разработка и сопровождение Ansible-ролей - 24

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

№ 11. Destroy

Мы провели тесты, test report в каком-то виде есть и теперь убираем весь мусор за собой.

Автоматизация

Molecule — отличный инструмент. Теперь осталось самое простое — подключить к нему систему непрерывной интеграции, чтобы наслаждаться автоматическим тестированием наших ролей, что мы и сделали.

Эффективная разработка и сопровождение Ansible-ролей - 25

Как и везде, есть несколько особенностей.

Некоторые роли, которые мы пишем для автоматизации чего-то, хороши, но мы не можем тестировать систему с помощью Travis, потому что роли разворачивают продукты, которые мы не можем выложить в общий доступ по лицензионным соображениям.

Например, у вас есть автоматизация разворачивания базы Oracle. Если выложите в файл инсталлятор базы, то к вам придут юристы компании и будут сильно ругаться. Чтобы все жили в мире и не ругались, мы решили сделать следующее.

  • GitLab, в одном из последних релизов, научился делать CI для сторонних репозиториев.
  • Роль лежит в публичном GitHub, к нему подключен такой же публичный GitLab.com, в котором мы указали: «Дорогой GitLab, собирай нам CI для внешнего репозитория».
  • К GitLab прикручены приватные runners, в закрытом периметре, и у них уже есть доступ к binary, которые они могут разворачивать.

Фактически роль лежит публично, данные тоже, и мы никого не обманываем — у нас прогоняются реальные тесты с реальными инструментами.

Давайте посмотрим по шагам, как это выглядит в Travis.

Travis

Эффективная разработка и сопровождение Ansible-ролей - 26

По шагам:

  • На первом шаге, 8-я строчка, мы сообщаем Travis, что мы не просто хотим его запустить, а еще воспользоваться Docker-сервисом, чтобы Docker был доступен внутри Travis.
  • Дальше, 10-я строчка, мы забираем свои lint rules. Мы не только используем дефолтные Ansible lint rules, но и пишем свои.
  • На 15-й строчке мы сначала вызываем lint, чтобы сэкономить время на прогон тестовой матрицы. Если что-то написано не по правилам, и lint это не найдет, то идет в начало и оставляет отчет. Разработчик, который коммитил, чинит свой коммит или отменяет изменения. Когда починит, пусть приходит, и мы будем дальше продолжать тест.

Публичный CI

Публичный CI выглядит элементарно.

Эффективная разработка и сопровождение Ansible-ролей - 27

От GitHub стрелочка к Travis, внутри которого живёт Molecule и Docker.

Приватный CI

Для приватной части GitLab все то же самое.

Эффективная разработка и сопровождение Ansible-ролей - 28

В приватном периметре у нас запущен runner, и картинка выглядит веселее.

Эффективная разработка и сопровождение Ansible-ролей - 29

Код попадает из GitHub в GitLab, где-то бежит приватный runner, который умеет дергать внешние сервисы, например, запускать что-то в Amazon.

Маленькое отступление. Запуск и разворачивание тестовой среды в Amazon не хочется переносить, потому что нужны ключи. Придумывать механизмы, чтобы положить их в паблик, но при этом не стать очередной стартап-платформой для майнинга — это нетривиальная задача. Поэтому мы ее не решали, а унесли runner в приват, чтобы не майнить биткойны Amazon.

Даже здесь, мы чуть-чуть поленились и сделали следующее. У нас в EPAM есть свое приватное облако и оно гибридное. Это значит, что многие публичные облака доступны из внутреннего облака, как регионы. Можно не писать тысячу тестов, а поиграться с регионами и сказать: «Теперь проведи тест вот по этому тестовому сценарию для региона AWS, EPAM Cloud, Azure».

Ansible Galaxy

Подошли к финалу, наша роль зеленая, красивая, опубликуем ее в Galaxy.

Эффективная разработка и сопровождение Ansible-ролей - 30

Это простая операция:

  • Вызов webhook, который есть в Travis.
  • При этом у нас тригернется Travis, пробежит еще раз CI.
  • Вызов webhook.
  • Новая версия успешно прорастет в Galaxy.

Есть одна особенность — если вы не маркируете роль, не тегируете, не назначаете ей версию, то в Galaxy она всегда будет без версии. Как только другой разработчик захочет ее себе поставить через Ansible Galaxy install, он заберет роль, которая лежит в мастер-ветке, либо в другом branch по умолчанию. По умолчанию branch не всегда стабилен, что неудобно.

Если вы что-то публикуете в Galaxy, не забывайте это тегировать, прямо чтобы были версии, и все было клево.

Шаблоны

Делюсь маленькой хитростью: чтобы каждый раз не копипастить при написании новой роли, мы решили создать шаблоны и отдельный репозиторий, в который положили шаблон, чтобы быстро с нуля писать роли.

У шаблона есть настройки по умолчанию для Ansible lint и GitHub issue_template. Всё в свободном доступе, поэтому issue_template в красивой форме, чтобы pull request или bug reports нам оформляли тоже красиво. В тот же репозиторий складываем шаблоны для Gitignore, Gitlab-ci и лицензию.

Эффективная разработка и сопровождение Ansible-ролей - 31

По умолчанию мы публикуемся под лицензией Apache 2.0. Если захотите сходить к нам и переиспользовать шаблоны, то можете всё забрать, создать закрытый репозиторий и никому ничего не объяснять. Спасибо Apache.

У нас лежит несколько вариантов тестов, чтобы можно было быстренько все пнуть и завести.

Итог

Заключения не будет, вместо него есть ссылки на мой GitHub, мой профайл в Galaxy, на GitHub Lean Delivery и Ansible Galaxy. По ссылкам можно посмотреть, как все работает. Все примеры в свободном доступе.

Следующая конференция по DevOps пройдет в мае.

Пока мы в ожидании события, подпишитесь на YouTube-канал и рассылку. Канал будет пополняться записями лучших докладов, а в рассылке будут подборки полезных материалов, расшифровки и DevOps-новости.

Подписывайтесь, будет интересно:)

Автор: osminog

Источник

* - обязательные к заполнению поля