Как стать автором
Обновить

Комментарии 15

Идемпотентность — ключевое требование к Ansible-ролям.
Система после каждого запуска должна приходить в одинаковое состояние

Расскажите, как это выглядит на практике. Допустим, в версии 1 роль делала apt-get install libfoo. В версии 2 роли libfoo больше не нужна и она перестала делать apt-get install. Вопрос. Как привести машины, на которых ранее прогонялась версия 1, в одинаковое состояние с машинами, на которых сразу выполняли версию 2? Удалять в роли пакет? Нельзя, может он другим ролям нужен, не?

Добавить libfoo в эти самые другие роли, не?

А если таких ролей не оказалось? Кто удалит libfoo?

Как вариант, делаем отдельный таск удаления пакета libfoo, если он установлен и прогоняем по нужной группе хостов. Навешиваем тэг таске для установки пакета libfoo, и при следующем запуске роли этот тэг игнорируем.

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

Давайте разберемся.

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

Во вторых если речь о вспомогальном пакете- библиотеке, напрямую не влияющием на функционал ПО из роли (например jq) - я бы грохнул, без зазрения совести. Если же речь о пакете - зависимости, то либо он не нужен, так как меняется версия, устанавливаемого ПО (а значит меняются переменные - версии и ни о какой идемпотентности после запусков не может быть речи), либо в новой версии у нас появился пересобранный deb пакет без зависимости. А если другим ролям всё таки этот пакет нужен - то смотри пункт про проверку зависимостей. И пошагово:

  1. Роль А версии 1 установила зависимость.

  2. Роль Б подтвердила наличие зависимости.

  3. Роль А версии 2 удалила зависимость при apt install -y.

  4. Роль Б установила зависимость.

  5. Роль А версии 2 не внесла изменений при apt install -y.

И пошагово

Эм в смысле, вы предлагаете вечно хранить все версии роли? Что будем делать когда древняя версия сломалась? Ну там сертификат протух или урл сменился или ещё какая хрень?

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

Кстати, спасибо за идею.

Не забывайте про SOLID. Принцип единой ответственности никто не отменял. Это существенная смена функционала. Т.е. в вашем случае пишем дополнительную проверку на наличие версии и формируем проведение в зависимости от потребностей (оставляем как есть/удаляем и ставим новую).

Кстати, я обычно делаю versionlock для пакета - это прям про идемпотентность, если на тачке пасётся ещё кто нибудь с котом кроме меня. При управляемом обновлении поконтурно указываю новую.

С рутом

оставляем как есть/удаляем и ставим новую

Как роли принять решение об удалении если она не знает о существовании других ролей, которые могут не хотеть удаления?

Роль не знает ничего об окружении и других ролях. Про вспомогательный пакет я уже писал. apt yum dnf rmp не удаляют "чужие" используемые зависимости.

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

Например, в ходе установки какого-то ПО понадобилось включить ip_forward. На первый раз решил включить руками, а потом это не требуется (можно запамятовать). Вот такие моменты помогает вычислить возвраты к первому состоянию ВМ.

Ещё рекомендую использовать мультироли. Каждая суброль должна выполнять маленький блок и быть независимой. Как раз теги помогут вызвать именно ту самую суброль, которая нужна. А meta поможет настроить между ними зависимости в случае необходимости.

Например, вам необходимо установить ПО, которое деплоится только через Docker Compose. Вот тут и пригодится зависимость через meta, которая устанавливает Docker.

Примеры очень упрощённые, но думаю суть вы поняли.

Опять по порядку, на основании собственно опыта.

Например, в ходе установки какого-то ПО понадобилось включить ip_forward. На первый раз решил включить руками

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

Например, вам необходимо установить ПО, которое деплоится только через Docker Compose

Значит ставим Compose как зависимость. Вызывать тегами отдельную роль - для меня странно. Я придерживаюсь подхода в котором в любой роли теги имеют одинаковое именование. При вашем подходе, вместо изолированного конфигурирования роли А ( тег config) я пройдусь по по всему кластеру.

Про мультироли наверное самый яркий пример - установка отказоустойчивого кластера postgres. В некоторых случаях наверное это более понятная концепция, нежели вязать через CI/tower последовательный деплой.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации