Но для начала немного о том, чем я пользовался прежде.
Прежде для тестирования создаваемых мной ролей ansible я использовал vagrant, вбивая незамысловатые:
$ vagrant init debian/jessie64
$ vagrant up
Создавая виртуальные машины, после чего писал inventory и playbook для запуска роли, пока однажды мне не довелось познакомиться с molecule.
Что может предложить molecule?
- Первоначальная инициализация роли
- Driver/Provider
- Тесты на идемпотентность
- Верификация
Первоначальная инициализация роли
В случае указания новой роли создает типовую структуру для роли ansible
Driver/Provider
Molecule позволяет нам использовать в качестве подопытного кролика либо Docker-контейнер, либо виртуальную машину посредством Vagrant-а определяется это указанием driver-а при инициализации, либо в molecule.yml. Т.к. мне приходится тестировать роли оркестрирующие контейнеры, то предпочтительным для меня в качестве driver-а остается Vagrant. Выбор Vagrant-а в качестве driver-а так же позволяет выбрать Provider-а.
Доступны следующие:
- Libvirt
- Parallels
- VirtualBox (default)
- VMware Fusion
Далее будет рассматриваться вариант Vagrant-а с VirtualBox в качестве provider-а.
Тесты на идемпотентность
Cогласно wiki:
свойство объекта или операции при повторном применении операции к объекту давать тот же результат, что и при одинарном.
Применительно к ролям ansible — при повторном запуске роли не должно произведено каких-либо изменений.
Верификация
Для того, что бы убедиться в том, что роль отработала должным образом — не завалить какой-либо из task-ов недостаточно. Ведь необходимо проверить, что сервисы стартовали, порты открыты и т.д.
Для верификации доступны следующие фреймворки:
- Goss
- Serverspec
- Testinfra (default)
Мной были опробованы Goss и Testinfra. Для себя я выбрал Testinfra.
Пример использования:
$ molecule init --role sample-role
После выполнения данной комманды мы получаем дирректорию sample-role c типичной для роли ansible структурой и необходимыми yaml-файлами:
defaults
handlers
meta
molecule.yml // конфиг-файл для molecule
playbook.yml // плэйбук для запуска нашей роли
README.md
tasks
tests // скрипты для верификации
vars
Можно запустить без указания ключа --role, в этом случае буду созданы файлы molecule.yml и playbook.yml в текущей дирректории.
Бывает, что требуется обеспечить работу роли на нескольких дистрибутивах в этом случае в molecyle.yml стоит указать имена box-ов vagrant-а (в platforms):
vagrant:
platforms:
- name: jessie64
box: debian/jessie64
- name: centos7
box: centos/7
Далее добавляем необходимые действия/переменные и т.д. в роль, после чего тестируем на всех определенных платформах:
$ molecule test --platform all
После этого molecule:
- в случае наличия уже созданных виртуальных машин остановит и удалит их
- поднимет необходимые виртуальные машины
- проверит нашу роль при помощи ansible-lint
- выполнит нашу роль но новосозданных контейнерах
- произведет тест на идемпотентность
- запустить тесты testinfra
- удалит созданные виртуальные машины
Может потребоваться изменить поведение molecule при запуске test, например не производить тест на идемпотентность, для этого в molecule.yml стоит добавить следующее:
molecule:
test:
sequence:
- destroy
- syntax
- create
- converge
- verify
- destroy
Так же можно вызывать каждый из соответствующих шагов отдельно при помощи соответствующей комманды, пример:
$ molecule create --platform all
$ molecule syntax
$ molecule create
$ molecule converge
$ molecule verify
Как один из вариантов — не удалять/создавать новую виртуальную машину перед каждым converge.
Можно указать определенную platform-у и протестировать ее отдельно:
$ molecule create --platform jessie64
$ molecule syntax
$ molecule create
$ molecule converge
$ molecule verify
Спасибо за внимание!
Комментарии (10)
andreymal
23.01.2019 15:36при повторном запуске роли не должно произведено каких-либо изменений.
К сожалению, на практике это не всегда возможно в том числе из-за багов самого Ansible. Например, модуль pip почти всегда выдаёт changed, даже если на деле ничего не изменилось. Из-за подобных косяков мне не удаётся добиться полной идемпотентности (если понимать под этим changed=0) своих ролей, как бы я этого ни желал
kharkevich
23.01.2019 19:18всегда же можно исправить баг в ансибле
andreymal
23.01.2019 19:21Тогда очень странно, что за год с лишним его так никто не исправил, это же так легко
kharkevich
23.01.2019 20:06+1Значит это никому не мешало, ну не настолько что бы взять и исправить.
По поводу легко — сейчас в ансибле открыто болешь чем 1.5к пулл-реквестов, нужно ещё как-то пробится через эту всю толщьgecube
23.01.2019 22:29Опенсурс такой опенсурс. Все пользуются, мирятся с багами, а когда доходит до дела — фиксить некому. Шикарно. Я уж не говорю о том, что наверняка есть фиксы на указанные баги, но тут уже включается бюрократическая машина, которая попросту не может завалидировать 1.5к пулл реквестов. Просто отлично!
Второй момент. В других SCM (puppet, salt, chef) я не видел аналогичных проблем в аналогичных модулях, что показывает ansible 100% не с лучшей стороны.
gecube
Есть. Как минимум — habr.com/ru/company/oleg-bunin/blog/431542
И еще — а Вы точно уверены, что все роли должны быть идемпотентными?
А если ансибль у нас используется как просто способ описания для каких-то задач (например, бекап, или изменения в инфраструктуре) — очевидно, что могут быть разные сценарии.
urtow
Да, все роли должны быть идемпотентными. Потому что иначе будет больше геморроя, чем пользы.
НЕ НАДО использовать ansible для бекапа. Тут справится и bash скрипт.
Изменение в инфраструктуре ОБЯЗАНО быть идемпотентным, потому что плейбук описывает состояние К которому надо привести систему, а не действия которые надо выполнить.
gecube
Я сам сильно агитирую за то, что Вы пишете, но, к сожалению, у многих альтернативное мнение.
К тому же это реально удобно (что, видимо, и приводит к описанному мной) иметь один инструмент для решения задач (а не тащить 100500 разных тулингов).
Еще момент, что идемпотентность в сложных случаях будет все равно реализована путем написания своих императивных модулей (условно — мы хотим удалить файл, то тогда нам все равно нужно две вещи: проверить, что он существует, и потом уже его удалить — обе, очевидно, императивщина).
urtow
Альтернативное мнение, как и мнение альтернативно одаренных не стоит учитывать, себе доорже выйдет.
Мое мнение, что инструмент под задачу, а не растить монстра из одного инстнумента. Приведем тот же пример с бекапами. Бекап нужно
а) Создать. Скопировать файл, сделать дамп базы, etc.
б) Перенести в место, где он будет хранится. Иметь возможность настроить правила типа «Хранить Х бекапов за срок Y», удалять старые бекапы и далее.
в) Проверить бекап. А не нулевой ли у нас дамп? А не побился ли файл при сохранении? И далее, далее. Gitlab учит нас этому :)
г) Как-то восстановить бекап.
Это мои базовые требования к системе, которая делает бекапы. Все на основе личнгого опыта и опыта коллег. Что-то меньшее — не имеет смысла, потому что я просто не буду ему верить. Делать все это на ansible? Ну… каждый развлекается как хочет. Но вот в продакшене я бы за такое бил по рукам :)
Да, надо писать свои модули. А как иначе? :)
Касательно удаленного файла, у вас небольшая ошибка. Мы описываем состояние, а не действия. То есть мы не хотим удалить файл. Для нас важно, что файла нету. То есть это по факту один модуль, который в самом простом случае выполняет команду rm -rf path || true.
truetrup Автор
Должен добавить, что это пост из песочницы. Пост мной был написан в ~ мае 2017 и на тот момент каких-либо упоминаний molecul'ы на хабре мной обнаружено не было.
В остальном полностью согласен с urtow