- PVSM.RU - https://www.pvsm.ru -
Ansible — система, которая решает различные задачи автоматизации, включая конфигурирование, резервное копирование и деплой проектов. Систему приятно использовать для написания сценариев автоматизации от простого окружения до крупного проекта. В сценариях важную роль играют playbooks и роли — структурированные playbooks.
Ansible не волшебная таблетка, и помогает только на первых порах. Когда проект растет, становится сложно поддерживать разросшееся количество ролей. Помогает решить проблему механизм непрерывной поставки для ролей.
Как раз об этом расшифровка доклада Александра Харкевича на DevOps Conf Russia [1]. В докладе: разработка Ansible-ролей через CI, механизм разработки публичных ролей и публичных ролей с тестовыми прогонами в приватной инфраструктуре. А еще в докладе нет вывода.
О спикере: Александр Харкевич (kharkevich [2]) старший системный инженер в компании EPAM Systems [3].
Начнем с краткого обзора.
Ansible — система для управления конфигурациями. Написана на Python, шаблонизируется Junja, а в качестве DSL используется YAML. Управляется через Ansible Tower — WebUI для управления и мониторинга работы системы.
Ansible появилась в 2012 году, через 3 года Red Hat купил проект целиком, а еще через два года представила AWX — Project Open Source-версию Ansible Tower.
Чтобы использовать Ansible, нужно сделать две простые вещи.
На первом этапе составить файл инвентаризации в случае статической инфраструктуры.
На втором — написать Playbook, который приведет систему в ожидаемое состояние.
Часто у нас возникает непреодолимое желание написать автоматизацию, которую можно переиспользовать еще раз. Автоматизация — хорошее желание, и ребята из Ansible придумали классную концепцию — роль.
Это структурированная сущность, которая приведет систему в ожидаемое состояние с возможностью переиспользовать автоматизацию.
Например, мы можем написать роль для Oracle Java: возьмем Playbook, поставим роль и применим ее к целевой системе. На выходе получим установленную Java.
Раз в Ansible есть такая прекрасная вещь, как роли, то мы думали, что сейчас возьмем и напишем много-много ролей на все случаи жизни, пошарим, и будем переиспользовать, чтобы сократить количество работы.
Мы думали, что будем писать красивые и умные роли…
Но жизнь оказалась сложнее.
Когда над написанием роли или ее улучшением работает больше, чем один человек, то все пишут в одно место и возникают неприятные сюрпризы: роль ведет себя не так, как изначально задумывалось автором.
Хорошо, когда она применяется до конца, но это не всегда случается. Иногда роль успешно исполняется, но на целевой системе это сказывается совсем не так, как хотелось изначально.
В результате возникают ужасные конструкции, попытки перенести bash в Ansible и подать все это под соусом configuration management. Мы столкнулись с этим явлением и взгрустнули.
Подумав, мы обнаружили, что в нашем configuration management есть некое подобие кода, а значит, практики, которые применимы к управлению кодом в Systems Development Life Cycle, применимы и в Ansible.
Мы решили реализовать практики у себя и сразу пошли искать подходящие инструменты.
С точки зрения систем контроля версий и непрерывной интеграции есть десяток доступных решений, и развесистый зоопарк по тестированию.
С точки зрения release management в Ansible не так уж и много решений: тегировать в Git, либо тегировать в Git и выкладывать в Galaxy.
По инструментам тестирования много подходов, каждый использует то, что нравится. Популярны решения с использованием KitchenCI, InSpec, Serverspec.
У нас душа не лежала брать Ansible написанный на Python, и примешивать к нему инструменты из мира Ruby. Поэтому, выкинув всё неродное миру Python, мы получили следующую картину.
Мы используем:
Наш цикл разработки с этими инструментами стал выглядеть веселее.
Данный инструмент помогает полноценно протестировать ansible-роль. Для этого у него все есть:
Рассмотрим тестовую матрицу по шагам. Всего шагов 11, но буду краток.
Прогоняются YAML lint и Ansible lint, и что-нибудь находят.
В примере выше lint ругается на то, что shell нужно не просто вызывать в Ansible, а фиксировать его, привязывая к чему-то.
Molecule избавляется от всего, что осталось после предыдущих тестов.
Бывают случаи, когда прошел прогон, развернулся полигон и тестирование завершилось. Стенд должен в конце почиститься, но вмешались непреодолимые силы и чистки не было. Для таких ситуаций Molecule прогоняет destroy и чистит среду от остатков.
Берем файлик requirements.yml и добавляем зависимости нашей роли от других ролей. Например, отсылку к тому, что роль не взлетит без установленной на системе Java:
---
- src: lean_delivery.java
version: 1.4
Molecule это понимает и исполнит сценарий:
Следующий шаг — проверка синтаксиса. но не вашей роли, а тестовой Playbook, которую вы добавляете в Molecule. На этом шаге тоже бывают ошибки связанные с синтаксисом.
На слайде видно, что ansible-роль называется ‘kibana’, а в тестовой Playbook — ansible-role-kibana. Система говорит: «Все бы хорошо и здесь можно создавать, но я так делать не буду, потому что имена не совпадают!»
На этом этапе указываем драйвер, с помощью которого разворачивается тестовый полигон. Укажете Google — он поднимет в Google Cloud тестовые машинки.
Мы можем в файле molecule.yml прописать, что мы хотим. Посмотрим как это выглядит на примере для Docker.
Я хочу иметь два изображения: один для RHEL-подобного, второй для Debian-подобного, чтобы быть уверенным в том, что во время тестового прогона все будет хорошо и с RHEL, и с Debian.
Это шаг предварительной подготовки среды выполнения тестов.
Вроде бы все поднялось, но иногда нужно выполнить какие-нибудь дополнительные настройки. В случае тестирования внутри приподнятого Docker в Debian или Ubuntu, требуется поставить второй Python, что часто бывает.
Этап первого большого прогона роли внутрь instance, чтобы убедиться, что она добегает до конца, прогоняется, и Ansible подтверждает, что все хорошо.
Проверка на идемпотентность простая и выглядит так.
В результате мы понимаем, что наша роль не действует деструктивно.
Этот этап у ребят, с которыми я работаю, вызвал боль. Они пытались пойти обходными путями, чтобы победить проверку на идемпотентность. У Molecule можно управлять этапами, которые она проходит, и первое, что они сделали — отключили проверку на идемпотентность.
Мы ловили отключения и били за это по рукам, но инженеры умные и пошли глубже. Разработчики решили говорить, что этот шаг в Ansible ничего не меняет.
Хотя на самом деле здесь появится какая-то команда. Ansible прямо возьмет и
будет перезаписывать файл, но при этом все выглядит идемпотентно.
Когда эту хитрость тоже отловили, картинка стала выглядеть так.
Хорошо — сценарий пробежал под именем default, и он идемпотентный.
На следующем этапе накладываются побочные эффекты. Это делать необязательно, но удобно, когда вы тестируете сложные развесистые роли, зависимые друг от друга.
Например, поднимаете ELK stack, затем Elasticsearch в кластере. На этапе side_effect добавляете тестовых данных и удаляете пару узлов из кластера. Тестовый полигон готов для функциональных тестов, которые происходят на следующем этапе.
Тестируем инфраструктуру.
Выше пример очень простого теста. Мы проверяем, что у нас пакет Docker Community Edition в случае Ubuntu установлен, у него нужная версия, и сервис запущен.
На этом этапе запуска функциональных тестов можно все сильно усложнить.
Наверно, лучшим примером будет, в случае ELK stack, если на каких-то тестовых данных сделаем запрос в Elasticsearch, и так как тестовые данные нам известны, то он нам ответит. Мы не будем проверять, что все установленные компоненты собраны, а посмотрим, что Elasticsearch поднят, работает и выдает на поиске именно то, что нужно.
Когда бегут функциональные тесты, это выглядит вроде бы красиво, прогоняется по всей инвентаризации вверх-вниз, и система сообщает нам о том, что у нас все хорошо. Опять же, тесты будут бежать, если мы их напишем.
Мы провели тесты, test report в каком-то виде есть и теперь убираем весь мусор за собой.
Molecule — отличный инструмент. Теперь осталось самое простое — подключить к нему систему непрерывной интеграции, чтобы наслаждаться автоматическим тестированием наших ролей, что мы и сделали.
Как и везде, есть несколько особенностей.
Некоторые роли, которые мы пишем для автоматизации чего-то, хороши, но мы не можем тестировать систему с помощью Travis, потому что роли разворачивают продукты, которые мы не можем выложить в общий доступ по лицензионным соображениям.
Например, у вас есть автоматизация разворачивания базы Oracle. Если выложите в файл инсталлятор базы, то к вам придут юристы компании и будут сильно ругаться. Чтобы все жили в мире и не ругались, мы решили сделать следующее.
Фактически роль лежит публично, данные тоже, и мы никого не обманываем — у нас прогоняются реальные тесты с реальными инструментами.
Давайте посмотрим по шагам, как это выглядит в Travis.
По шагам:
Публичный CI выглядит элементарно.
От GitHub стрелочка к Travis, внутри которого живёт Molecule и Docker.
Для приватной части GitLab все то же самое.
В приватном периметре у нас запущен runner, и картинка выглядит веселее.
Код попадает из GitHub в GitLab, где-то бежит приватный runner, который умеет дергать внешние сервисы, например, запускать что-то в Amazon.
Маленькое отступление. Запуск и разворачивание тестовой среды в Amazon не хочется переносить, потому что нужны ключи. Придумывать механизмы, чтобы положить их в паблик, но при этом не стать очередной стартап-платформой для майнинга — это нетривиальная задача. Поэтому мы ее не решали, а унесли runner в приват, чтобы не майнить биткойны Amazon.
Даже здесь, мы чуть-чуть поленились и сделали следующее. У нас в EPAM есть свое приватное облако и оно гибридное. Это значит, что многие публичные облака доступны из внутреннего облака, как регионы. Можно не писать тысячу тестов, а поиграться с регионами и сказать: «Теперь проведи тест вот по этому тестовому сценарию для региона AWS, EPAM Cloud, Azure».
Подошли к финалу, наша роль зеленая, красивая, опубликуем ее в Galaxy.
Это простая операция:
Есть одна особенность — если вы не маркируете роль, не тегируете, не назначаете ей версию, то в Galaxy она всегда будет без версии. Как только другой разработчик захочет ее себе поставить через Ansible Galaxy install, он заберет роль, которая лежит в мастер-ветке, либо в другом branch по умолчанию. По умолчанию branch не всегда стабилен, что неудобно.
Если вы что-то публикуете в Galaxy, не забывайте это тегировать, прямо чтобы были версии, и все было клево.
Делюсь маленькой хитростью: чтобы каждый раз не копипастить при написании новой роли, мы решили создать шаблоны и отдельный репозиторий, в который положили шаблон, чтобы быстро с нуля писать роли.
У шаблона есть настройки по умолчанию для Ansible lint и GitHub issue_template. Всё в свободном доступе, поэтому issue_template в красивой форме, чтобы pull request или bug reports нам оформляли тоже красиво. В тот же репозиторий складываем шаблоны для Gitignore, Gitlab-ci и лицензию.
По умолчанию мы публикуемся под лицензией Apache 2.0. Если захотите сходить к нам и переиспользовать шаблоны, то можете всё забрать, создать закрытый репозиторий и никому ничего не объяснять. Спасибо Apache.
У нас лежит несколько вариантов тестов, чтобы можно было быстренько все пнуть и завести.
Заключения не будет, вместо него есть ссылки на мой GitHub [4], мой профайл в Galaxy [5], на GitHub Lean Delivery [6] и Ansible Galaxy [7]. По ссылкам можно посмотреть, как все работает. Все примеры в свободном доступе.
Следующая конференция по DevOps [1] пройдет в мае.
Пока мы в ожидании события, подпишитесь на YouTube-канал [8] и рассылку [9]. Канал будет пополняться записями лучших докладов, а в рассылке будут подборки полезных материалов, расшифровки и DevOps-новости.
Подписывайтесь, будет интересно:)
Автор: osminog
Источник [10]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/sistemnoe-administrirovanie/303473
Ссылки в тексте:
[1] DevOps Conf Russia: https://devopsconf.io/
[2] kharkevich: https://habr.com/users/kharkevich/
[3] EPAM Systems: https://habr.com/company/epam_systems/
[4] мой GitHub: https://github.com/kharkevich
[5] профайл в Galaxy: https://galaxy.ansible.com/kharkevich
[6] GitHub Lean Delivery: https://github.com/lean-delivery
[7] Ansible Galaxy: https://galaxy.ansible.com/lean_delivery
[8] YouTube-канал: https://www.youtube.com/c/DevOpsChannel
[9] рассылку: http://eepurl.com/bN_0E1
[10] Источник: https://habr.com/post/431542/?utm_campaign=431542
Нажмите здесь для печати.