Diagram as Code in ConnectSoft Microservice Template¶
Purpose & Overview¶
Diagram as Code is a practice of defining diagrams programmatically using code or markup languages, enabling version control, automated generation, and consistency across documentation. In the ConnectSoft Microservice Template, diagram-as-code is implemented using two complementary approaches:
- Python Diagrams Library: Programmatic diagram generation using the
diagramsPython library - Mermaid: Text-based diagram markup for embedding in Markdown documentation
Why Diagram as Code?¶
Diagram as Code offers several key benefits:
- Version Control: Diagrams are stored as code, enabling version tracking and change history
- Automation: Diagrams can be generated automatically in CI/CD pipelines
- Consistency: Same diagrams across all documentation and environments
- Maintainability: Update diagrams by editing code, not manual image editing
- Collaboration: Multiple developers can work on diagrams without conflicts
- Reproducibility: Generate diagrams on-demand with consistent results
- Integration: Diagrams can be embedded in documentation and generated during builds
- Reusability: Diagram components can be shared and reused across projects
Diagram as Code Philosophy
Diagrams should be treated as code—versioned, tested, and generated automatically. This ensures documentation stays in sync with the actual system architecture and provides a single source of truth for visual representations of the system.
Architecture Overview¶
Diagram Types¶
The template supports multiple diagram types:
Diagram as Code
├── Python Diagrams (diagrams library)
│ ├── C4 Diagrams (System Context, Container, Component, Deployment, Dynamic, System Landscape)
│ ├── Infrastructure Diagrams (AWS, Azure, Kubernetes, Docker Compose)
│ ├── Observability Diagrams
│ └── CI/CD Diagrams
└── Mermaid Diagrams
├── Flowcharts
├── Sequence Diagrams
├── Class Diagrams
└── State Diagrams
Project Structure¶
ConnectSoft.MicroserviceTemplate.DiagramAsCodeModel/
├── ConnectSoft.MicroserviceTemplate.DiagramAsCodeModel.pyproj
├── requirements.txt
├── ConnectSoft.MicroserviceTemplate.C4-SystemContextDiagram.py
├── ConnectSoft.MicroserviceTemplate.C4-ContainerDiagram.py
├── ConnectSoft.MicroserviceTemplate.C4-ComponentDiagram.py
├── ConnectSoft.MicroserviceTemplate.C4-DeploymentDiagram.py
├── ConnectSoft.MicroserviceTemplate.C4-DynamicDiagram.py
├── ConnectSoft.MicroserviceTemplate.C4-SystemLandscapeDiagram.py
├── ConnectSoft.MicroserviceTemplate.Azure.py
├── ConnectSoft.MicroserviceTemplate.AWS.py
├── ConnectSoft.MicroserviceTemplate.Kubernetes.py
├── ConnectSoft.MicroserviceTemplate.DockerCompose.py
├── ConnectSoft.MicroserviceTemplate.Observability.py
├── ConnectSoft.MicroserviceTemplate.CICD.py
├── ConnectSoft.MicroserviceTemplate.OnPrem.py
└── images/
├── hangfire.png
├── health.png
├── orleans.png
├── otel-collector.png
├── seq.png
└── swagger.png
Docs/Diagrams/
├── Solution Structure Graph.mmd
└── Use Cases.mmd
ConnectSoft.MicroserviceTemplate.DiagramAsCodeModel Project¶
Project Overview¶
The ConnectSoft.MicroserviceTemplate.DiagramAsCodeModel is a Python project that provides programmatic diagram generation for the microservice template. It uses the diagrams Python library to generate architecture diagrams programmatically, ensuring consistency and maintainability.
Key Features:
- Visual Studio Integration: Python project file (.pyproj) for Visual Studio support
- C4 Model Diagrams: Complete C4 model implementation (System Context, Container, Component, Deployment, Dynamic, System Landscape)
- Infrastructure Diagrams: Azure, AWS, Kubernetes, Docker Compose, On-Premises
- Observability Diagrams: Telemetry and monitoring architecture
- CI/CD Diagrams: Build and deployment pipeline visualization
- Custom Icons: Custom images for template-specific components (Hangfire, Orleans, Swagger, etc.)
Project File Structure¶
ConnectSoft.MicroserviceTemplate.DiagramAsCodeModel.pyproj:
Visual Studio Python project file that:
- Defines project structure and dependencies
- Configures build settings
- Sets startup file (ConnectSoft.MicroserviceTemplate.OnPrem.py)
- Includes all Python diagram scripts
- References custom images
requirements.txt:
Dependencies:
- diagrams: Python library for generating architecture diagrams
- pip: Package installer (version pinned for consistency)
Diagram Scripts¶
Each diagram script is a standalone Python file that generates a specific type of diagram. All scripts follow a consistent pattern:
Common Pattern¶
All diagram scripts follow this pattern:
import os
from diagrams import Diagram, Cluster, Edge
# Configure output path
script_dir = os.path.dirname(os.path.abspath(__file__))
output_path = os.path.join(script_dir, "..", "Images", "DiagramName")
images_path = os.path.join(script_dir, "Images")
# Graph styling attributes
graph_attr = {
"center": "true",
"splines": "spline", # Rounded arrows
"fontsize": "16",
"fontname": "Arial",
"fontcolor": "black",
"style": "rounded"
}
cluster_attr = {
"fontsize": "16",
"fontname": "Arial",
"fontcolor": "black",
"style": "rounded"
}
# Generate diagram
with Diagram('DiagramName',
show=True,
direction="TB",
filename=output_path,
outformat="png",
graph_attr=graph_attr):
# Diagram content
C4 System Context Diagram¶
File: ConnectSoft.MicroserviceTemplate.C4-SystemContextDiagram.py
Purpose: Shows the microservice in the context of its users and external systems.
Components: - User/Developer - Application container - Dashboards (Hangfire, Swagger, Health Check, Orleans Dashboard) - Dependencies (Redis, RabbitMQ, MongoDB, SQL Server) - Security (Azure Key Vault) - Observability Collectors (Elasticsearch, Jaeger, Prometheus, OTel Collector, Seq) - Observability Visualizations (Kibana, Grafana)
Output: Images/ConnectSoft.MicroserviceTemplate.C4SystemContext.png
C4 Container Diagram¶
File: ConnectSoft.MicroserviceTemplate.C4-ContainerDiagram.py
Purpose: Shows the containers (applications, databases, etc.) that make up the microservice.
Components: - API container (Dotnet Core) - Worker container (Background Worker) - OTel Collector - Seq (Logs) - Dashboards (Hangfire, Swagger UI, Health Check, Orleans Dashboard) - Dependencies (Redis, RabbitMQ, MongoDB, SQL Server) - Security (Azure Key Vault) - Observability stack (Elasticsearch, Jaeger, Prometheus, Kibana, Grafana)
Output: Images/ConnectSoft.MicroserviceTemplate.C4Container.png
Key Features:
- Uses C4 model Container and Database types
- Shows relationships between containers
- Groups related components using SystemBoundary
C4 Component Diagram¶
File: ConnectSoft.MicroserviceTemplate.C4-ComponentDiagram.py
Purpose: Shows the internal components of the API container.
Output: Images/ConnectSoft.MicroserviceTemplate.C4Component.png
C4 Deployment Diagram¶
File: ConnectSoft.MicroserviceTemplate.C4-DeploymentDiagram.py
Purpose: Shows how containers are deployed to infrastructure.
Output: Images/ConnectSoft.MicroserviceTemplate.C4Deployment.png
C4 Dynamic Diagram¶
File: ConnectSoft.MicroserviceTemplate.C4-DynamicDiagram.py
Purpose: Shows dynamic interactions and flows between components.
Output: Images/ConnectSoft.MicroserviceTemplate.C4Dynamic.png
C4 System Landscape Diagram¶
File: ConnectSoft.MicroserviceTemplate.C4-SystemLandscapeDiagram.py
Purpose: Shows multiple systems and their relationships.
Output: Images/ConnectSoft.MicroserviceTemplate.C4SystemLandscape.png
Azure Infrastructure Diagram¶
File: ConnectSoft.MicroserviceTemplate.Azure.py
Purpose: Shows Azure-specific infrastructure components.
Components: - Azure App Services - Azure SQL Database - Azure Storage - Azure Key Vault - Azure Service Bus - Azure Application Insights
Output: Images/ConnectSoft.MicroserviceTemplate.Azure.png
AWS Infrastructure Diagram¶
File: ConnectSoft.MicroserviceTemplate.AWS.py
Purpose: Shows AWS-specific infrastructure components.
Components: - EC2 instances - RDS databases - S3 buckets - AWS Lambda - AWS CloudWatch
Output: Images/ConnectSoft.MicroserviceTemplate.AWS.png
Kubernetes Diagram¶
File: ConnectSoft.MicroserviceTemplate.Kubernetes.py
Purpose: Shows Kubernetes deployment architecture.
Components: - Kubernetes cluster - Pods - Services - Deployments - ConfigMaps - Secrets
Output: Images/ConnectSoft.MicroserviceTemplate.Kubernetes.png
Docker Compose Diagram¶
File: ConnectSoft.MicroserviceTemplate.DockerCompose.py
Purpose: Shows Docker Compose stack architecture.
Components: - Application container - Database containers (SQL Server, MongoDB, Redis) - Message queue (RabbitMQ) - Monitoring stack (Prometheus, Grafana) - CI/CD integration (Azure DevOps)
Output: Images/ConnectSoft.MicroserviceTemplate.DockerCompose.png
Example Code:
from diagrams import Diagram, Cluster, Edge
from diagrams.onprem.compute import Server
from diagrams.onprem.database import Mssql
from diagrams.onprem.inmemory import Redis
from diagrams.onprem.queue import Rabbitmq
def main():
with Diagram('ConnectSoft.MicroserviceTemplate Diagram', show=True, direction="TB"):
with Cluster("ConnectSoft.MicroserviceTemplate.Application"):
app_server = Server("Server")
db = Mssql("Database")
cache = Redis("Cache")
message_queue = Rabbitmq("Message Queue")
app_server >> Edge(label="SQL") >> db
app_server >> Edge(label="Cache") >> cache
app_server >> Edge(label="Queues") >> message_queue
if __name__ == "__main__":
main()
Observability Diagram¶
File: ConnectSoft.MicroserviceTemplate.Observability.py
Purpose: Shows the observability stack and telemetry flow.
Components: - Instrumented Application - Collection (OTel Collector) - Processing and Storage (Jaeger, Prometheus, Elasticsearch) - Visualization and Alerting (Kibana, Grafana, Notification Systems)
Output: Images/ConnectSoft.MicroserviceTemplate.Observability.png
Key Features: - Shows complete telemetry pipeline - Demonstrates trace, metric, and log flows - Includes alerting and notification systems
Example Code:
from diagrams import Diagram, Cluster, Edge
from diagrams.onprem.container import Docker
from diagrams.custom import Custom
from diagrams.onprem.tracing import Jaeger
from diagrams.onprem.monitoring import Prometheus, Grafana
with Diagram('ConnectSoft.MicroserviceTemplate.Observability',
show=True,
direction="TB",
filename=output_path,
outformat="png",
graph_attr=graph_attr):
app = Docker("Instrumented Application")
with Cluster("Collection", graph_attr=cluster_attr):
otel_collector = Custom("OTel Collector", os.path.join(images_path, "otel-collector.png"))
with Cluster("Processing and Storage", graph_attr=cluster_attr):
jaeger = Jaeger("Jaeger")
prometheus = Prometheus("Prometheus")
elasticsearch = Elasticsearch("Elasticsearch")
with Cluster("Visualization and Alerting", graph_attr=cluster_attr):
kibana = Kibana("Kibana")
grafana = Grafana("Grafana")
app >> Edge(label="sends\ntelemetry") >> otel_collector
otel_collector >> Edge(label="traces") >> jaeger
otel_collector >> Edge(label="metrics") >> prometheus
otel_collector >> Edge(label="logs") >> elasticsearch
prometheus >> Edge(label="connects") >> grafana
elasticsearch >> Edge(label="connects") >> kibana
CI/CD Diagram¶
File: ConnectSoft.MicroserviceTemplate.CICD.py
Purpose: Shows CI/CD pipeline and deployment process.
Components: - Azure DevOps - Application server - Database - Cache - Message Queue - Monitoring and dashboards
Output: Images/ConnectSoft.MicroserviceTemplate.CICD.png
On-Premises Diagram¶
File: ConnectSoft.MicroserviceTemplate.OnPrem.py
Purpose: Shows on-premises deployment architecture.
Components: - On-premises servers - Local databases - Local infrastructure components
Output: Images/ConnectSoft.MicroserviceTemplate.OnPrem.png
Note: This is the startup file for the Visual Studio Python project.
Custom Icons¶
The project includes custom icons for template-specific components:
Location: images/ directory
Custom Icons:
- hangfire.png - Hangfire background job scheduler
- health.png - Health check dashboard
- orleans.png - Orleans dashboard
- otel-collector.png - OpenTelemetry Collector
- seq.png - Seq log viewer
- swagger.png - Swagger UI
Usage:
from diagrams.custom import Custom
import os
images_path = os.path.join(os.path.dirname(__file__), "Images")
# Use custom icon
hangfire = Custom("Hangfire", os.path.join(images_path, "hangfire.png"))
swagger = Custom("Swagger UI", os.path.join(images_path, "swagger.png"))
Benefits: - Consistent branding across diagrams - Template-specific components clearly identified - Professional appearance
Output Configuration¶
Output Path:
All diagrams are generated in the Images/ directory at the solution root:
script_dir = os.path.dirname(os.path.abspath(__file__))
output_path = os.path.join(script_dir, "..", "Images", "DiagramName")
Output Format:
- Default: PNG (outformat="png")
- Can be changed to: SVG, PDF, JPG
File Naming:
- Files are named based on the diagram title
- Example: ConnectSoft.MicroserviceTemplate.C4SystemContext.png
Visual Studio Integration¶
Python Project File:
The .pyproj file enables Visual Studio integration:
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<StartupFile>ConnectSoft.MicroserviceTemplate.OnPrem.py</StartupFile>
<Name>ConnectSoft.MicroserviceTemplate.DiagramAsCodeModel</Name>
</PropertyGroup>
<ItemGroup>
<Compile Include="ConnectSoft.MicroserviceTemplate.C4-SystemContextDiagram.py" />
<!-- ... other diagram scripts ... -->
</ItemGroup>
</Project>
Features: - F5 Launch: Run diagram scripts directly from Visual Studio - Debugging: Set breakpoints and debug diagram generation - IntelliSense: Code completion and syntax highlighting - Project Management: Organize diagram scripts as a project
Running Diagrams:
1. Right-click on any .py file → "Set as Startup File"
2. Press F5 to run and generate the diagram
3. Diagram opens automatically (if show=True)
Running Diagram Scripts¶
Individual Script:
# Navigate to diagram project
cd ConnectSoft.MicroserviceTemplate.DiagramAsCodeModel
# Run specific diagram
python ConnectSoft.MicroserviceTemplate.C4-SystemContextDiagram.py
All Scripts:
# Run all C4 diagrams
python ConnectSoft.MicroserviceTemplate.C4-SystemContextDiagram.py
python ConnectSoft.MicroserviceTemplate.C4-ContainerDiagram.py
python ConnectSoft.MicroserviceTemplate.C4-ComponentDiagram.py
python ConnectSoft.MicroserviceTemplate.C4-DeploymentDiagram.py
python ConnectSoft.MicroserviceTemplate.C4-DynamicDiagram.py
python ConnectSoft.MicroserviceTemplate.C4-SystemLandscapeDiagram.py
# Run infrastructure diagrams
python ConnectSoft.MicroserviceTemplate.Azure.py
python ConnectSoft.MicroserviceTemplate.AWS.py
python ConnectSoft.MicroserviceTemplate.Kubernetes.py
python ConnectSoft.MicroserviceTemplate.DockerCompose.py
# Run specialized diagrams
python ConnectSoft.MicroserviceTemplate.Observability.py
python ConnectSoft.MicroserviceTemplate.CICD.py
python ConnectSoft.MicroserviceTemplate.OnPrem.py
Automated Generation Script: Create a script to generate all diagrams:
# generate_all_diagrams.py
import os
import subprocess
script_dir = os.path.dirname(os.path.abspath(__file__))
diagram_scripts = [
"ConnectSoft.MicroserviceTemplate.C4-SystemContextDiagram.py",
"ConnectSoft.MicroserviceTemplate.C4-ContainerDiagram.py",
"ConnectSoft.MicroserviceTemplate.C4-ComponentDiagram.py",
"ConnectSoft.MicroserviceTemplate.C4-DeploymentDiagram.py",
"ConnectSoft.MicroserviceTemplate.C4-DynamicDiagram.py",
"ConnectSoft.MicroserviceTemplate.C4-SystemLandscapeDiagram.py",
"ConnectSoft.MicroserviceTemplate.Azure.py",
"ConnectSoft.MicroserviceTemplate.AWS.py",
"ConnectSoft.MicroserviceTemplate.Kubernetes.py",
"ConnectSoft.MicroserviceTemplate.DockerCompose.py",
"ConnectSoft.MicroserviceTemplate.Observability.py",
"ConnectSoft.MicroserviceTemplate.CICD.py",
"ConnectSoft.MicroserviceTemplate.OnPrem.py",
]
for script in diagram_scripts:
script_path = os.path.join(script_dir, script)
print(f"Generating {script}...")
try:
subprocess.run(["python", script_path], check=True, cwd=script_dir)
print(f"✓ Generated {script}")
except subprocess.CalledProcessError as e:
print(f"✗ Failed to generate {script}: {e}")
print("All diagrams generated!")
Diagram Styling¶
Consistent Styling: All diagram scripts use consistent styling:
graph_attr = {
"center": "true",
"splines": "spline", # Rounded arrows
"fontsize": "16",
"fontname": "Arial",
"fontcolor": "black",
"style": "rounded"
}
cluster_attr = {
"fontsize": "16",
"fontname": "Arial",
"fontcolor": "black",
"style": "rounded"
}
Benefits: - Consistent appearance across all diagrams - Professional look and feel - Easy to read and understand - Brand consistency
Customization¶
Adding New Diagrams:
1. Create new Python file: ConnectSoft.MicroserviceTemplate.NewDiagram.py
2. Follow the common pattern
3. Add to .pyproj file
4. Update generation scripts
Modifying Existing Diagrams: 1. Edit the corresponding Python file 2. Run the script to regenerate 3. Commit changes to version control
Adding Custom Icons:
1. Add PNG/SVG file to images/ directory
2. Reference in diagram script:
Python Diagrams Library¶
Overview¶
The Python Diagrams library is a Python package that generates cloud system architecture diagrams using code. It uses Graphviz under the hood to render diagrams as images (PNG, SVG, etc.).
Installation¶
Prerequisites: - Python 3.7+ - Graphviz (must be installed on the system)
Install Graphviz:
# Windows (using Chocolatey)
choco install graphviz
# macOS (using Homebrew)
brew install graphviz
# Linux (Ubuntu/Debian)
sudo apt-get install graphviz
Install Python Dependencies:
requirements.txt:
Basic Usage¶
Simple Diagram:
from diagrams import Diagram, Cluster, Edge
from diagrams.onprem.compute import Server
from diagrams.onprem.database import Mssql
with Diagram('Simple Microservice', show=True, direction="TB"):
server = Server("Application")
database = Mssql("Database")
server >> Edge(label="connects to") >> database
Output: Generates a PNG image showing a server connected to a database.
Diagram Structure¶
Basic Elements:
from diagrams import Diagram, Cluster, Edge
# Create diagram
with Diagram('My Diagram', show=True, direction="TB"):
# Add nodes
node1 = Server("Node 1")
node2 = Server("Node 2")
# Add connections
node1 >> Edge(label="label") >> node2
Parameters:
- show=True: Open the diagram after generation
- direction: "TB" (top-bottom), "LR" (left-right), "BT" (bottom-top), "RL" (right-left)
- filename: Output file path (without extension)
- outformat: Output format ("png", "svg", "pdf", "jpg")
Clusters¶
Grouping Components:
from diagrams import Diagram, Cluster
from diagrams.onprem.compute import Server
from diagrams.onprem.database import Mssql
with Diagram('Clustered Architecture', show=True):
with Cluster("Application Layer"):
app1 = Server("App 1")
app2 = Server("App 2")
with Cluster("Database Layer"):
db1 = Mssql("Database 1")
db2 = Mssql("Database 2")
C4 Diagrams¶
C4 Model Support:
The template includes C4 diagram scripts for different levels of abstraction:
System Context Diagram:
from diagrams.c4 import Person, System, SystemBoundary, Relationship
with Diagram('System Context', show=True):
user = Person(name="User", description="System user", external=True)
with SystemBoundary("ConnectSoft.MicroserviceTemplate"):
system = System(
name="Microservice",
description="Main microservice application",
external=False)
user >> Relationship("Uses") >> system
Container Diagram:
from diagrams.c4 import Container, SystemBoundary, Person, Database, Relationship
with Diagram('Container Diagram', show=True):
user = Person(name="User", external=True)
with SystemBoundary("Microservice"):
api = Container(
name="API",
technology=".NET Core",
description="REST API")
database = Database(
name="Database",
technology="SQL Server",
description="Main database")
user >> Relationship("Uses") >> api
api >> Relationship("Reads/Writes") >> database
Available C4 Diagrams in Template:
- C4-SystemContextDiagram.py: System context view
- C4-ContainerDiagram.py: Container view
- C4-ComponentDiagram.py: Component view
- C4-DeploymentDiagram.py: Deployment view
- C4-DynamicDiagram.py: Dynamic/interaction view
- C4-SystemLandscapeDiagram.py: System landscape view
Custom Icons¶
Using Custom Images:
from diagrams import Diagram
from diagrams.custom import Custom
import os
images_path = os.path.join(os.path.dirname(__file__), "images")
with Diagram('Custom Icons', show=True):
hangfire = Custom("Hangfire", os.path.join(images_path, "hangfire.png"))
swagger = Custom("Swagger", os.path.join(images_path, "swagger.png"))
Provider-Specific Diagrams¶
Azure Diagrams:
from diagrams.azure.compute import AppServices
from diagrams.azure.database import SQLDatabases
from diagrams.azure.storage import StorageAccounts
with Diagram('Azure Architecture', show=True):
app = AppServices("Web App")
db = SQLDatabases("SQL Database")
storage = StorageAccounts("Storage")
app >> db
app >> storage
AWS Diagrams:
from diagrams.aws.compute import EC2
from diagrams.aws.database import RDS
from diagrams.aws.storage import S3
with Diagram('AWS Architecture', show=True):
ec2 = EC2("EC2 Instance")
rds = RDS("RDS Database")
s3 = S3("S3 Bucket")
ec2 >> rds
ec2 >> s3
Advanced Configuration¶
Graph Attributes:
graph_attr = {
"center": "true",
"splines": "spline", # Rounded arrows
"fontsize": "16",
"fontname": "Arial",
"fontcolor": "black",
"style": "rounded"
}
cluster_attr = {
"fontsize": "16",
"fontname": "Arial",
"fontcolor": "black",
"style": "rounded"
}
with Diagram('Styled Diagram',
show=True,
graph_attr=graph_attr):
# Diagram content
Output Configuration:
script_dir = os.path.dirname(os.path.abspath(__file__))
output_path = os.path.join(script_dir, "..", "Images", "MyDiagram")
with Diagram('My Diagram',
show=True,
filename=output_path,
outformat="png",
graph_attr=graph_attr):
# Diagram content
Running Diagram Scripts¶
Individual Scripts:
# Navigate to diagram project
cd ConnectSoft.MicroserviceTemplate.DiagramAsCodeModel
# Run a specific diagram script
python ConnectSoft.MicroserviceTemplate.C4-SystemContextDiagram.py
python ConnectSoft.MicroserviceTemplate.Azure.py
All Scripts:
# Run all diagram scripts
python ConnectSoft.MicroserviceTemplate.C4-SystemContextDiagram.py
python ConnectSoft.MicroserviceTemplate.C4-ContainerDiagram.py
python ConnectSoft.MicroserviceTemplate.C4-ComponentDiagram.py
# ... etc
Mermaid Diagrams¶
Overview¶
Mermaid is a text-based diagram markup language that can be embedded directly in Markdown files. It's supported by many documentation platforms (GitHub, GitLab, MkDocs, etc.) and renders diagrams client-side.
Flowcharts¶
Basic Flowchart:
flowchart TD
Start([Start]) --> Process[Process]
Process --> Decision{Decision?}
Decision -->|Yes| End1([End 1])
Decision -->|No| End2([End 2])
Code:
```mermaid
flowchart TD
Start([Start]) --> Process[Process]
Process --> Decision{Decision?}
Decision -->|Yes| End1([End 1])
Decision -->|No| End2([End 2])
**Complex Flowchart with Subgraphs**:
```mermaid
flowchart TB
subgraph "Application Layer"
API[API]
Service[Service]
end
subgraph "Database Layer"
DB[(Database)]
end
API --> Service
Service --> DB
Sequence Diagrams¶
Sequence Diagram:
sequenceDiagram
participant Client
participant API
participant Service
participant Database
Client->>API: Request
API->>Service: Process
Service->>Database: Query
Database-->>Service: Result
Service-->>API: Response
API-->>Client: Response
Class Diagrams¶
Class Diagram:
classDiagram
class Processor {
+Process(input) IOutput
}
class Retriever {
+Retrieve(input) IOutput
}
class Repository {
+Insert(entity)
+Update(entity)
+Delete(entity)
}
Processor --> Repository
Retriever --> Repository
State Diagrams¶
State Diagram:
stateDiagram-v2
[*] --> Draft
Draft --> Review
Review --> Approved
Review --> Rejected
Approved --> Published
Rejected --> Draft
Published --> [*]
Solution Structure Diagram¶
Example from Template:
graph TB
subgraph "ConnectSoft.MicroserviceTemplate [Microservice]"
subgraph TestLibraries [Test Libraries]
UnitTests["ConnectSoft.MicroserviceTemplate.UnitTests"]
ArchitectureTests["ConnectSoft.MicroserviceTemplate.ArchitectureTests"]
end
subgraph DomainLayer [Domain Layer]
DomainModel["ConnectSoft.MicroserviceTemplate.DomainModel"]
end
end
File: Docs/Diagrams/Solution Structure Graph.mmd
Use Case Diagrams¶
Example from Template:
flowchart LR
subgraph 'ConnectSoft.MicroserviceTemplate microservice'
uc1((Retrieve MicroserviceAggregateRoots use case))
uc2((Process MicroserviceAggregateRoots use cases))
uc3((Create MicroserviceAggregateRoot use case))
uc4((Delete MicroserviceAggregateRoot use case))
end
consumer[Microservice Consumer]
consumer-->uc1
consumer-->uc2
uc2 -. include .-> uc3
uc2 -. include .-> uc4
File: Docs/Diagrams/Use Cases.mmd
Embedding in Documentation¶
MkDocs Integration:
Mermaid diagrams are automatically rendered in MkDocs when using the mkdocs-mermaid2-plugin:
Markdown Usage:
# Architecture Overview
Here's the system architecture:
```mermaid
flowchart TD
A[Client] --> B[API]
B --> C[Service]
## CI/CD Integration
### Pipeline Configuration
**Azure DevOps Pipeline**:
```yaml
# azure-pipelines.yml
variables:
isRemovePythonDiagramsEnabled: true
pythonDiagramsProjectName: 'ConnectSoft.MicroserviceTemplate.DiagramAsCodeModel/ConnectSoft.MicroserviceTemplate.DiagramAsCodeModel.pyproj'
stages:
- stage: GenerateDiagrams
jobs:
- job: GeneratePythonDiagrams
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '3.9'
- script: |
cd ConnectSoft.MicroserviceTemplate.DiagramAsCodeModel
pip install -r requirements.txt
python ConnectSoft.MicroserviceTemplate.C4-SystemContextDiagram.py
python ConnectSoft.MicroserviceTemplate.C4-ContainerDiagram.py
# ... other diagram scripts
displayName: 'Generate Python Diagrams'
- task: PublishPipelineArtifact@1
inputs:
targetPath: 'Images'
artifactName: 'diagrams'
Pre-commit Hooks¶
Generate Diagrams Before Commit:
#!/bin/bash
# .git/hooks/pre-commit
cd ConnectSoft.MicroserviceTemplate.DiagramAsCodeModel
pip install -r requirements.txt
python ConnectSoft.MicroserviceTemplate.C4-SystemContextDiagram.py
# ... other scripts
Build Integration¶
MSBuild Target:
<Target Name="GenerateDiagrams" BeforeTargets="Build">
<Exec Command="python ConnectSoft.MicroserviceTemplate.DiagramAsCodeModel/ConnectSoft.MicroserviceTemplate.C4-SystemContextDiagram.py" />
</Target>
Best Practices¶
Do's¶
-
Version Control All Diagram Code
-
Use Descriptive Names
-
Organize by Purpose
-
Use Consistent Styling
-
Document Diagram Purpose
-
Generate Images Automatically
-
Keep Diagrams Up to Date
Don'ts¶
-
Don't Commit Generated Images
-
Don't Hardcode Paths
-
Don't Mix Diagram Types
-
Don't Create Overly Complex Diagrams
-
Don't Ignore Diagram Updates
Diagram Types Guide¶
C4 Model Diagrams¶
When to Use Each Level:
| Level | Purpose | When to Use |
|---|---|---|
| System Context | High-level system overview | Initial documentation, stakeholder communication |
| Container | Application containers and interactions | Architecture documentation, deployment planning |
| Component | Internal components and relationships | Developer documentation, code organization |
| Deployment | Physical infrastructure | Infrastructure planning, deployment documentation |
| Dynamic | Interaction flows | Understanding system behavior |
| System Landscape | Multiple systems overview | System portfolio view, enterprise architecture |
Infrastructure Diagrams¶
When to Use:
- Azure Diagrams: For Azure-hosted deployments
- AWS Diagrams: For AWS-hosted deployments
- Kubernetes Diagrams: For container orchestration
- Docker Compose Diagrams: For local development setup
- On-Prem Diagrams: For on-premises deployments
Observability Diagrams¶
When to Use:
- Show monitoring and logging architecture
- Document telemetry flow
- Explain observability stack
CI/CD Diagrams¶
When to Use:
- Document build and deployment pipelines
- Show automated workflows
- Explain deployment process
Troubleshooting¶
Issue: Python Diagrams Not Generating¶
Symptoms: Diagram script runs but no image is created.
Solutions:
1. Verify Graphviz is installed: dot -V
2. Check Python dependencies: pip list | grep diagrams
3. Verify output path is writable
4. Check for errors in script execution
5. Verify show=True parameter (if testing interactively)
Issue: Mermaid Diagrams Not Rendering¶
Symptoms: Mermaid code blocks show as code instead of diagrams.
Solutions:
1. Verify MkDocs plugin is installed: pip install mkdocs-mermaid2-plugin
2. Check plugin configuration in mkdocs.yml
3. Verify syntax is correct (proper indentation)
4. Check browser console for JavaScript errors
5. Verify Mermaid version compatibility
Issue: Custom Icons Not Showing¶
Symptoms: Custom icon placeholders appear instead of images.
Solutions: 1. Verify image path is correct (relative to script) 2. Check image file exists and is readable 3. Verify image format is supported (PNG, SVG) 4. Check file permissions 5. Use absolute paths if relative paths fail
Issue: Diagrams Too Large¶
Symptoms: Generated diagrams are too large or complex.
Solutions: 1. Split into multiple diagrams (C4 model levels) 2. Reduce number of nodes 3. Use clusters to group related components 4. Increase output resolution settings 5. Use vector formats (SVG) for scalability
Advanced Patterns¶
Diagram Generation Script¶
Automated Generation:
# generate_all_diagrams.py
import os
import subprocess
diagram_scripts = [
"ConnectSoft.MicroserviceTemplate.C4-SystemContextDiagram.py",
"ConnectSoft.MicroserviceTemplate.C4-ContainerDiagram.py",
"ConnectSoft.MicroserviceTemplate.C4-ComponentDiagram.py",
"ConnectSoft.MicroserviceTemplate.Azure.py",
"ConnectSoft.MicroserviceTemplate.Kubernetes.py",
]
script_dir = os.path.dirname(os.path.abspath(__file__))
for script in diagram_scripts:
script_path = os.path.join(script_dir, script)
print(f"Generating {script}...")
subprocess.run(["python", script_path], check=True)
print(f"✓ Generated {script}")
print("All diagrams generated successfully!")
Template-Based Diagrams¶
Reusable Components:
# diagram_components.py
from diagrams import Cluster, Edge
from diagrams.onprem.compute import Server
from diagrams.onprem.database import Mssql
def create_application_cluster(name):
with Cluster(name):
app = Server("Application")
db = Mssql("Database")
app >> db
return app, db
# Usage
from diagram_components import create_application_cluster
with Diagram('Multi-Service Architecture', show=True):
app1, db1 = create_application_cluster("Service 1")
app2, db2 = create_application_cluster("Service 2")
Conditional Diagram Generation¶
Environment-Based Diagrams:
import os
environment = os.getenv("DEPLOYMENT_ENVIRONMENT", "development")
if environment == "production":
# Generate production diagram
from diagrams.azure.compute import AppServices
elif environment == "development":
# Generate development diagram
from diagrams.onprem.compute import Server
Summary¶
Diagram as Code in the ConnectSoft Microservice Template provides:
- ✅ Version Control: Diagrams stored as code in version control
- ✅ Automation: Automatic diagram generation in CI/CD
- ✅ Consistency: Same diagrams across all environments
- ✅ Maintainability: Update diagrams by editing code
- ✅ Multiple Formats: Python diagrams (PNG/SVG) and Mermaid (text-based)
- ✅ C4 Model Support: Full C4 model implementation
- ✅ Provider Support: Azure, AWS, Kubernetes, Docker Compose
- ✅ Documentation Integration: Mermaid diagrams embedded in Markdown
By following these patterns, teams can:
- Maintain Up-to-Date Documentation: Diagrams stay in sync with architecture
- Collaborate Effectively: Multiple developers can work on diagrams
- Automate Generation: Diagrams generated automatically in CI/CD
- Ensure Consistency: Same diagrams across all environments
- Reduce Maintenance: Update code, not images
- Improve Communication: Visual representations of system architecture
Diagram as Code transforms diagrams from static images into living documentation that evolves with the system, ensuring architecture documentation remains accurate and up-to-date.