* feat: add c4-diagramming skill Signed-off-by: Magnus Hedemark <magnus919@pm.me> * fix: remove host-specific port assumptions Signed-off-by: Magnus Hedemark <magnus919@pm.me> --------- Signed-off-by: Magnus Hedemark <magnus919@pm.me>
12 KiB
Architecture as Code (AaC) Ecosystem
Tools, conventions, and patterns for managing C4 model diagrams, arc42 documentation, and Architecture Decision Records (ADRs) together in a git repository.
1. Structurizr — C4 Reference Implementation
Structurizr is the official "models as code" tool for the C4 model, created by Simon Brown (the C4 model's author). You write a text-based DSL that defines your entire software architecture model; all diagrams are generated from that single model.
Key website: https://structurizr.com/ — Docs: https://docs.structurizr.com/
Core Concepts
- Workspace — the top-level container. Holds a model + views + documentation + decisions.
- Model — defines elements (persons, software systems, containers, components) and their relationships.
- Views — selects subsets of the model for diagram rendering (system context, container, component, dynamic, deployment).
- DSL — text-based domain-specific language. Single source of truth. Git-friendly.
Minimal Example (All Four C4 Levels)
workspace {
model {
user = person "Customer"
system = softwareSystem "Internet Banking System" {
webapp = container "Web Application" "TypeScript, React" {
user -> this "Uses"
}
api = container "API" "Go" {
webapp -> this "Makes API calls"
}
db = container "Database" "PostgreSQL" {
api -> this "Reads/writes"
}
}
}
views {
systemContext system {
include *
autolayout lr
}
container system {
include *
autolayout lr
}
component api {
include *
autolayout lr
}
theme default
}
}
The !adrs Keyword — Native ADR Integration
Structurizr can import Architecture Decision Records directly into the workspace:
workspace {
!adrs docs/adr
model { ... }
views { ... }
}
This imports all Markdown files from docs/adr/ using the adr-tools format by default. Supported formats:
adrtools(default) — expects files matching adr-tools naming conventionmadr— for MADR-format ADRslog4brains— for log4brains-format ADRs
The ADRs are rendered in the Structurizr UI alongside the C4 diagrams. This is the tightest integration available between C4 and ADRs.
The !docs Keyword — arc42 Documentation Import
workspace {
!docs docs/arc42
model { ... }
views { ... }
}
Imports Markdown or AsciiDoc documentation (structured as arc42 sections) and renders them in the UI alongside diagrams and ADRs. Supports section-based navigation.
Structurizr Lite — Local Preview
Docker container for rendering the full workspace in a browser:
# docker-compose.yml
services:
structurizr-lite:
image: structurizr/lite
ports:
- "8081:8080"
volumes:
- ./docs/arch:/usr/local/structurizr
Access at http://localhost:8081. Shows C4 diagrams, arc42 documentation, and ADRs in a unified web UI with navigation.
CI/CD Commands
# Validate DSL syntax and model consistency
structurizr-cli validate -w docs/arch/model/system.dsl
# Inspect for architectural drift
structurizr-cli inspect -w docs/arch/model/system.dsl
# Export diagrams to PlantUML
structurizr-cli export -w docs/arch/model/system.dsl -format plantuml
# Export diagrams to Mermaid
structurizr-cli export -w docs/arch/model/system.dsl -format mermaid
# Export to static HTML site
structurizr-cli export -w docs/arch/model/system.dsl -format site
DSL Cookbook
Full tutorial guide: https://docs.structurizr.com/dsl/cookbook/
Topics covered: workspace structure, model elements, relationships, views, styling, themes, animations, deployment nodes, dynamic diagrams, filtering, properties, perspectives.
2. C4-PlantUML — Lighter Alternative
Repo: https://github.com/plantuml-stdlib/C4-PlantUML
PlantUML include files that add C4 semantics to standard PlantUML. No single-model consistency (each diagram is a separate file), but much lower learning curve than Structurizr.
Function Reference
| Function | C4 Level | Purpose |
|---|---|---|
Person(alias, label, description) |
Any | External user or actor |
Person_Ext(alias, label, description) |
Context | External user (outside system boundary) |
System(alias, label, description) |
Context | Software system |
System_Ext(alias, label, description) |
Context | External software system |
Container(alias, label, tech, description) |
Container | Application container (web app, API, DB) |
Container_Boundary(alias, label) |
Container | Groups related containers |
Component(alias, label, tech, description) |
Component | Module within a container |
System_Boundary(alias, label) |
Context | Groups related systems |
Rel(from, to, label, tech) |
Any | Relationship between elements |
Rel_D(from, to, label, tech) |
Any | Relationship (dashed) |
Rel_Neighbor(from, to, label, tech) |
Any | Relationship rendering optimization |
UpdateLayoutConfig(c4ShapeInRow, c4BoundaryInRow) |
Any | Layout tuning |
LAYOUT_WITH_LEGEND() |
Any | Renders with automatic legend |
Example
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Context.puml
Person(customer, "Customer")
System(system, "Your System", "Core platform")
System_Ext(external, "External Service", "Payment processor")
Rel(customer, system, "Uses")
Rel(system, external, "Charges via")
@enduml
When to Choose Over Structurizr
| Situation | Choice |
|---|---|
| Team already uses PlantUML for other diagrams | C4-PlantUML (consistent toolchain) |
| Need a quick C4 diagram for an ad-hoc document | C4-PlantUML (no DSL learning curve) |
| Need consistent multi-diagram model across 4 C4 levels | Structurizr (single source of truth) |
| Want ADR integration in the diagram viewer | Structurizr (native !adrs support) |
| CI pipeline already has PlantUML | Either — Structurizr exports to PlantUML |
3. docToolChain — arc42 Build Pipeline
Repo: https://github.com/docToolchain/docToolchain
A Gradle-based docs-as-code toolchain purpose-built for arc42 documentation. Handles the full pipeline: AsciiDoc compilation, PlantUML diagram generation, PDF/HTML export, Confluence publishing.
Key Capabilities
- arc42 template management — generates skeleton arc42 documentation with all 12 sections
- AsciiDoc compilation — converts
.adocsource files to HTML, PDF, DocBook - PlantUML integration — renders C4 diagrams (via C4-PlantUML includes) as part of the build
- Confluence export — publishes rendered docs to Confluence spaces via asciidoc2confluence
- Gradle task hierarchy —
generateHTML,generatePDF,exportConfluenceas standard tasks
Directory Structure Convention
docs/
├── src/
│ ├── arc42/
│ │ ├── 01_introduction_and_goals.adoc
│ │ ├── ...
│ │ └── 12_glossary.adoc
│ └── images/
├── build/ ← Generated output
├── build.gradle ← docToolChain configuration
└── gradle.properties
When to Use
docToolChain is for organizations that want a standardized, build-pipeline-driven approach to arc42 documentation. It adds ceremony (Gradle build, strict directory structure) in exchange for consistent output formats and Confluence integration. For teams that just want C4 diagrams with ADRs, Structurizr is lighter.
4. Converged Repo Convention
The AaC community has converged on a standard directory structure for combining C4, arc42, and ADRs in a single git repository. Multiple reference implementations use the same pattern:
Directory Structure
docs/arch/
├── model/
│ ├── system.dsl ← Structurizr DSL (the architecture model)
│ └── deployment/ ← Deployment-specific views (dev, staging, prod)
│ ├── dev.dsl
│ └── live.dsl
├── src/ ← arc42 12-section template
│ ├── 01_introduction_and_goals.adoc
│ ├── 02_constraints.adoc
│ ├── 03_system_scope_and_context.adoc
│ ├── 04_solution_strategy.adoc
│ ├── 05_building_block_view.adoc
│ ├── 06_runtime_view.adoc
│ ├── 07_deployment_view.adoc
│ ├── 08_crosscutting_concepts.adoc
│ ├── 09_architecture_decisions.adoc
│ ├── 10_quality_requirements.adoc
│ ├── 11_technical_risks.adoc
│ └── 12_glossary.adoc
├── adr/ ← Architecture Decision Records
│ ├── 0001-record-architecture-decisions.md
│ ├── 0002-use-postgresql.md
│ ├── 0003-adopt-event-sourcing.md
│ └── README.md ← ADR index with status table
├── images/ ← Embedded screenshots, diagrams
├── README.md ← Project overview
└── docker-compose.yml ← Structurizr Lite
How the Three Methodologies Relate
| Component | Purpose | Created By | Consumed By |
|---|---|---|---|
model/system.dsl |
C4 model (all levels) | Technical architect | Structurizr renders 4 diagrams |
src/09_architecture_decisions.adoc |
arc42 decision section | Technical architect | Humans reading arc42 docs |
adr/0002-use-postgresql.md |
Full ADR content | Technical architect | Structurizr imports via !adrs |
docker-compose.yml |
Local preview | Team | docker compose up → browser |
Reference Implementations
- dzimchuk/architecture-as-code — Structurizr DSL + arc42 AsciiDoc + ADRs + Docker Compose. The cleanest minimal example. https://github.com/dzimchuk/architecture-as-code
- milanm/architecture-docs — Same approach but with PlantUML diagram export and GitHub Pages CI. https://github.com/milanm/architecture-docs
- bitsmuggler/arc42-c4-example — arc42 template filled out for an Internet Banking System. https://bitsmuggler.github.io/arc42-c4-software-architecture-documentation-example/
5. Tool Comparison
| Criteria | Structurizr | C4-PlantUML | Mermaid |
|---|---|---|---|
| Model consistency | Single model → all 4 diagrams | Per-file includes | Per-file manual |
| Learning curve | Medium (DSL syntax) | Low (PlantUML) | Low |
| ADR integration | Native (!adrs keyword) |
None | None |
| arc42 integration | Native (!docs keyword) |
None | None |
| CI readiness | CLI + Docker image | PlantUML CLI | mmdc CLI |
| GitHub rendering | No (needs Structurizr viewer) | Via PlantUML GitHub Action | Native (if flowchart syntax) |
| Local preview | Structurizr Lite (Docker) | PlantUML server | VS Code plugins |
| Layout | Auto + manual (drag to arrange) | Auto only | Auto via --- direction |
6. Further Reading
- Structurizr DSL cookbook: https://docs.structurizr.com/dsl/cookbook/
- Structurizr DSL language reference: https://docs.structurizr.com/dsl/language
- Structurizr ADR integration: https://docs.structurizr.com/dsl/adrs
- Structurizr "as code" philosophy: https://docs.structurizr.com/as-code
- C4-PlantUML: https://github.com/plantuml-stdlib/C4-PlantUML
- docToolChain: https://github.com/docToolchain/docToolchain
- dzimchuk AaC example: https://github.com/dzimchuk/architecture-as-code
- milanm AaC example: https://github.com/milanm/architecture-docs
- CI pipeline templates (GitHub Actions, GitLab CI, ForgeJo):
references/ci-pipeline-templates.md