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

Наделяем Ansible состоянием, делая похожим на Terraform

Уровень сложностиСложный
Время на прочтение7 мин
Количество просмотров8.7K
Всего голосов 17: ↑14 и ↓3+11
Комментарии8

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

Выдёргивал динамический ip адрес создаваемой VM в yandex cloud из фактов, и добавлял его в inventory для других тасков. Своего рода динамический inventory. Хотя создавать VM с помощью Ansible весьма специфичная задача, для этого действительно есть terraform).

Почему не pam с лдапом и корректные sudo?

Так статья не про настройку Linux. Но sssd, pam и sudo мы используем.

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

Господи зачем так сложно? Если задача только в пользователях - сразу опиши эту логику в роли… у меня есть роль которая работает по примерной логике 1) есть список пользаков в ансибле (на самом деле он еще отрезается в зависимости от энва) 2) есть модуль который отдает тебе список пользаков в системе с фильтром (например по комменту к пользавотелю) 3) первая часть роли убеждается что все пользователи из списка в аесибле есть в системе (все ключи все баш профили и ид) 4) вторая часть роли вырезает разницу между тем что получили в пункте 2 и тем что в списке в весибле и удаляет всех лишних … все

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

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

Прорабатывали предложенный вариант с вызовом модуля ansible.builtin.getent. Не могу сказать, что получилось проще. Подход с использованием фактов показался более универсальным.

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

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

Все верно, именно getent. По поводу проще или нет - вы предлагаете из одного инструмента сделать другой (что не раз упоминаете в статье), я же просто реализовал идемпотентность на уровне роли стандартными методами инструмента (никакого питон кода). Так давайте подумаем логически, что же проще? ;)

Давайте) Я не хочу делать монстра, а предлагаю точечно использовать нужное нам поведение из Terraform.  Можно обойтись без упоминания Terraform, но тогда понадобится дольше пояснять, что хочется реализовать.  На самом деле Terraform использует текущий конфиг(1), ранее примененный – tfstate(2) и текущее состояние по управляемым элементам(3), что, действительно, является честным поведением. В статье используется сравнение 1-2, в Вашем подходе 2-3. Так что, думаю, и в Вашем случае можно сказать «вы предлагаете из одного инструмента сделать другой». Можно это как угодно назвать, но реализованная логика и сложность не поменяется.

И в Вашем и моем подходе используется «идемпотентность на уровне роли стандартными методами инструмента (никакого питон кода)».

Дополнительно, предложенный мною подход имеет следующие сильные стороны:

1.       Безопасность – используем только объекты, ранее попавшие под управление. Не пытаюсь работать со всеми пользователями в системе. К примеру, условие сравнения пользователей может быть некорректным (пустая переменная или пробел), что может привести к попытке удаления всех пользователей ОС, маловероятно, но возможно. Подход с управлением только «своими» элементами использует Terraform, и я это поддерживаю.

2.       Функционал – можно использовать поля из удаляемых объектов, говорил в комментарии выше.

3.       Универсальность – локальные факты можно использовать в других задачах примерно с одинаковой кодовой базой. Если сравнивать с «живым» состояние системы, то потребуется каждый раз вызывать соответствующие утилиты и заниматься парсингом их вывода, задача может стать сложной ввиду различий вывода от версии к версии.

Но есть и слабые стороны:

1.       Сложно вывести элемент из-под управления – нужно редактировать факты.

2.       Возможность удалить всех пользователей под управлением роли – по этой причине идет проверка на наличие минимум двух админов.

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

Жирным – подход из статьи, курсивом – сравнение на «живую». Без форматирования общие шаги

1.       Различные проверки – скорее всего одинаково по сложности.

2.       Обновить локальные факты – модуль setup

3.       Управление имеющимися пользователями и другие шаги, связанные с этим – одинаково по сложности.

4.       Получаем актуальный список пользователей – модуль getent

5.       Удаление пользователей. В одном случае diff по фактам.  В другом diff из модуля getent. Одинаковая сложность если выкинуть реализацию работы с отдельными параметрами удаленных элементов.

6.       Сохранить переменные в локальные факты – модуль copy

7.       Повторно обновить локальные факты – модуль setup. На самом деле модуль вызывать не обязательно. Другой код, работающий с фактами, должен обновить их самостоятельно, как делается в п2, добавлено для наглядности.

Думаю, пункты 4 и 6 соразмерны в ложности реализации.  В сухом остатке, вся разница выражается в двух вызовах модуля setup (один обязательный, второй для перестраховки). В результате «Не могу сказать, что получилось проще», учитывая сильные и слабые стороны подхода, но точно не «Господи зачем так сложно?».

Искренне признателен, что заглянули в комментарии, рассказали о своем опыте и отстаиваете его. Читателям будет полезно знать предложенный Вами подход, спасибо!

Я точно так же реализовал) Только во втором пункте у меня просто /usr/bin/getent отдает пользаков и сравнивается со списком, лишнее удаляем. Раньше был отдельный список для удаленных пользаков.

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