Всем привет! Меня зовут Сидоров Антон, я руководитель отдела технической архитектуры в департаменте сопровождения информационных технологий ПСБ. Моя команда занимается архитектурой инфраструктурных систем, и сегодня я хочу рассказать вам про наш первый опыт использования подхода «Архитектура как код»
«Архитектура как код» (англ. Architecture as Code, AaC) — это уже не новый, но пока не получивший широкого распространения в силу недостатка зрелых и популярных инструментов подход к описанию информационных систем посредством создания и обновления различных диаграмм и схем с использованием текстового описания.
Что имеется в виду под архитектурой?
Само понятие «архитектура» имеет много определений. Но в общих словах всё сводится к структуре чего‑либо, выраженной через описание элементов и их взаимосвязи с внешним миром.
Сложность заключается в том, чтобы сделать это описание как можно более понятным и точным. В некоторых источниках этот подход так и называют «диаграмма как код», но это относится к случаям, когда область его применения сужена только до отрисовки схем, мы же рассмотрим комплексную концепцию с созданием архитектурного репозитория и организацией работы команды с ним.

Попросите кого‑нибудь из строительной отрасли показать архитектуру здания, и вам покажут планы участка, планы этажей, виды фасадов, виды в разрезе и подробные чертежи в единой нотации и устоявшейся терминологии.
В сфере информационных технологий архитектура традиционно также описывается в виде схем и диаграмм, но зачастую они представляют собой изображения с буйством форм и стилей, отличающимся цветовым кодированием и смешанными абстракциями.
Чтобы этого избежать в индустрии появились такие тяжеловесные стандарты как ArchiMate, SysML и подобные, но на практике большинство организаций уже отказались от них в пользу гораздо более простых схем с прямоугольниками и стрелками.
На разных этапах создания архитектуры — от создания концептуального дизайна до описания размещения на оборудовании разными участниками используются различные форматы представления информации: диаграммы последовательностей, ERD, компонентные схемы и прочее. У всех одна задача — упростить донесение информации о том, чем является конкретная информационная система и как она устроена. Системные архитекторы чаще всего работают со схемами сетевого взаимодействия, поэтому для примеров я буду опираться именно на этот вид схем, как более близкий мне по роду деятельности, но всё сказанное также применимо и для других типов документов, и может использоваться не только архитекторами, но и аналитиками, сопроводителями систем и вообще всеми, кто связан с подготовкой или ведением документации.
Что не так с традиционным подходом к описанию архитектуры?

На рисунке изображена типовая схема сетевого взаимодействия для информационной системы, состоящей всего из одного нового сервера.
Что с ней не так?
Мы видим сверху номер версии, но не знаем были ли кем‑то созданы более свежие;
Мы не можем добавить компонент, не нарушив раскладку карточек;
Мы не можем выгрузить все представленные на схеме соединения в виде легенды, чтобы дальше с ней могли работать коллеги из Блока информационной безопасности;
Рисунок статичен, и мы не можем «провалиться», например, в систему прокси, чтобы узнать с чем ещё она взаимодействует или как реализована балансировка, а добавление сведений на эту схему усложнит её восприятие;
Адреса некоторых серверов или их состав к моменту, когда мы рассматриваем эту схему могут быть уже неактуальны.
Одним из возможных способов устранения перечисленных проблем является совокупность мероприятий по созданию единого места для хранения схем и по изменению способа их создания и изменения.
Виды инструментов

Как и у других подобных подходов с использованием текстового описания, например, как у «Инфраструктуры как код» или «Документации как код», предпосылками к появлению стало желание применить довольно развитые к настоящему времени процессы из разработки программного обеспечения на другие области с целью автоматизировать и упростить трудозатратные и неоптимальные операции.
В развитии подхода можно очень условно выделить две группы инструментов: для отрисовки и для мод��лирования.
Отрисовка (Диаграмма как код)
Отличительная черта инструментов этой группы в том, что их языки описания опираются на объекты визуализации, в коде отражаются геометрические фигуры и их свойства, а не отражаемые абстракции.
Код на примере Mermaid.js (в народе — «Русалка»)
architecture-beta
group api(cloud)[API]
service db(database)[Database] in api
service disk1(disk)[Storage] in api
service disk2(disk)[Storage] in api
service server(server)[Server] in api
db:L -- R:server
disk1:T -- B:server
disk2:T -- B:dbПолучившаяся схема

На этом этапе диаграммы по‑прежнему создаются независимо, как отдельные файлы, и должны поддерживаться в нескольких местах одновременно. Каждый раз, когда требуется внести какое‑либо изменение, приходится помнить где и что заменить в каждом из этих расположений. Даже если потребуется просто переименовать объект, который присутствует на двух или трёх схемах (а на практике их может быть значительно больше) — придётся вносить изменения сразу в нескольких местах.
По сравнению с традиционным подходом (с использованием графических средств), это всё же прогресс: уже используются инструменты и сопутствующие процессы управления кодом, но тем не менее, еще не закрыты основные проблемные участки, такие как дублирование и трудоемкость актуализации документов.
Моделирование (Архитектура как код)
«Архитектура — искусство не изобразительное, а созидательное. Оно не изображает предметы, а создаёт их». Андрей Буров (архитектор, инженер‑изобретатель)
В случае моделирования создается один текстовый файл с моделью, а далее на базе неё уже строятся различные представления. Источник данных при этом один и в случае необходимости внесения изменений достаточно изменить только один раз саму модель.
В языках описаний инструментов этой группы уже присутствуют правила и мета‑модель, описываются представляемые сущности, а не объекты их отображающие.
Код инструментов группы моделирования на примере инструмента LikeC4
specification {
element system
element component
}
model {
api = system 'API' {
component server 'Server' {
}
component database 'Database' {
}
component storage1 'Storage 1' {
}
component storage2 'Storage 2'
server -> database
server -> storage1
database -> storage2
}
}
views {
view index {
title 'Landscape view'
include *
}
view api of api {
include *
}
}Снимок экрана с получившейся динамической схемой в одном из представлений. Понажимать можно в песочнице на официальном сайте.

Если инструменты первой группы можно было сравнить с заменой средств для рисования схем (таких как АСМО‑графический редактор, Microsoft Visio, draw.io, LucidChart и проч.), то архитектура как код с использованием инструментов группы моделирования призвана заменить такие специализированные средства разработки архитектуры как Sparx Enterprise Architect или Archi.
Какие существуют инструменты?
Я проанализировал существующие инструменты и узнал, что специалисты из разных областей уже давно пытаются создать идеальный для их сценариев использования вариант. Этим обусловлен сильный уклон инструментов в узкие области применения (корпоративная архитектура, локальные вычислительные сети и так далее).
В инструментах используются разные нотации, и в целом, даже способ использования различается от инструмента к инструменту: где‑то достаточно блокнота, а где‑то для просмотра диаграмм требуется рендеринг, запуск кода или даже отдельное пользовательское приложение. Ниже приведена сравнительная таблица с наиболее распространенными инструментами данного класса, которые мне удалось найти.
Название | Лицензия | Язык описания | Язык движка | Группа | Комментарий |
GPL-3.0 | DSL | Java | Отрисовка | Не самый современный, но безопасный выбор, огромное сообщество. | |
Eclipse Public License 1.0 | DSL (dot) | C | Отрисовка | Чаще всего используется только как движок для более высокоуровневых и удобных в использовании средств (например, PlantUML). | |
MIT | Python / Go | Python | Отрисовка | На базе graphviz, субъективно самый простой в использовании в случае Python, есть форк, написанный на Golang. | |
MIT | YAML | JavaScript | Отрисовка | Использование ограничено схемами сетей передачи данных. | |
MIT | DSL (Markdown‑подобный) | JavaScript | Отрисовка | Присутствуют диаграммы классов, процессов, но нет схем сетевого взаимодействия наподобие используемых в Банке и создаваемых в Microsoft Visio. | |
GPL 2.0 | DSL (ascii) | Java | Отрисовка | Редактирование в виде ASCII. Не совсем код, больше псевдографика, вносить изменения так же неудобно, как и в Visio. | |
MIT | DSL (ascii) | Ruby | Отрисовка | Расширения для asciidoctor (который в свою очередь на базе ditaa). | |
проприетарная | DSL | Java | Моделирование | Может интегрироваться с PlantUML, graphviz, Mermaid, ilograph, есть макросы для Confluence. В бесплатной версии ограничение на одно рабочее место и урезан функционал (отсутствуют интеграция по LDAP, внешнее хранилище). Лицензии постоянные, но обновления только по подписке $10/рабочее место в месяц. | |
MIT | DSL | TypeScript | Моделирование | Вдохновлен моделью C4 и Structurizr, стремительно набирает популярность в последнее время | |
проприетарная | YAML | TypeScript | Моделирование | Ilograph LLC, США (санкции для РФ), бесплатно для личного использования, для организаций цена по запросу. | |
проприетарная | Markdown | JavaScript | Отрисовка | Volare Labs, Колумбия, поддержка $1000/год на неограниченное кол‑во пользователей. Не рассматриваем для использования, но хороший пример инструментов такого класса. | |
Apache-2.0 license | - | JavaScript | Отрисовка | Упор на графический редактор. Может сохранять в XML и SVG, но создавать с нуля или редактировать их вручную не представляется возможным (большое число атрибутов с метаданными графического представления). | |
проприетарная | DSL (YAML‑подобный) | C# | Отрисовка | Зарубежное SaaS решение, в США, бесплатно для 5 участников, $80 за пользователя в месяц по расширенному тарифу, ролевая модель отсутствует. |
Основная трудность при выборе заключалась в том, что при всём многообразии инструментов, всё ещё не существует достаточно зрелого и универсального для практического использования. Ближе всего к реализации заложенных в подход идей подошло зарубежное коммерческое решение Structurizr от Саймона Брауна, создателя модели C4 (популярного метода моделирования архитектуры программных систем). Но с учётом действующих ограничений, наш выбор ограничен только инструментами от российских разработчиков и проектами с открытым кодом. Среди отечественного ПО решения класса «Архитектура как код», насколько мне известно, отсутствуют, а среди готовых свободно распространяемых решений с открытым исходным кодом наиболее подходящими под задачи системных архитекторов являются проекты Diagrams (mingrammer) и PlantUML. Оба относятся к первому поколению инструментов и не позволяют осуществлять полноцен��ое моделирование, но PlantUML более распространен в банковской сфере, имеет дополнения для VSCode, AHCode (Gitlab) и веб‑редактор, поэтому мы предпочли его.
Как это может быть устроено?
Эта статья начиналась два года назад как обзор концепции «Архитектура как код» для внутреннего использования. Тогда она, ограничиваясь теорией и обзором инструментов, отвечала на вопрос «что это?». Однако любой новый подход сталкивается со скептицизмом, который часто выражается известной фразой: «Гладко было на бумаге, да забыли про овраги», и чтобы ответить на главный вопрос: «как это применить?», я решил дополнить материал кейсом из нашего опыта пилотирования данного подхода.
Архитектурный репозиторий для хранения схем сетевого взаимодействия информационных систем представляет собой репозиторий в системе контроля версий, где для каждой системы выделен собственный каталог, имя которого соответствует уникальному единому буквенно‑цифровому коду, назначенному системе при её создании.
В каждом таком каталоге присутствует один или несколько текстовых файлов с кодом в формате PlantUML, а также графический файл с актуальной версией схемы и файл легенды к ней в формате таблицы Р7, которые хранятся в Git LFS.
В корне репозитория размещен файл common.puml, который содержит часто используемые точки сетевого взаимодействия с коммунальными инфраструктурными системами, чтобы не загромождать схемы других ИС лишней информацией об их внутреннем устройстве.
При каждом изменении кода схем систем автоматически выполняется конвейер CI/CD, который при помощи PlantUML превращает схему из кода в изображение, после чего запускается написанный мной скрипт на Python, который считывает все соединения в схемах и выгружает их в формате легенды к схеме, которую используют коллеги из информационной безопасности. Также можно экспортировать легенду и в других форматах, например, в виде готовых правил iptables.
Я разделяю принципы Open Source и планирую в будущем поделиться кодом скрипта, но чтобы сделать это корректно, обязан соблюдать внутренние политики, и на текущий момент процесс согласования публикации с соответствующими внутренними подразделениями ещё не завершен.
Работа со схемами
Создавать и редактировать схемы PlantUML можно в любом текстовом редакторе, но лично для меня самым удобным оказался вариант с VSCode и плагином предварительного просмотра jebbs.plantuml. На рисунке видно, как экран делится на три области: слева навигация по репозиторию, посередине основное окно редактирования с примером настоящей рабочей схемы системы управления адресным пространством и справа область предварительного просмотра, которая динамически перерисовывает схему при внесении правок.

Также в настройках Gitlab можно включить интеграцию с PlantUML Server, тогда для файлов PlantUML в интерфейсе рядом с кнопкой исходного кода появится кнопка предварительного просмотра без необходимости экспорта в графический формат. В качестве упомянутого сервера можно использовать исполняемый файл самого инструмента со встроенным PicoWeb, либо образ официального контейнера с jetty или tomcat на выбор.
В соответствии с известным принципом DRY (англ. Don«t Repeat Yorself, „Не повторяйся“), пришедшим из области программирования, для часто используемых взаимодействий с инфраструктурными компонентами в схеме информационной системе используется директива!include, которая импортирует значения переменных из общего файла common.puml. Это позволяет не описывать каждый раз повторно адреса и протоколы, а использовать вместо них переменные. По нашему соглашению в качестве имен используются единые буквенно‑цифровые коды информационных систем и они же с суффиксом _ports для переменных, содержащих типовые порты и протоколы для подключения. Например, для почтового сервера в файле common.puml могут использоваться следующие переменные:»
!$IS000002 = "<b>SMTP</b>\nsmtp.psb.example\n172.16.1.100"
!$IS000002_ports = "25/tcp (SMTP)"
Скрипт для генерации легенды к схеме также размещен в репозитории и изменения в котором отслеживаются системой контроля версий. Логика его работы такова:
Найти все соединения (которые обычно обозначаются как стрелки вида «‑→»);
С учетом всех директив include, используемых в коде схемы разрешить все нужные переменные;
С использованием регулярных выражений из общего массива вычленить нужные адреса сетей, порты и протоколы;
При помощи библиотеки openpyxl записать результат в файл с расширением xlsx.
Ниже в качестве примера приведен участок кода, описывающий все внешние соединения одной из систем и фрагмент файла с получившейся из этого кода легендой.
cld_prvate --> mail : $IS000002_ports
cld_private --> monitoring : $IS000010_ports
cld_private --> backup : $IS000008_ports
cld_private --> ntp : $AG000001_ports
cld_private --> repo : $IS000009_ports

Решаемые проблемы и выводы
Предложенная концепция внедрения подхода «Архитектура как код» — это непростое изменение, оно требует некоторого уровня инженерной культуры, дисциплины и зрелости процессов в организации. Схемы тоже получаются не такие симпатичные, как созданные вручную, тем не менее, оно действительно стоит того, так как позволит решить самые насущные наши проблемы:
Проблема | Решение |
Неизвестно какая схема системы последняя и где её искать. | Простая структура централизованного репозитория позволяет легко найти последнюю схему нужной системы по её уникальному буквенно‑цифровому коду, а использование системы контроля версий — сохранить всю историю изменений без появления отдельных файлов вида «схема_last(2)». |
В крупную сложную схему были внесены изменения, но неясно какие именно и не было ли других изменений помимо заявленных. | Текстовый формат схем позволяет наглядно отобразить внесенные изменения в системе контроля версий, а также их авторов, |
Процедура создания легенды к схеме сетевого взаимодействия долгая и мучительная, требуется вручную выписывать в таблицу каждый адрес, порт и протокол всех узлов и соединений на схеме. | Автоматическая генерация легенды по коду схемы. |
Политика импортозамещения не позволяет использовать мощные зарубежные инструменты (как Structurizr, например), а новые отечественные либо отсутствуют, либо пока что недостаточно зрелые для практического использования. | Использование свободного решения с открытым исходным кодом PlantUML в совокупности с возможностью использовать любой простой текстовый редактор позволяют исключить зависимость от лицензионной политики поставщиков проприетарного ПО. |
Помимо уже сказанного, подход «Архитектура как код» предоставляет широкие возможности по развитию автоматизации в будущем: проверка синтаксиса кода и ревью, автоматизированные тесты архитектуры, разрешение имен в легенде напрямую из DNS или интеграции с системой управления адресного пространства и CMDB, добавление библиотек с иконками, чтобы улучшить читабельность сложных схем и так далее Также можно попробовать добиться синергетического эффекта, совместив с подходом «Инфраструктура как код»: по аналогии с автоматической генерацией кода для программного обеспечения генерировать манифесты Terraform или Heat из кода схем или наоборот — актуализировать схемы из файлов состояний фактической инфраструктуры, в общем, на что хватит фантазии и времени.
Архитектура как код — это не просто смена инструментов, это смена парадигмы в сторону большей гибкости и контроля. Уверен, что у вас могли возникнуть собственные идеи на этот счет, я буду рад их услышать и обсудить. Всегда на связи!
