Доброго времени суток. На Хабре не раз упоминался ansible, но статей о тестировании его ролей при помощи molecule мной обнаружено не было, однако Я нахожу данный фреймворк крайне удобным и хотел бы поделиться этим с аудиторией Хабра.
Но для начала немного о том, чем я пользовался прежде.

Прежде для тестирования создаваемых мной ролей ansible я использовал vagrant, вбивая незамысловатые:

$ vagrant init debian/jessie64
$ vagrant up

Создавая виртуальные машины, после чего писал inventory и playbook для запуска роли, пока однажды мне не довелось познакомиться с molecule.

Что может предложить molecule?


  1. Первоначальная инициализация роли
  2. Driver/Provider
  3. Тесты на идемпотентность
  4. Верификация

Первоначальная инициализация роли


В случае указания новой роли создает типовую структуру для роли 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)


  1. gecube
    23.01.2019 11:39

    Есть. Как минимум — habr.com/ru/company/oleg-bunin/blog/431542

    И еще — а Вы точно уверены, что все роли должны быть идемпотентными?
    А если ансибль у нас используется как просто способ описания для каких-то задач (например, бекап, или изменения в инфраструктуре) — очевидно, что могут быть разные сценарии.


    1. urtow
      23.01.2019 12:17
      +1

      Да, все роли должны быть идемпотентными. Потому что иначе будет больше геморроя, чем пользы.
      НЕ НАДО использовать ansible для бекапа. Тут справится и bash скрипт.
      Изменение в инфраструктуре ОБЯЗАНО быть идемпотентным, потому что плейбук описывает состояние К которому надо привести систему, а не действия которые надо выполнить.


      1. gecube
        23.01.2019 13:01

        Я сам сильно агитирую за то, что Вы пишете, но, к сожалению, у многих альтернативное мнение.

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

        Еще момент, что идемпотентность в сложных случаях будет все равно реализована путем написания своих императивных модулей (условно — мы хотим удалить файл, то тогда нам все равно нужно две вещи: проверить, что он существует, и потом уже его удалить — обе, очевидно, императивщина).


        1. urtow
          23.01.2019 13:23

          Альтернативное мнение, как и мнение альтернативно одаренных не стоит учитывать, себе доорже выйдет.

          Мое мнение, что инструмент под задачу, а не растить монстра из одного инстнумента. Приведем тот же пример с бекапами. Бекап нужно
          а) Создать. Скопировать файл, сделать дамп базы, etc.
          б) Перенести в место, где он будет хранится. Иметь возможность настроить правила типа «Хранить Х бекапов за срок Y», удалять старые бекапы и далее.
          в) Проверить бекап. А не нулевой ли у нас дамп? А не побился ли файл при сохранении? И далее, далее. Gitlab учит нас этому :)
          г) Как-то восстановить бекап.

          Это мои базовые требования к системе, которая делает бекапы. Все на основе личнгого опыта и опыта коллег. Что-то меньшее — не имеет смысла, потому что я просто не буду ему верить. Делать все это на ansible? Ну… каждый развлекается как хочет. Но вот в продакшене я бы за такое бил по рукам :)

          Да, надо писать свои модули. А как иначе? :)
          Касательно удаленного файла, у вас небольшая ошибка. Мы описываем состояние, а не действия. То есть мы не хотим удалить файл. Для нас важно, что файла нету. То есть это по факту один модуль, который в самом простом случае выполняет команду rm -rf path || true.


    1. truetrup Автор
      23.01.2019 12:48
      +1

      Есть. Как минимум — habr.com/ru/company/oleg-bunin/blog/431542

      Должен добавить, что это пост из песочницы. Пост мной был написан в ~ мае 2017 и на тот момент каких-либо упоминаний molecul'ы на хабре мной обнаружено не было.
      В остальном полностью согласен с urtow


  1. andreymal
    23.01.2019 15:36

    при повторном запуске роли не должно произведено каких-либо изменений.

    К сожалению, на практике это не всегда возможно в том числе из-за багов самого Ansible. Например, модуль pip почти всегда выдаёт changed, даже если на деле ничего не изменилось. Из-за подобных косяков мне не удаётся добиться полной идемпотентности (если понимать под этим changed=0) своих ролей, как бы я этого ни желал


    1. kharkevich
      23.01.2019 19:18

      всегда же можно исправить баг в ансибле


      1. andreymal
        23.01.2019 19:21

        Тогда очень странно, что за год с лишним его так никто не исправил, это же так легко


        1. kharkevich
          23.01.2019 20:06
          +1

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


          1. gecube
            23.01.2019 22:29

            Опенсурс такой опенсурс. Все пользуются, мирятся с багами, а когда доходит до дела — фиксить некому. Шикарно. Я уж не говорю о том, что наверняка есть фиксы на указанные баги, но тут уже включается бюрократическая машина, которая попросту не может завалидировать 1.5к пулл реквестов. Просто отлично!

            Второй момент. В других SCM (puppet, salt, chef) я не видел аналогичных проблем в аналогичных модулях, что показывает ansible 100% не с лучшей стороны.