Всем привет! Меня зовут Сидоров Антон, я руководитель отдела технической архитектуры в департаменте сопровождения информационных технологий ПСБ. Моя команда занимается архитектурой инфраструктурных систем, и сегодня я хочу рассказать вам про наш первый опыт использования подхода «Архитектура как код»

«Архитектура как код» (англ. Architecture as Code, AaC) — это уже не новый, но пока не получивший широкого распространения в силу недостатка зрелых и популярных инструментов подход к описанию информационных систем посредством создания и обновления различных диаграмм и схем с использованием текстового описания.

Что имеется в виду под архитектурой?

Само понятие «архитектура» имеет много определений. Но в общих словах всё сводится к структуре чего‑либо, выраженной через описание элементов и их взаимосвязи с внешним миром.

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

Источник фото

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

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

Чтобы этого избежать в индустрии появились такие тяжеловесные стандарты как ArchiMate, SysML и подобные, но на практике большинство организаций уже отказались от них в пользу гораздо более простых схем с прямоугольниками и стрелками.

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

Что не так с традиционным подходом к описанию архитектуры?

Рисунок 1. Пример схемы сетевого взаимодействия в формате Microsoft Visio
Рисунок 1. Пример схемы сетевого взаимодействия в формате Microsoft Visio

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

Что с ней не так?

  • Мы видим сверху номер версии, но не знаем были ли кем‑то созданы более свежие;

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

  • Мы не можем выгрузить все представленные на схеме соединения в виде легенды, чтобы дальше с ней могли работать коллеги из Блока информационной безопасности;

  • Рисунок статичен, и мы не можем «провалиться», например, в систему прокси, чтобы узнать с чем ещё она взаимодействует или как реализована балансировка, а добавление сведений на эту схему усложнит её восприятие;

  • Адреса некоторых серверов или их состав к моменту, когда мы рассматриваем эту схему могут быть уже неактуальны.

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

Виды инструментов

Источник изображения

Как и у других подобных подходов с использованием текстового описания, например, как у «Инфраструктуры как код» или «Документации как код», предпосылками к появлению стало желание применить довольно развитые к настоящему времени процессы из разработки программного обеспечения на другие области с целью автоматизировать и упростить трудозатратные и неоптимальные операции.

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

Отрисовка (Диаграмма как код)

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

Код на примере 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.

Какие существуют инструменты?

Я проанализировал существующие инструменты и узнал, что специалисты из разных областей уже давно пытаются создать идеальный для их сценариев использования вариант. Этим обусловлен сильный уклон инструментов в узкие области применения (корпоративная архитектура, локальные вычислительные сети и так далее).

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

Название

Лицензия

Язык описания

Язык движка

Группа

Комментарий

PlantUML

GPL-3.0

DSL

Java

Отрисовка

Не самый современный, но безопасный выбор, огромное сообщество.

graphviz

Eclipse Public License 1.0

DSL (dot)

C

Отрисовка

Чаще всего используется только как движок для более высокоуровневых и удобных в использовании средств (например, PlantUML).

Diagrams

MIT

Python / Go

Python

Отрисовка

На базе graphviz, субъективно самый простой в использовании в случае Python, есть форк, написанный на Golang.
 На выходе файлы в форматах: png, jpg, svg, pdf. Требуется запуск как программы для каждого изменения, может быть запущен из блокнота Jupyter. Минусы: представление смешано со структурой.

drawthe.net

MIT

YAML

JavaScript

Отрисовка

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

Mermaid

MIT

DSL (Markdown‑подобный)

JavaScript

Отрисовка

Присутствуют диаграммы классов, процессов, но нет схем сетевого взаимодействия наподобие используемых в Банке и создаваемых в Microsoft Visio.

ditaa

GPL 2.0

DSL (ascii)

Java

Отрисовка

Редактирование в виде ASCII. Не совсем код, больше псевдографика, вносить изменения так же неудобно, как и в Visio.

asciidoctor Diagram

MIT

DSL (ascii)

Ruby

Отрисовка

Расширения для asciidoctor (который в свою очередь на базе ditaa). 

Structurizr

проприетарная

DSL

Java

Моделирование

Может интегрироваться с PlantUML, graphviz, Mermaid, ilograph, есть макросы для Confluence. В бесплатной версии ограничение на одно рабочее место и урезан функционал (отсутствуют интеграция по LDAP, внешнее хранилище). Лицензии постоянные, но обновления только по подписке $10/рабочее место в месяц.

Like C4

MIT

DSL

TypeScript

Моделирование

Вдохновлен моделью C4 и Structurizr, стремительно набирает популярность в последнее время

Ilograph

проприетарная

YAML

TypeScript

Моделирование

Ilograph LLC, США (санкции для РФ), бесплатно для личного использования, для организаций цена по запросу.

Diagram.Codes

проприетарная

Markdown

JavaScript

Отрисовка

Volare Labs, Колумбия, поддержка $1000/год на неограниченное кол‑во пользователей. Не рассматриваем для использования, но хороший пример инструментов такого класса.

draw.io

Apache-2.0 license

-

JavaScript

Отрисовка

Упор на графический редактор. Может сохранять в XML и SVG, но создавать с нуля или редактировать их вручную не представляется возможным (большое число атрибутов с метаданными графического представления).

IcePanel

проприетарная

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)"

Скрипт для генерации легенды к схеме также размещен в репозитории и изменения в котором отслеживаются системой контроля версий. Логика его работы такова:

  1. Найти все соединения (которые обычно обозначаются как стрелки вида «‑→»);

  2. С учетом всех директив include, используемых в коде схемы разрешить все нужные переменные;

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

  4. При помощи библиотеки 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 из кода схем или наоборот — актуализировать схемы из файлов состояний фактической инфраструктуры, в общем, на что хватит фантазии и времени.

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