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

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

НЛО прилетело и опубликовало эту надпись здесь

Мой опыт показывает, что все то, что дают теги в плане разделения сценариев запуска, можно реализовать и без тегов. Т.е. иметь все плюсы, но без минусов. Если можно обойтись без костылей, то зачем их использовать?

НЛО прилетело и опубликовало эту надпись здесь

Я писал довольно много больших проектов на Ansible. Как ролей, так и плейбуков. И даже модули с плагинами. Так что некоторое представление имею. И да - я не видел еще ни одной реальной задачи на Ansible, которую нельзя было бы реализовать без тегов.

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

Теги очень хороши когда у вас роли вынесены в библиотеку, по умолчанию роли написаны для работы без тегов, но специфичные таски обвешаны тегами, что позволяет точечно запускаться для разбора инцидентов

Тут тоже, на мой взгляд, проще тогда сделать отдельные плейбуки на каждый сценарий запуска, куда включать нужные таски из ролей. Для этого есть специальная конструкция: tasks_from для модуля include_role.

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

Статью в целом можно свести к 2 тезисам:

  • Не используйте теги в тасках ролей, используйте в плейбуках на уровне ролей.

  • Используйте членство в группах и переменные для управления ролями.

Но кажется что проблема кроется глубже:

Итак, лично мое мнение на этот счет такое. Теги в Ansible – это аналог оператора GOTO в инфраструктурном коде. В программировании оператор безусловного перехода (goto) давно считается плохим стилем.

Нет, конечно.
Использую теги только над ролями и не понимаю о какой проблеме говорит автор?
Если одним тегом помечается несколько ролей, то в плейбуке они и так перечисляются в порядке их преполагаемого выполнения.
Где проблема?

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

Отсюда и растет непонимание. Ansible - это не программа с порядком исполнения, а набор шагов последовательно преводяший состояние к желаемому. Это никак не код с каким-то локальным контекстом из-за выскакивания/заскакивания из/в который так не любят goto. В идеальном ansible playbook никакого контекста нет вовсе (такого конечно не бывает на практике, но мы стремимся).

В мире Ansible аналогичную роль играют теги.

Нет. Теги играют роль ОПЕРАТИВНОГО (нужного не всегда, а в редких моментах) включения/отключения ролей при отладочном прогоне плейбука и при применении конкретных изменений. (например если мне нужно выкатить только изменения firewall, то я пишу --tag nftables (покрывающий одноименную роль) и получаю результат без ожидания прохода сотен тасок).

Отсутствие иерархии и дефолтных значений

А зачем мне иерария и дефолтные значения тагов если я ими только ОПЕРАТИВНО включаю/выключаю роли?
Иерархия включения ролей уже есть в каждом play в ключе hosts, что разумеется наследуется.
Дефолтные значения того чем нет необходимости постоянно пользоваться? Зачем?

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

Это не имеет отношения только к тегам. Проблема в соглашении об именовании всех вообще сущностей в ansible.
Аналогичные проблемы встречаются и с переменными. Возьмите какой-нибудь крупный проект (например kubespray) и посмотрите как там переменные называются.

Например, представьте плейбук с несколькими задачами, каждая из которых помечена разными тегами: install, config, deploy

Это неправильные границы разбития плейбука/ролей на задачи. Должна быть просто 1 роль: - { role: что_вы_там_запускаете }. Возможности дергать роль за потроха быть не должно.

если у вас есть аналогичные теги с таким же названием

А если будут аналогичные переменные? Что-то изменится?
Ну так скорее будет хуже, таги - просто включат/выключат отдельные роли и сервер останется в корректном текущем/прерыдущем состоянии, а переменные - сломают состояние сервера.

Теги просто не позволяют установить чёткую иерархию и структуру исполнения.

Она написана в плейбуке. Зачем мне для этого еще и теги? Неудобно.

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

Почему пытаемся? Вполне себе получаем. Тагируя только роли мы получаем ситуацию что прогон плейбука гарантированно корректно исполняется. Роли ведь не зависят друг от друга, а те которые зависят, помечаются одним тагом.

Вместо создания сценариев в виде плейбук, где каждая отвечает за отдельную часть процесса (например, nginx_install, nginx_configure, nginx_deploy), вы помечаете разные задачи тегами типа setup, configuration, deployment и т.п. В итоге получается код, который очень сложно поддерживать и масштабировать, так как задачи теряют контекст, превращаясь просто в набор абстрактных команд, запускаемых хаотично.

У вас какая-то ложная дихотомия или "аксиома Эскобара" ("что то... что это...").
Правильный выбор границ разбиения - { role: nginx }.

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

А какая разница как сильно растет это сочетание покуда таги не зависят друг от друга?

Допустим, у вас есть три задачи с тегами install, configure, start. Если мы используем все три тега в нашем коде автоматизации, то появляется не просто три сценария запуска, а восемькомбинаций: install, configure, start, install&configure, install&start, configure&start, install&configure&start

В очередно раз неправильная граница разбиения. Уже не смешно.

Можно выделить три условных плейбука: app_full_deploy app_packages_upgrade app_config

Снова неверные границы. Зачем?
Вот так надо: { role: app }.
Зачем мне плодить на каждую роль еще и несколько плейбуков?
По вашему "Infrastructure as a bash history" работает только в отношении тагов? А в отношении 100500 плейбуков не работает? Почему?
Нужно избавляться от сложности, а не переносить её в другую плоскость, где пока вы её не видите.

В эти плейбуки вы можете выборочно включать нужные файлы тасков или задавать гибкие критерии их запуска, используя различные инструменты ветвления кода (when, with_first_found, incude_tasks, tasks_from для ролей и т.п.)

Вот это уже просто пушка.
Правильное использование тагов конечно же в 1000 раз лучше, чем оголтелое навязывание вместо них любых условных конструкций. (Не рекомендую для всех: но последнее время максимально отказываюсь от when, как раз чтобы было видно отсутствие ветвления. И использую вместо него "{{ obj | selectattr() }}" (и т.п. и в том же духе) так что запуск превращается в запуск над подмножеством, а не ответвлением.)

инструменты ветвления кода

С "оператора ветвления" в контексте ансибл... кекнул в голос.

А что думаете на этот счет вы?

Думаю 10 кеков/10

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

Я ничего не придумал. Я описываю то, с чем регулярно сталкиваюсь на практике в чужом коде.

Использую теги только над ролями и не понимаю о какой проблеме говорит автор?

Т.е. вы заведомо ограничиваете применение тегов. Ок, это тоже вариант. Но зачем тогда притворяться, что не понимаете, что так делают далеко не все?

В идеальном ansible playbook никакого контекста нет вовсе (такого конечно не бывает на практике, но мы стремимся).

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

Нет. Теги играют роль ОПЕРАТИВНОГО (нужного не всегда, а в редких моментах) включения/отключения ролей при отладочном прогоне плейбука и при применении конкретных изменений. (например если мне нужно выкатить только изменения firewall, то я пишу --tag nftables (покрывающий одноименную роль) и получаю результат без ожидания прохода сотен тасок).

Что "нет"? Я описываю то, как теги используются в общем. И это встречается во многих проектах. То, что в ваших личных теги используются очень ограниченно и только для специальных целей, не означает, что всего остального нет.

А зачем мне иерария и дефолтные значения тагов если я ими только ОПЕРАТИВНО включаю/выключаю роли?

Опять вы все сводите только к своему случаю. Ваш юзкейс далеко не единственный.

Это не имеет отношения только к тегам. Проблема в соглашении об именовании всех вообще сущностей в ansible.Аналогичные проблемы встречаются и с переменными.

С переменными такая проблема тоже есть. Но у переменных есть иерархия и разные области применимости. Я, например, могу одной роли задать одно значение какой-то переменной, а другой - совершенно другое, хотя имя переменной тоже самое. И все это в рамках одного плейбука. С тегами так не получится.

P.S. В целом спасибо за интересные комментарии.

А теперь по другим - более странным комментариям:

Это неправильные границы разбития плейбука/ролей на задачи. Должна быть просто 1 роль: - { role: что_вы_там_запускаете }. Возможности дергать роль за потроха быть не должно.

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

А если будут аналогичные переменные? Что-то изменится?

Конечно. Потому что у переменных есть:

  1. Иерархия

  2. Приоритеты

  3. Область применения

Об этом в статье довольно детально написано.

У вас какая-то ложная дихотомия или "аксиома Эскобара" ("что то... что это...").Правильный выбор границ разбиения - { role: nginx }.

Я описываю конкретные примеры наиболее частого применения тегов. С которыми постоянно сталкиваюсь, смотря образцы чужого кода. При чем тут аксиома Эскобара?

А какая разница как сильно растет это сочетание покуда таги не зависят друг от друга?

Если вы не понимаете в чем проблема роста числа возможных сценариев запуска одного и того же кода, мне сложно будет это объяснить. Как столкнетесь - поймете.

Снова неверные границы. Зачем?Вот так надо: { role: app }.Зачем мне плодить на каждую роль еще и несколько плейбуков?

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

Вот это уже просто пушка.Правильное использование тагов конечно же в 1000 раз лучше, чем оголтелое навязывание вместо них любых условных конструкций. (Не рекомендую для всех: но последнее время максимально отказываюсь от when, как раз чтобы было видно отсутствие ветвления. И использую вместо него "{{ obj | selectattr() }}" (и т.п. и в том же духе) так что запуск превращается в запуск над подмножеством, а не ответвлением.)

И как это поможет? Допустим, роль у вас должна выполняться на нескольких разных дистрибутивах. Для одних дистрибутивов нужны одни модули, для других - другие. Для некоторых версий бывают нужны отдельные дополнительные таски. Расскажите, как эти сценарии использования роли покрывает "{{ obj | selectattr() }}"?

С "оператора ветвления" в контексте ансибл... кекнул в голос.

Не очень понятно, что вы там сделали, но если поясните, то будет понятнее.

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

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

Банально, у вас есть плейбук, который запускает приложение в docker на 1000 хостов, и все замечательно, но в моменте, вы осознаете, что у вас каждый раз при запуске плейбука уходит около часа времени на то, чтобы проверить, что на хостах установлен docker. Есть вариант распилить плейбук на 2, установку docker и установку приклада. Получается у нас 2 плейбука, вам надо написать инструкцию условному пользователю, а он должен понять, в какой последовательности запустить плейбуки. Можно вызавть оба плейбука их из третьего, можно придумать еще кучу сценариев, и один из них, который может в моменте оказаться наиболее подходящим - проставить теги.

Теги дают гибкость, они не всегда про удобство.

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

В статье подробно описано, какие проблемы это с собой несет и почему так делать не стоит. И нет - в любой комбинации (особенно не протестированной) корректная работа кода вовсе не гарантирована.

В программировании оператор безусловного перехода (goto) давно считается плохим стилем.

разработчики ядра линукс: ну да ну да, пошли мы нафиг

$ find ./linux-6.12/ -type f -name "*.c" -exec grep -E ".*goto\s.*" {} \; | wc -l
  201596

С этим не будет работать статический анализатор кода. И не будут работать всякие конструкции вроде --list-tasks. Ну, и все прочие описанные недостатки тоже никуда не деваются.

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

Публикации