Architecture As Code (AaC): от рисунка на салфетке к инструменту анализа
Сегодня поговорим о подходе Architecture as Code и о том, как он может улучшить ваши рабочие процессы.
Содержание
Что такое Architecture as Code (AaC)?
Несмотря на популярность термина, устоявшегося определения для него нет. Чаще всего встречается следующая формулировка:
Подход Architecture as Code направлен на разработку и управление архитектурой программного обеспечения на основе читаемой и версионируемой кодовой базы. Это способствует глубокому пониманию, эффективной разработке и бесперебойному обслуживанию сложных информационных систем.
Если коротко: «Опишите архитектуру кодом и положите в Git».
На практике возникает много вопросов о том, что именно можно считать AaC. Например:
- Если у меня диаграммы в PlantUML — это Architecture as Code?
- Если я генерирую диаграммы по коду — это считается?
Дело в том, что сейчас популярны различные подходы «как код» (Infrastructure as Code, Diagrams as Code, Documentation as Code и т. д.), поэтому важно чётко очертить границы AaC.
Основными задачами, которые мы хотели решить, используя подход AaC, были:
1. Получить согласованную архитектурную модель.
2. Сместить фокус с представления на содержание.
3. Автоматизировать генерацию артефактов.
Причём от автоматизации генерации артефактов зависит выполнение первых двух:
- Для согласованности нужно иметь один источник истины и процесс, который позволяет сформировать необходимые представления из этого источника,
- Использование DSL позволяет вынести вопрос размещения элементов на диаграмме за скобки, переложив его на инструменты.
Дополнительными задачами могут стать:
- Версионировать и совместно владеть архитектурой,
- Выполнять запросы к архитектурной модели, то есть автоматизировать задачи извлечения информации из архитектурных артефактов,
- Автоматизировать процессы проверки корректности реализации относительно архитектуры.
В контексте этих задач становится видна разница между подходами Architecture as Code и Diagram as Code. Diagram as Code работает в первую очередь с визуальным представлением архитектуры. Таких представлений в одном проекте может существовать множество и данный подход не ставит целью обеспечить их согласованность. В свою очередь Architecture as Code фокусируется именно на описании самой архитектуры – архитектурной модели. При этом представления рассматриваются как вспомогательные артефакты, формируемые автоматически на основе данной модели, что позволяет обеспечить их согласованность.
Таким образом, главной особенностью данного подхода, отличающим его от других подходов as Code, является наличие архитектурной модели. И именно это свойство обеспечивает реализацию большинства сценариев, описанных в данной статье.
Выбор инструментов
Теперь, когда мы разобрались, для чего нужен и чем полезен Architecture as Code, давайте посмотрим, какие инструменты помогают реализовать этот подход.
Чаще всего в контексте AaC упоминаются PlantUML, Structurizr, LikeC4, Archi, ArchUnitNET. Однако не все из них одинаково полезны для описания архитектуры. Например, ArchUnitNET скорее решает задачу контроля реализации, чем проектирования.
На что же стоит обратить внимание при выборе инструмента?
- Открытый код позволяет свободно использовать инструменты, читать и изменять исходный код.
- Компоненты архитектуры можно переиспользовать в разных представлениях. Это необходимо для обеспечения согласованной архитектурной модели, чтобы все артефакты проекта оперировали одним и тем же набором компонентов, чтобы все взаимодействия компонентов описывались одним и тем же образом и не противоречили друг другу.
- Фильтрация компонентов диаграмм даёт возможность автоматического построения представлений для отдельных сценариев или частей решения.
- Описание метаданных для компонентов архитектурных модели позволяет расширить список сценариев, в которых она может использоваться, повысить её информативность.
- Предпочтительно, чтобы инструмент был ориентирован на редактирование модели из кода, а не через визуальный редактор. IDE и даже текстовые редакторы предоставляют множество функций, которые упрощают работу с архитектурной моделью по сравнению с визуальными редакторами (поиск, подстановка, разрешение конфликтов и т.д.).
- Навигация между диаграммами полезна на этапе погружения в проект. Она позволяет быстро переключаться между разными представлениями, а значит, будет проще погружаться в проект и искать необходимую информацию.
- Наличие API для работы с моделью упрощает реализацию собственных инструментов для работы с ней.
- Общее качество инструментов заметно сказывается на эффективности работы. Наличие встроенных средств предпросмотра, форматирования и валидации будет существенным плюсом.
- Также полезной будет возможность вручную скорректировать расположение элементов на диаграмме, потому что автоматический layout не всесилен.
- Не стоит недооценивать возможность интеграции инструмента с продуктом, в котором вы ведете базу знаний проекта. Ситуация может варьироваться от простой вставки изображений до наличия специализированных плагинов.
Возможно, ваши критерии будут отличаться с учетом особенностей проекта. Однако, список выше можно использовать как отправную точку. Мы остановили выбор на LikeC4 и последующие примеры используют этот инструмент.
Architecture as Code на практике
Рассмотрим, как AaC можно применить в реальном проекте.
Контекст
В качестве примера возьмём онлайн-магазин, вдохновлённый eShop reference app от Microsoft. Доступ к системе возможен из мобильного приложения и через веб-интерфейс.
В онлайн-магазине существует несколько ролей. Первая из них — покупатель, который может найти интересующие его товары, добавить их в корзину, а затем оформить заказ с возможностью оплаты онлайн. Вторая — администратор, который управляет настройками интеграции с внешними системами, которыми в свою очередь являются:
- Платёжный шлюз,
- Email-сервер и SMS-шлюз для отправки оповещений
- Система складского учёта и логистики, которая отвечает за учёт позиций на складе, организацию доставки, а также предоставляет информацию об имеющихся товарных позициях.
Но как это представить в виде архитектуры? Давайте разберёмся.
Декомпозируем систему на контейнеры
Систему можно декомпозировать на три прикладных сервиса:
- Каталога товаров,
- Корзины,
- Заказов.
А также ряд инфраструктурных сервисов.
Однако просто перечислить компоненты недостаточно — важно описать их взаимодействия.
Описываем компоненты и взаимодействия
Первое, что нам необходимо описать — это компоненты системы и взаимодействия между ними. Как видите, всё вполне прозрачно.
Настраиваем представления
Чтобы диаграмма со всеми связями не была перегруженной, мы можем протегировать взаимодействия в соответствии со сценариями, в которых они участвуют.
Затем эти теги можно использовать для формирования view сценариев и/или отдельных компонентов. Первое представление отобразит все компоненты, являющиеся инициатором или целью взаимодействия с соответствующим тегом. Второе представление отобразит компонент сервиса заказов, его зависимости, а также компоненты, зависящие от этого сервиса.
Такое описание мы можем положить рядом с кодом и автоматизировать построение представлений. А как еще можно использовать наше описание?
Построение сводных таблиц
Допустим нам нужно описание API с информацией о нагрузке.
Можно дополнить нашу модель метаданными об используемой технологии, частоте запросов и используемых топиках или методах REST.
Сделать выгрузку суммарных требований по нагрузке к отдельным методам REST API.
В зависимости от потребностей вашего проекта столбцов может быть больше.
Проверяем полноту
Здесь хотим поделиться одним из наших страхов: а что если в выборку попали не все взаимодействия, например, потому что для них не добавлены метаданные? Бывают ситуации, когда нужно срочно внести крупные изменения, либо когда на момент формирования описания нет необходимых данных. Найти потом такие взаимодействия довольно трудно, потому что нужно просматривать все артефакты в поисках того, чего там нет. Можем ли мы автоматизировать такие проверки?
Во многих случаях — можем. Достаточно выполнить запросы к модели, чтобы проверить наличие или формат необходимых данных. Тут мы убеждаемся, что для всех взаимодействий заданы используемые протоколы.
Список имеющихся проблем можно встроить в конвейер сборки. Чтобы получить список, нужно запустить скрипт.
Моделирование угроз
Для разработки средств защиты информации, необходимо понимать, что и от кого мы должны защищать.
Это позволяет правильно идентифицировать угрозы и реализовать необходимые меры защиты в рамках практики «моделирование угроз» («Моделирование угроз (описание объекта защиты)»).
Входными данными здесь являются:
- Границы доверия, то есть те границы, при пересечении которых изменяются уровни полномочий.
- Интеракторы, пользователи и внешние системы, взаимодействующие с анализируемой системой.
- Потоки данных между компонентами системы, между системой и интеракторами.
- Механизмы защиты, применяемые к потокам данных.
Количество взаимодействий может превышать сотню. Такая активность должна проводится при каждом релизе. Ручной сбор этой информации трудоёмок, но AaC позволяет автоматизировать процесс. Архитектурная модель предоставляет исходные данные, а скрипты преобразуют их в нужный формат.
Оформляем модель угроз в виде страницы в Confluence в соответствии с шаблоном. Для получения списка интеракторов достаточно получить из архитектурной модели список элементов с типами Person и External System. Далее на основе него формируется CSV-файл, который загружается как вложение к Confluence-странице.
Границы доверия могут быть заданы через диаграммы развертывания, т.к. они зачастую совпадают с физическими границами устройств, сетей и т.д. Они также экспортируются в CSV и затем загружаются в Confluence.
На нашем шаблоне потоки данных представлены в двух вариантах: в виде диаграмм, а также в виде таблицы. Важно, что модель у нас описана в терминах взаимодействий, а не потоков данных.
Потоки данных
В нашем случае удалось описать информацию о потоках данных при помощи метаданных взаимодействий. В частности, для взаимодействия мы указываем идентификатор потока, типы передаваемых данных и направление движения данных, относительно направления взаимодействия. Тут же описывается механизм защиты, применяемый для потока.
Такое представление имеет ряд ограничений и не позволяет отразить все нюансы, однако, для модели угроз этого вполне достаточно.
В результате мы получаем вот такие диаграммы уже в терминах потоков данных.
Страницу в Confluence используют архитектор проекта и специалисты по безопасной разработке для выявления угроз и выбора компенсирующих их мер.
В результате мы получаем такой документ.
Заключение
Architecture as Code — это мощный инструмент, который помогает не только описывать, но и анализировать архитектуру, делая её прозрачной и управляемой. Architecture as Code сокращает объём рутинной работы, повышает согласованность артефактов и даёт возможность автоматизировать проверки.
Начните с малого — формализуйте ключевые компоненты и их взаимодействия, а затем расширяйте модель под свои задачи. Чем раньше вы попробуете, тем быстрее ощутите преимущества этого подхода.
P.S. Чтобы всегда первыми видеть наши новые материалы, подписывайтесь на канал.