Ansible & UML: Кто-нибудь пробовал описывать playbook’и на UML?

ansible-umlДля описания Ansible плэйбуков и ролей попробуем использовать UML-диаграммы. Ранее уже была предпринята попытка взглянуть на Ansible, как на некое подобие языка программирования под углом ООП, сейчас же проделаем подобное с помощью диаграмм классов UML.

Взаимосвязи ролей и плэйбуков изображаем в виде класс-диаграмм. Но для начала создаём пару новый стереотипов (stereotypes):

role-and-playbook-stereotype<<playbook>> для плэйбуков и <<role>> для ролей (при желании роли и плэйбуки можно даже в разные цвета стилями покрасить).

По именам ролей мы условились суффиксом (тот что до «/», у нас тут boo) обозначать принадлежность к определённой независимой системе.

 

Далее поговорим про методы наших «классов», зачем они нужны и вложенные роли.

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

Как только появляется необходимость различать части роли, это должно найти отражение в сценариях Ansible. Можно либо «выкусывать» нужные части с помощью тэгов или переменных (variables), либо разделять роль на несколько ролей. Мы пойдём вторым путём, но чтобы подчеркнуть тесную связанность новых ролей, поместим их в папку с исходной. Получатся эдакие подроли.

Например, дерево ролей для boo/collector может выглядеть так:

Тут мы выделили:

  • sys — папку с ролями для установки системных пакетов, для чего требуются права суперюзера (в некоторых обстоятельствах root нам не доступен для этого и выделили эту подроль)
  • code — папку с ролями для выливки кода из Git’а или ещё откуда-нибудь
  • api — папку с ролями для установки и конфигурации WEB API. Завели отдельную роль, поскольку не все ноды использующие роль code должны иметь доступ через API

В нотации UML это могло бы выглядеть как:

boo-collector-with-methodsгде вложенные роли обозначаются методами.

Тот факт, что роль boo/collector да и все другие роли обладают неким поведением по-умолчанию описанным в tasks/main.yml, отображаем следующим образом:

Перейдём к переменным (variables), значения которым обычно указываются в yml-файлах директории group_vars.

Их можно было бы отображать в виде атрибутов наших «классов», типа:

role-varsПроанализируем, что-бы могло означать следующее:

role-aggregation

Это могло бы означать, что роль boo/collector в meta/main.yml имеет упоминания других ролей: nginx (на конец-то знакомое слово!) и boo/common; и в файле с групповыми переменными необходимо указать значения переменным: boocollector_var1, boocollector_var2, boocollector_var3, nginx_config, boocommon_var1, boocommon_var2.

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

Агрегацией (aggregation, да и composition) считается уместным указывать жёсткую связь ролей, каждая из которых отвечает за выполнение каких-либо задач по развёртыванию на том же сервере, что и другая.

Менее жёсткой связью можно указывать зависимости от ролей отвечающих за выкатывание софта на других серверах:

role-useВ принципе это уже чем-то дублирует  Диаграмму Развёртывания (Deployment Diagram).

Ну, и на конец, рисуем картинку с плэйбуком:

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

Додумать, как мог бы быть отображён плэйбук, выкатывающий артефакты сразу на несколько групп серверов, предлагается факультативно. Я пока не придумал.

 


 

Таким образом, вполне не сложно заметить, что статическая структура системы развёртывания, построенной на Ansible, вполне сносно ложится на UML Диаграммы Классов (Class Diagram), и последние (диаграммы) могут быть использованы для документирования сложных процедур выкатки программных комплексов.

Было бы интересно узнать, как у вас происходит процесс моделирования-документирования процедур развёртывания.

До встречи.