Я изо всех сил пытаюсь сделать свои роли в Ansible в некоторой степени компонуемыми и пригодными для повторного использования.
У меня есть роль, которая выполняет несколько этапов. В зависимости от других ролей, применяемых к узлу, другие роли должны запускать задачи на каждом этапе.
Я работаю с PostgreSQL и управлением расширениями PostgreSQL, но для простоты воспользуемся примером веб-сервера и некоторых приложений, которые на нем работают.
В webserver
роль:
В myapp
роль должна иметь возможность добавлять некоторые настройки в конфигурацию веб-сервера, которые должен применяться до создания базы данных веб-сервера. Он также должен выполнить некоторые действия до того, как будет впервые указан веб-сервер.
В myotherapp
роль также необходимо добавить некоторые настройки в конфигурацию веб-сервера перед первым запуском, не сбивая настройки из myapp
. Он также должен выполнить некоторые действия после первого запуска веб-сервера, перезапустить его, выполнить дополнительную работу и снова перезапустить.
(Это надумано, но выражает все потребности моего реального варианта использования, не вдаваясь в подробности о внутренностях PostgreSQL, которые вы когда-либо хотели знать).
Я думал, что смогу использовать для этого обработчики. Есть webserver
просто огонь notify
s на каждом соответствующем шаге, чтобы другие роли могли подключать эти уведомления для добавления в списки или добавления ключей к хэшам, используемым для создания шаблонов конфигурации, запускать свои собственные задачи и т. д. restart_webserver
обработчик, который myotherapp
может уведомлять каждый раз, когда он хочет выполнить перезапуск, без необходимости знать, как этот перезапуск фактически выполняется. и т.п.
Тем не мение:
Если есть уведомление, обработчик должен существует. Ansible не допускает дополнительных обработчиков.
Если для уведомления существует несколько обработчиков, Ansible просто выбирает первый и игнорирует все остальные.
Уведомления срабатывают только в конце раздела воспроизведения. Их нельзя сразу уволить. Есть meta: flush_handlers
но он смывается все обработчики, даже те из других несвязанных ролей и задач, которые могут не ожидать, что их обработчики запустятся раньше.
Удивительно сложно добавить в список или добавить ключи к словарю. Поэтому довольно сложно составить несколько связанных ролей, не просто вручную склеив конфигурацию с некоторыми host_vars
yml.
Так что обработчики и уведомления, похоже, не умеют это делать.
Как написать составные задачи и роли?
Я пытаюсь использовать велосипедное колесо в качестве молотка? Вы просто не должны таким образом использовать роли? Кажется, это согласуется с концепцией роль.
Должно ли быть написано что-то неопределенно повторно используемое или менее чем полностью линейное, отбросив систему Ansible задач / ролей / переменных / и т. Д. И сделав это на Python в качестве модуля Ansible? Если да, то есть ли какой-либо практический способ реализовать большую часть мозгов такого модуля, как списки задач Ansible, файлы переменных yml и т. Д., И просто иметь логику управления в модуле, чтобы модуль не нужно было повторно реализовать тонны вещей?
Версия "PostgreSQL кишки":
А postgres_server
роль. Устанавливает Pg из пакетов дистрибутива или из исходного кода по мере необходимости. Есть много варов в defaults/main.yml
которые можно переопределить, чтобы контролировать поведение. Предоставляет возможность создания шаблона конфигурации PostgreSQL для предоставления параметров для postgresql.conf
. Позволяет вызывающему абоненту заменять или добавлять строки к pg_hba.conf
. После установки PostgreSQL от initdb. После настройки запускает PostgreSQL. Умеет запускать, останавливать и перезапускать postgres_server
(обработчик). Предоставляет факты, чтобы сообщить другим ролям, где установлен PostgreSQL.
А bdr_extension
роль. Назначен хосту, на котором бдр расширение будет установлено в PostgreSQL. Необходимо видеть факты, раскрытые postgres_sever
чтобы узнать, как установить. Может получать / компилировать / устанавливать BDR из git или устанавливать из пакетов ОС.
PostgreSQL не может начать успешно если bdr
находится в конфигурации shared_preload_libraries
. Так postgres_server
Запуск сервера должен быть отложен до его установки, если это расширение включено.
А bdr_node
роль. Зависит от postgres_server
и bdr_extension
. Знает параметры конфигурации PostgreSQL, необходимые для работы BDR на PostgreSQL, например max_wal_senders = 20
. Необходимо убедиться, что параметр конфигурации PostgreSQL shared_preload_libraries
имеет bdr
в его списке значений, разделенных запятыми, когда postgres_server
генерирует конфиг. Заменяет значение по умолчанию pg_hba.conf
шаблон в postgres_server
для включения записей репликации.
Эта роль должна запускать некоторые команды SQL после PostgreSQL запущен.
А pg_stat_statements
роль. Можно установить pg_stat_statements
расширение из пакетов git или ОС. Необходимо видеть факты, раскрытые postgres_sever
чтобы узнать, как установить. Требуется возможность добавлять в postgresql.conf
. Необходимо иметь возможность добавлять 'pg_stat_statements'
к shared_preload_libraries
настройка в конфигурации сервера PostgreSQL.
PostgreSQL не может начать успешно если shared_preload_libraries
находится в конфигурации pg_stat_statements
. Так postgres_server
Запуск сервера должен быть отложен до его установки, если это расширение включено.
Итак, узел BDR - это сервер PostgreSQL, у которого есть расширение BDR и расширение pg_stat_statements, а также другие.
я ожидается чтобы иметь возможность выставлять обработчики в postgres_server
роль и вызывать их из других ролей по мере необходимости, чтобы активировать соответствующие действия в postgres_server
роль, как перезапуск сервера БД, но, похоже, она совсем не так спроектирована.
Понимаю ли я все это полностью задом наперед, думая о ролях Ansible как о моделировании? роли?
Я не знаком с PostgreSQL, поэтому я не уверен в содержимом различных файлов конфигурации, которые вы упомянули, но если вам нужно разрешить нескольким ролям участвовать в одном файле конфигурации, я сделал это одним из двух способов в зависимости от от того, что поддерживает файл конфигурации:
Используйте файл конфигурации с большим количеством операторов include, чтобы включить дополнительные файлы конфигурации, расположенные в подкаталогах. Это хорошо работает с чем-то вроде Apache для правил перезаписи, директив конфигурации для конкретных приложений и виртуальных хостов.
Соберите файл конфигурации из нескольких файлов частичной конфигурации, хранящихся в каталоге, используя собрать модуль. Я использовал этот метод для создания файла master.cf для Postfix, поскольку у меня был postfix
роль и другая роль, которую необходимо добавить в файл Postfix master.cf. Поэтому я изменил postfix
роль для создания каталога /etc/postfix/master.d и обработчика, который собирает файлы в этом каталоге в файл master.cf. К сожалению, как вы отметили, поскольку я не могу вызвать обработчик в postfix
роль из другой роли, мне пришлось дублировать этот обработчик в моей дополнительной роли. Это немного меньше, чем идея, но это работает и идемпотентно.