Архитектура как код: инструменты

опубликовано: ⏰ 14

Для реализации подхода Architecture as Code необходимы удобные инструменты, которые позволяют описывать архитектуру в текстовом виде или в виде кода, а затем, с помощью CI/CD процессов, обновлять и автоматически генерировать документацию на основе этих описаний. В этой статье я хотел привести пример некоторых из таких инструментов.

Введение

Во вводной статье уже было рассказано о том, что такое Architecture as Code и зачем он нужен. Здесь будут более подробно рассмотрены применяемые инструменты.

Естественно, в статье будут рассматриваться в основном инструменты, которые я сам использовал или хотя бы пробовал. Всё это не является полным списком, но может быть полезно для тех, кто хочет начать использовать подход AaC.

Общие требования

Требования к инструментам в основном формируются из того на что нацелен сам подход AaC:

  • Формат описания архитектурных артефактов должен быть преимущественно текстовым с возможностью редактирования в любом удобном редакторе.
  • Архитектурные модели могут быть описаны в виде кода, который можно вносить в систему контроля версий (git).
  • На основе этого описания должна быть возможность автоматической генерации диаграмм и других графических представлений.
  • Возможность встраивания в процессы CI/CD, например, для автоматического обновления документации при их изменении.
  • Должна быть возможность организации библиотек компонентов для повторного использования, чтобы минимизировать дублирование и повторение однотипной работы.
  • Формат описания должен быть понятен для GenAI (например, LLM), чтобы в дальнейшем их можно было использовать для анализа или генерации документации. А также как базу знаний для обучения и внедрения GenAI в процесс проектирования и разработки.

Очень желательно, чтобы инструменты были бесплатными и открытыми (Open Source), но это не является обязательным требованием. Если код открыт, то это позволяет дорабатывать их под свои нужды, так как внутренние требования к документации и процессы в компаниях могут отличаться, а как известно – универсального решения подходящего всем не существует.

Какие инструменты использовать?

Ниже несколько инструментов, которые можно использовать. Конечно же есть ещё варианты с созданием внутренних решений, но они не рассматриваются здесь.

ИнструментГлавный функционалЛучше всего подходит для…Менее подходит для…СложностьCI/CDOSS
StructurizrC4-модель, автоматизация из кодаКомплексных систем, команд, использующих C4, “живой” документацииПростых схем, команд не использующих C4СредняяОтличнаяЧастично (CLI/Lite)
MermaidПростота, универсальность, массовая поддержкаБыстрой интеграции в Markdown, небольших/средних проектовДетализированных или нестандартных архитектурных диаграммНизкаяОтличнаяДа
PlantUMLУдобство и разнообразие типов диаграммДетализированных и смешанных диаграмм, сложных взаимодействийПростых схем, где нужна автоматическая компоновкаСредняя/ВысокаяОтличнаяДа
GraphvizАвтоматическая компоновка сложных графовГенерации зависимостей, визуализации больших связей через скриптыРучного описания всей архитектуры, простых схемНизкая/СредняяХорошая (через скрипты)Да

Structurizr

Structurizr – комплексное решение для документирования архитектуры, основанная на C4-модели. Позволяет описывать архитектуру в коде (JSON/YAML) и генерировать интерактивные диаграммы разных уровней (контекст, контейнер, компонент, код) в виде веб-портала.

Основные преимущества:

  • Построен на использовании нотации C4, которая является одной из самых простых и популярных для описания архитектуры.
  • Поддержка автоматической интеграции с кодом для генерации описания.
  • Два варианта развёртывания – Structurizr Lite (для локальной разработки) и Structurizr On-Premises (для совместной работы).
  • Возможность экспортировать диаграммы в различные форматы: PNG, SVG. Полезно, если необходимо передать схемы в другие системы.
  • Возможность встраивания в CI/CD используя Structurizr CLI.
  • Открытый исходный код (можно дорабатывать и писать плагины).
  • Есть интеграции с системами ведения документации, например Confluence.

Дополнительно имеет возможность организации внутренней документации по архитектуре, например в виде Markdown или AsciiDoc, с возможностью вставки ссылок на схемы. Плюс в отдельный раздел вынесены ADR.

Возможные недостатки:

  • Есть необходимость обучения работе с DSL.
  • Сложность интеграции с существующими системами документирования.
  • Производительность при больших моделях и большом количестве диаграмм может снизиться. Особенно при использовании веб-интерфейса и росте документации.

Сценарии использования:

  • Разработка архитектурных моделей с использованием C4-модели.
  • Автоматическая генерация диаграмм и документации из кода или DSL.
  • Интеграция с CI/CD для автоматического обновления архитектурной документации.
  • Совместная работа над архитектурой и документацией в рамках команды разработчиков.
  • Публикация архитектурной документации в виде статического сайта.

Примеры

System Architecture (High-Level Overview)
Shell
workspace "Online Shop Architecture" {
    model {
        user = person "Customer"

        onlineShop = softwareSystem "Online Shop" "Allows customers to browse and buy products" {

            webApp = container "Web Application" "Allows customers to browse and buy via browser" {
                technology "React"
            }

            mobileApp = container "Mobile App" "Allows customers to browse and buy via phone" {
                technology "iOS/Android"
            }

            api = container "Backend API" "Handles business logic and requests" {
                technology "Java/Spring Boot"
            }

            db = container "Database" "Stores customer, order, and product data" {
                technology "PostgreSQL"
            }

            cache = container "Cache" "Improves API response times" {
                technology "Redis"
            }

            paymentGateway = container "Payment Gateway"  "External payment processing" {
                technology "Stripe/PayPal API"
                tag external
            }
        }

        user -> webApp "Uses"
        user -> mobileApp "Uses"
        webApp -> api "Makes API calls [HTTPS]"
        mobileApp -> api "Makes API calls [HTTPS]"
        api -> db "Reads/Writes [JDBC]"
        api -> cache "Caches results"
        api -> paymentGateway "Processes Transactions"
    }

    views {

        styles {
            element "external" {
                background gray
                color #ffffff
            }
            element "Web Browser" {
                shape WebBrowser
            }
            element "database" {
                shape Cylinder
            }
            element Component {
                shape Component
            }
        }
        theme default
    }
}

PlantUML

PlantUML – это инструмент для создания диаграмм с использованием структурированного текстового описания. Это позволяет создавать диаграммы из текстового описания, что соответствует концепции AaC. Так же, есть множество плагинов, которые позволяют интегрировать PlantUML в различные IDE и генерировать диаграммы автоматически из исходного кода. Поддерживает различные типы диаграмм, включая: UML, C4, Archimate, BPMN, Deployment, Network, WBS, MindMap, Gantt, Chronology и так далее.

Основные преимущества:

  • Большая библиотека поддерживаемых типов диаграмм: архитектурные, классов, последовательности, состояний, BPMN и т.д.
  • Позволяет создавать довольно сложные и детализированные диаграммы. Ограничения есть, но не критичные
  • Есть возможность настройки стилей, тем представлений, цветов, шрифтов, стилей связей, представлений для блоков диаграмм и так далее.
  • Очень распространённый формат описания диаграмм и поддерживается во всех популярных редакторах и IDE
  • Легко встраивается в CI/CD процессы.
  • Поддерживается в большинстве генераторов документации (AsciiDoc, Markdown через расширения, Confluence).
  • Открытый исходный код.

Возможные недостатки:

  • Необходимо изучить язык описания диаграмм (DSL) и его синтаксис.
  • Некоторые сложные диаграммы могут быть неудобны для редактирования вручную, особенно если они содержат много элементов. Например, не всегда легко выстроить правильные связи между элементами, чтобы они корректно отображались на финальной диаграмме.

Сценарии использования:

  • Описание различных типов архитектурных диаграмм и не только, которые в дальнейшем будут использоваться в документации проекта.
  • Создание автоматически генерируемых из кода схем (например, через аннотации или метаданные) в виде диаграмм. Освобождает от ручного описания диаграмм и их поддержки.
  • Использование в CI/CD для автоматической генерации диаграмм при каждом изменении кода.

Примеры

System Architecture (High-Level Overview)
Shell
@startuml
!theme vibrant
!define RECTANGLE class

' Define Styling
skinparam componentStyle rectangle
skinparam backgroundColor #FEFEFE

actor "User" as User

package "Client Layer" {
    component "Web Application" as Web
    component "Mobile App" as Mobile
}

package "Infrastructure" {
    component "Load Balancer" as LB
    component "Backend API" as API
}

component "Auth Service" as Auth
database "Primary DB" as DB
database "Redis Cache" as Cache
cloud "Payment Gateway" as Payments
cloud "Shipping Provider" as Ship

' Connections
User --> Web : HTTPS
User --> Mobile : HTTPS

Web --> LB
Mobile --> LB

LB --> API

API --> Auth
API --> Cache
API --> DB

API --> Payments : REST API
API --> Ship : API

@enduml

Checkout Process (Sequence Diagram)
Shell
@startuml
!theme vibrant

autonumber

actor "Customer" as C
participant "Website/App" as UI
participant "Server" as S
database "Database" as DB
participant "Payment Gateway" as P

C -> UI: View Cart & Checkout
UI -> S: POST /api/create-order
S -> DB: Verify Inventory & Reserve Items
DB --> S: Items Reserved
S --> UI: Order ID & Payment Token

UI -> C: Request Credit Card Details
C -> UI: Submit Payment Details

UI -> P: Charge Card (with Token)
P --> UI: Payment Success/Fail

alt Payment Successful
    UI -> S: POST /api/confirm-payment
    S -> DB: Update Order Status to "Paid"
    S --> UI: Confirmation Receipt
    UI --> C: Display "Thank You" Page
else Payment Failed
    S -> DB: Release Reserved Inventory
    UI --> C: Display Error Message
end

@enduml

Order Lifecycle (State Diagram)
Shell
@startuml
[*] --> Cart

state Cart {
    [*] --> Active
}

state "Payment Failed" as Failed
state "Payment Successful" as Paid

Cart --> Processing: Checkout
note right of Cart
  User fills details
  and clicks "Pay"
end note

Processing --> Failed: Payment Declined
Processing --> Paid: Payment Success

Paid --> Shipped: Order Picked & Packed
note right of Paid
  Warehouse handles
  physical goods
end note

Shipped --> Delivered: Customer Receives

Delivered --> Returned: Refund Requested
Delivered --> [*]: Order Complete

Returned --> Refunded: Item Received
Refunded --> [*]: Process Complete

Failed --> Cart: Try Again
Failed --> [*]: Abandoned

@enduml

Mermaid

Mermaid – это инструмент для генерации диаграмм из текстового описания. Аналог PlanUML, но с более простым синтаксисом и возможностью интеграции с Markdown. Он поддерживает множество типов диаграмм, включая: UML, C4, Flowcharts, Gantt, User Journey, Pie Charts, Timeline, Git Graphs и так далее.

Основные преимущества:

  • Легко интегрируется в Markdown-документы (GitHub, GitLab, Notion и др.), так как поддерживается практически всеми современными редакторами.
  • Встроенная поддержка на GitHub, GitLab, VS Code, Confluence и других платформах.
  • Большая библиотека поддерживаемых типов диаграмм.
  • Постоянно добавляются новые типы диаграмм и улучшения, включая поддержку архитектурных описаний (C4).
  • Может рисовать диаграммы прямо в браузере, так как это JS-библиотека.
  • Открытый исходный код.

Возможные недостатки (использовал редко, поэтому могу что-то упустить):

  • Нередко возникают проблемы с отображением диаграмм в некоторых редакторах или на определённых платформах – необходимо подбирать правильное описание диаграммы.
  • По ощущениям, хуже поддержка в IDE, чем для PlantUML.

Сценарии использования:

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

Примеры

System Architecture (High-Level Overview)
Shell
graph TD
    %% Nodes
    User((User))
    Web[Web Application]
    Mobile[Mobile App]
    LB[Load Balancer]
    API[Backend API Server]
    Auth[Auth Service]
    DB[(Primary Database)]
    Cache[(Redis Cache)]
    Payments[Payment Gateway]
    Ship[Shipping Provider]

    %% Relationships
    User -->|HTTPS| Web
    User -->|HTTPS| Mobile
    
    Web --> LB
    Mobile --> LB
    
    LB --> API
    
    API --> Auth
    API --> Cache
    API --> DB
    
    API -->|REST API| Payments
    API -->|API| Ship

    %% Styling
    style User fill:#f9f,stroke:#333,stroke-width:2px
    style DB fill:#ff9,stroke:#333,stroke-width:2px

Checkout Process (Sequence Diagram)
Shell
sequenceDiagram
    autonumber
    actor C as Customer
    participant UI as Website/App
    participant S as Server
    participant DB as Database
    participant P as Payment Gateway

    C->>UI: View Cart & Checkout
    UI->>S: POST /api/create-order
    S->>DB: Verify Inventory & Reserve Items
    DB-->>S: Items Reserved
    S-->>UI: Order ID & Payment Token
    
    UI->>C: Request Credit Card Details
    C->>UI: Submit Payment Details
    
    UI->>P: Charge Card (with Token)
    P-->>UI: Payment Success/Fail
    
    alt Payment Successful
        UI->>S: POST /api/confirm-payment
        S->>DB: Update Order Status to "Paid"
        S-->>UI: Confirmation Receipt
        UI-->>C: Display "Thank You" Page
    else Payment Failed
        S->>DB: Release Reserved Inventory
        UI-->>C: Display Error Message
    end

Order Lifecycle (State Diagram)
Shell
stateDiagram-v2
    [*] --> Cart

    Cart --> Processing: Checkout
    note right of Cart
        User fills details
        and clicks "Pay"
    end note

    Processing --> PaymentFailed: Payment Declined
    Processing --> Paid: Payment Success
    
    Paid --> Shipped: Order Picked & Packed
    note right of Paid
        Warehouse handles
        physical goods
    end note

    Shipped --> Delivered: Customer Receives
    
    Delivered --> Returned: Refund Requested
    Delivered --> [*]: Order Complete

    PaymentFailed --> Cart: Try Again
    PaymentFailed --> [*]: Abandoned
    
    Returned --> Refunded: Item Received
    Refunded --> [*]: Process Complete

Graphviz

Graphviz – это мощный инструмент визуализации графов, который использует язык описания графов DOT для создания диаграмм. Может быть полезен для визуализации сложных архитектурных схем и взаимосвязей между компонентами. Сам не использовал, но нужно упомянуть

Основные преимущества:

  • Алгоритмы Graphviz отлично справляются с компоновкой сложных графов без ручной расстановки.
  • Минималистичный DOT-синтаксис.
  • Может быть использован как самостоятельно, так и для других инструментов. Например, PlantUML использует его для генерации некоторых типов диаграмм.
  • Эффективно обрабатывает большие графы.
  • Полный контроль над внешним видом диаграммы и компоновкой.

Возможные недостатки:

  • Требуется знание синтаксиса DOT.
  • Не поддерживает визуальное редактирование.
  • Нет готовых шаблонов и блоков для разных типов диаграмм.

Сценарии использования:

  • Создание собственных инструментов визуализации.
  • Работа со сложными схемами, которые не поддерживаются другими инструментами.

Примеры

System Architecture (High-Level Overview)
Shell
digraph OnlineShopArch {
    // Graph Settings
    rankdir=TB; // Top to Bottom layout
    newrank=true;
    splines=ortho; // Straight lines
    node [shape=box, style="filled,rounded", fontname="Arial", fontsize=10];

    // External Nodes
    User [label="Customer", shape=oval, fill="#f9f"];

    // Cluster for Server Side
    subgraph cluster_backend {
        label = "Infrastructure";
        style=filled;
        color=lightgrey;

        Web [label="Web App", fill="#dodgerblue3"];
        Mobile [label="Mobile App", fill="#dodgerblue3"];
        LB [label="Load Balancer", fill="#gold"];
        API [label="Backend API", fill="#limegreen"];
        DB [label="Database", shape=cylinder, fill="#ff9"];
        Cache [label="Redis Cache", fill="#ff9"];
    }

    // External Services
    Payments [label="Payment Gateway", shape=cloud, fill="#e0e0e0"];
    Ship [label="Shipping Provider", shape=cloud, fill="#e0e0e0"];

    // Connections
    User -> Web [label="HTTPS"];
    User -> Mobile [label="HTTPS"];

    Web -> LB;
    Mobile -> LB;
    LB -> API;

    API -> Cache [label="Read/Write"];
    API -> DB [label="SQL"];

    API -> Payments [label="REST API"];
    API -> Ship [label="API"];
}

Checkout Process (Flow Diagram)
Shell
digraph CheckoutFlow {
    rankdir=TB;
    node [shape=rectangle, style="filled,rounded", fontname="Arial"];

    // Start
    Start [shape=oval, label="Customer Checkout", fill="#f9f"];

    // Process Steps
    UI [label="Web/App Interface"];
    CreateOrder [label="API: Create Order\n& Verify Inventory"];

    // Decision Diamond
    PayCheck [shape=diamond, label="Payment Success?"];

    // Success Path
    Confirm [label="API: Update Status\nto 'Paid'"];
    Receipt [label="Show Thank You"];

    // Failure Path
    Release [label="API: Release\nInventory"];
    Error [label="Show Error Message"];

    // Logic Flow
    Start -> UI;
    UI -> CreateOrder;
    CreateOrder -> PayCheck;

    PayCheck -> Confirm [label="Yes"];
    Confirm -> Receipt;

    PayCheck -> Release [label="No"];
    Release -> Error;

    // Styling
    Start [fill="#f9f"];
    UI [fill="#dodgerblue3"];
    CreateOrder [fill="#limegreen"];
    PayCheck [fill="orange"];
    Confirm [fill="#limegreen"];
}

Order Lifecycle (State Diagram)
Shell
digraph OrderLifecycle {
    rankdir=TB; // Top to Bottom
    
    // Node Styles
    node [shape=ellipse, style="filled", fontname="Arial"];
    Start [shape=point, label=""];
    
    // States
    Cart [fill="#add8e6", label="Cart"];
    Processing [fill="#add8e6", label="Processing"];
    Paid [fill="#add8e6", label="Paid"];
    Shipped [fill="#add8e6", label="Shipped"];
    Delivered [fill="#add8e6", label="Delivered"];
    Returned [fill="#ffcccb", label="Returned"];
    Refunded [fill="#ffcccb", label="Refunded"];
    Abandoned [shape=doublecircle, fill="#d3d3d3", label="Abandoned"];
    Complete [shape=doublecircle, fill="#90ee90", label="Complete"];

    // Transitions
    Start -> Cart;
    Cart -> Processing [label="Checkout"];
    
    Processing -> Paid [label="Success"];
    Processing -> Abandoned [label="Fail/Quit"];
    
    Paid -> Shipped [label="Pack & Ship"];
    Shipped -> Delivered [label="Receive"];
    
    Delivered -> Complete [label="Done"];
    Delivered -> Returned [label="Refund Req"];
    
    Returned -> Refunded [label="Item Received"];
    Refunded -> Complete [label="Done"];
    
    // Layout Optimization (Keep certain levels aligned)
    ranksep=1.0;
}

DocHub

DocHub – это инструмент для создания и управления документацией в формате Markdown. Он позволяет создавать документацию с помощью Markdown и автоматически генерирует статическую веб-страницу из Markdown-файлов. Он также поддерживает визуализацию диаграмм с помощью Mermaid и PlantUML.

Сам DocHub не использовал, но знаю что такой есть. По функционалу ближе к Structurizr. К тому же есть встроенный техрадар, что очень удобно.

Заключение

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

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

Дополнительный плюс в том, что при таком подходе часть документации может быть использована с GenAI-инструментами. Как минимум для анализа архитектурных решений на предмет выявления потенциальных проблем и уязвимостей.

Architecture-as-Code Structurizr Plantuml Mermaid Diagrams Graphviz