Deployment Diagram¶
A deployment diagram shows how software systems or containers are deployed onto infrastructure for an environment such as production, staging, or development. It is useful for developers, platform engineers, and operations teams who need to understand runtime topology and network boundaries.
Supported DSL Classes¶
Use DeploymentDiagram with:
Nodefor a generic infrastructure boundaryDeploymentNodefor a C4 deployment node such as a device, server, runtime, cluster, or managed serviceContainer,ContainerDb, and queue variants for deployed software- portable
Rel
Node and DeploymentNode are portable deployment model classes. Layout
variants live in contrib packages: NodeLeft and NodeRight in
c4.contrib.c4_macros, and DeploymentNodeLeft and DeploymentNodeRight in
c4.contrib.plantuml.
Portable Example¶
from c4 import Container, ContainerDb, DeploymentDiagram, DeploymentNode, Rel
with DeploymentDiagram(title="Retail production deployment") as diagram:
with DeploymentNode("Production Cloud Account"):
with DeploymentNode("Kubernetes Cluster"):
api = Container("Backend API", "Handles checkout.", "Python")
with DeploymentNode("Managed PostgreSQL"):
db = ContainerDb("Orders Database", "Stores orders.", "PostgreSQL")
api >> Rel("Reads and writes", "TLS / SQL") >> db
plantuml_source = diagram.as_plantuml()
mermaid_source = diagram.as_mermaid()
PlantUML enhanced example¶
Non-portable PlantUML example
This snippet uses PlantUML extension data, node variants, and layout helpers. Render it with the PlantUML rendering backend when keeping those hints.
The generated PlantUML example uses node tags, directional node variants, layout helpers, relationship styling, and a legend.
from c4 import (
Container,
ContainerDb,
ContainerExt,
ContainerQueue,
DeploymentDiagram,
DeploymentNode,
Node,
Person,
Rel,
)
from c4.contrib.plantuml import (
DeploymentNodeLeft,
DeploymentNodeRight,
LayD,
LayR,
NodeLeft,
NodeRight,
)
from c4.renderers import (
PlantUMLRenderOptionsBuilder,
)
with DeploymentDiagram(title='Online Shop - Production Deployment') as diagram:
customer = Person('Customer', 'Uses the online shop through a browser.', plantuml={'tags': ['person']}, alias='customer')
payment_gateway = ContainerExt('Payment Gateway', 'External service that processes card payments.', plantuml={'tags': ['external_service']}, technology='HTTPS API', alias='payment_gateway')
with Node('AWS Production Account', 'Production cloud account for the online shop.', plantuml={'tags': ['cloud_account'], 'type': 'Cloud Account'}, alias='aws_prod'):
with NodeLeft('Public Subnet', 'Internet-facing network segment.', plantuml={'tags': ['public_network'], 'type': 'Network Segment'}, alias='public_subnet'):
with DeploymentNodeLeft('Application Load Balancer', 'Terminates TLS and routes requests to the web tier.', plantuml={'tags': ['edge_node'], 'type': 'Ingress'}, alias='alb') as alb:
web_app = Container('Web Application', 'Serves the storefront UI.', plantuml={'tags': ['frontend']}, technology='Next.js', alias='web_app')
with NodeRight('Private Subnet', 'Internal network segment for application and data services.', plantuml={'tags': ['private_network'], 'type': 'Network Segment'}, alias='private_subnet'):
with DeploymentNode('Kubernetes Cluster', 'Runs backend services and asynchronous workers.', plantuml={'tags': ['runtime_node'], 'type': 'Runtime Environment'}, alias='app_cluster') as app_cluster:
backend_api = Container('Backend API', 'Handles catalog, checkout, and order processing.', plantuml={'tags': ['backend']}, technology='Python / FastAPI', alias='backend_api')
order_events = ContainerQueue('Order Events', 'Internal asynchronous event stream.', plantuml={'tags': ['message_bus']}, technology='Kafka', alias='order_events')
with DeploymentNodeRight('Managed PostgreSQL', 'Managed relational database service.', plantuml={'tags': ['data_node'], 'type': 'Data Platform'}, alias='db_service') as db_service:
orders_db = ContainerDb('Orders Database', 'Stores orders, payments, and fulfillment data.', plantuml={'tags': ['database']}, technology='PostgreSQL', alias='orders_db')
customer >> Rel('Uses', technology='HTTPS', plantuml={'tags': ['encrypted_traffic']}) >> alb
alb >> Rel('Routes traffic to', technology='HTTPS', plantuml={'tags': ['encrypted_traffic']}) >> app_cluster
app_cluster >> Rel('Reads and writes', technology='TLS / SQL', plantuml={'tags': ['encrypted_traffic']}) >> db_service
app_cluster >> Rel('Calls', technology='HTTPS/JSON', plantuml={'tags': ['encrypted_traffic']}) >> payment_gateway
backend_api >> Rel('Publishes events to', technology='Kafka', plantuml={'tags': ['async_flow']}) >> order_events
LayR(customer, alb)
LayR(alb, app_cluster)
LayD(app_cluster, db_service)
LayR(app_cluster, payment_gateway)
plantuml_render_options = (
PlantUMLRenderOptionsBuilder()
.layout_left_right(
with_legend=True,
)
.show_legend(
hide_stereotype=False,
details='Normal',
)
.update_legend_title(
'Deployment Legend',
)
.show_person_outline()
.show_person_sprite(
'person',
)
.add_person_tag(
tag_stereo='person',
bg_color='#e8f5e9',
font_color='#1b5e20',
border_color='#66bb6a',
shadowing=False,
legend_text='End user',
border_style='SolidLine',
border_thickness='2',
)
.add_external_container_tag(
tag_stereo='external_service',
bg_color='#f3e5f5',
font_color='#4a148c',
border_color='#ab47bc',
shadowing=False,
legend_text='External service',
border_style='DashedLine',
border_thickness='2',
)
.add_container_tag(
tag_stereo='frontend',
bg_color='#e3f2fd',
font_color='#0d47a1',
border_color='#42a5f5',
shadowing=False,
legend_text='Frontend container',
border_style='SolidLine',
border_thickness='2',
)
.add_container_tag(
tag_stereo='backend',
bg_color='#ede7f6',
font_color='#311b92',
border_color='#7e57c2',
shadowing=False,
legend_text='Backend container',
border_style='SolidLine',
border_thickness='2',
)
.add_container_tag(
tag_stereo='database',
bg_color='#fff3e0',
font_color='#e65100',
border_color='#fb8c00',
shadowing=False,
legend_text='Database container',
border_style='SolidLine',
border_thickness='2',
)
.add_container_tag(
tag_stereo='message_bus',
bg_color='#fce4ec',
font_color='#880e4f',
border_color='#ec407a',
shadowing=False,
legend_text='Message queue / stream',
border_style='SolidLine',
border_thickness='2',
)
.add_node_tag(
tag_stereo='cloud_account',
bg_color='#eef6ff',
font_color='#0d47a1',
border_color='#64b5f6',
shadowing=True,
shape='RoundedBoxShape',
type_='Infrastructure',
legend_text='Cloud account boundary',
legend_sprite='cloud',
border_style='SolidLine',
border_thickness='2',
)
.add_node_tag(
tag_stereo='public_network',
bg_color='#f1f8e9',
font_color='#33691e',
border_color='#8bc34a',
shadowing=False,
shape='RoundedBoxShape',
type_='DMZ',
legend_text='Public network zone',
legend_sprite='network',
border_style='SolidLine',
border_thickness='1',
)
.add_node_tag(
tag_stereo='private_network',
bg_color='#fbe9e7',
font_color='#bf360c',
border_color='#ff8a65',
shadowing=False,
shape='RoundedBoxShape',
type_='Internal',
legend_text='Private network zone',
legend_sprite='network',
border_style='SolidLine',
border_thickness='1',
)
.add_node_tag(
tag_stereo='edge_node',
bg_color='#e1f5fe',
font_color='#01579b',
border_color='#29b6f6',
shadowing=False,
shape='RoundedBoxShape',
type_='Ingress',
legend_text='Ingress deployment node',
legend_sprite='router',
border_style='BoldLine',
border_thickness='2',
)
.add_node_tag(
tag_stereo='runtime_node',
bg_color='#e8f5e9',
font_color='#1b5e20',
border_color='#66bb6a',
shadowing=True,
shape='RoundedBoxShape',
type_='Runtime',
legend_text='Runtime deployment node',
legend_sprite='server',
border_style='SolidLine',
border_thickness='2',
)
.add_node_tag(
tag_stereo='data_node',
bg_color='#fff8e1',
font_color='#ff6f00',
border_color='#ffb300',
shadowing=False,
shape='RoundedBoxShape',
type_='Data Platform',
legend_text='Data deployment node',
legend_sprite='database',
border_style='SolidLine',
border_thickness='2',
)
.add_rel_tag(
tag_stereo='encrypted_traffic',
text_color='#0d47a1',
line_color='#1976d2',
technology='TLS',
legend_text='Encrypted communication',
legend_sprite='lock',
line_style='SolidLine',
line_thickness='2',
)
.add_rel_tag(
tag_stereo='async_flow',
text_color='#4a148c',
line_color='#8e24aa',
technology='Kafka',
legend_text='Asynchronous event flow',
legend_sprite='queue',
line_style='DashedLine',
line_thickness='2',
)
.update_rel_style(
text_color='#37474f',
line_color='#546e7a',
)
.build()
)
diagram.set_render_options(
plantuml=plantuml_render_options,
)
Renderer Behavior¶
PlantUML has the most complete deployment support because C4-PlantUML provides deployment node rendering, left/right node variants, tags, sprites, and layout hints. Mermaid can render deployment-like nested nodes from the portable model, but Mermaid C4 support is experimental and lower fidelity for complex infrastructure topologies.
Generated Source and Image¶
Generated PlantUML source
@startuml
' convert it with additional command line argument -DRELATIVE_INCLUDE="relative/absolute" to use locally
!if %variable_exists("RELATIVE_INCLUDE")
!include %get_variable_value("RELATIVE_INCLUDE")/C4_Deployment.puml
!else
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Deployment.puml
!endif
AddPersonTag("person", $bgColor="#e8f5e9", $fontColor="#1b5e20", $borderColor="#66bb6a", $shadowing="false", $legendText="End user", $borderStyle=SolidLine(), $borderThickness="2")
AddExternalContainerTag("external_service", $bgColor="#f3e5f5", $fontColor="#4a148c", $borderColor="#ab47bc", $shadowing="false", $legendText="External service", $borderStyle=DashedLine(), $borderThickness="2")
AddContainerTag("frontend", $bgColor="#e3f2fd", $fontColor="#0d47a1", $borderColor="#42a5f5", $shadowing="false", $legendText="Frontend container", $borderStyle=SolidLine(), $borderThickness="2")
AddContainerTag("backend", $bgColor="#ede7f6", $fontColor="#311b92", $borderColor="#7e57c2", $shadowing="false", $legendText="Backend container", $borderStyle=SolidLine(), $borderThickness="2")
AddContainerTag("database", $bgColor="#fff3e0", $fontColor="#e65100", $borderColor="#fb8c00", $shadowing="false", $legendText="Database container", $borderStyle=SolidLine(), $borderThickness="2")
AddContainerTag("message_bus", $bgColor="#fce4ec", $fontColor="#880e4f", $borderColor="#ec407a", $shadowing="false", $legendText="Message queue / stream", $borderStyle=SolidLine(), $borderThickness="2")
AddNodeTag("cloud_account", $bgColor="#eef6ff", $fontColor="#0d47a1", $borderColor="#64b5f6", $shadowing="true", $shape=RoundedBoxShape(), $type="Infrastructure", $legendText="Cloud account boundary", $legendSprite="cloud", $borderStyle=SolidLine(), $borderThickness="2")
AddNodeTag("public_network", $bgColor="#f1f8e9", $fontColor="#33691e", $borderColor="#8bc34a", $shadowing="false", $shape=RoundedBoxShape(), $type="DMZ", $legendText="Public network zone", $legendSprite="network", $borderStyle=SolidLine(), $borderThickness="1")
AddNodeTag("private_network", $bgColor="#fbe9e7", $fontColor="#bf360c", $borderColor="#ff8a65", $shadowing="false", $shape=RoundedBoxShape(), $type="Internal", $legendText="Private network zone", $legendSprite="network", $borderStyle=SolidLine(), $borderThickness="1")
AddNodeTag("edge_node", $bgColor="#e1f5fe", $fontColor="#01579b", $borderColor="#29b6f6", $shadowing="false", $shape=RoundedBoxShape(), $type="Ingress", $legendText="Ingress deployment node", $legendSprite="router", $borderStyle=BoldLine(), $borderThickness="2")
AddNodeTag("runtime_node", $bgColor="#e8f5e9", $fontColor="#1b5e20", $borderColor="#66bb6a", $shadowing="true", $shape=RoundedBoxShape(), $type="Runtime", $legendText="Runtime deployment node", $legendSprite="server", $borderStyle=SolidLine(), $borderThickness="2")
AddNodeTag("data_node", $bgColor="#fff8e1", $fontColor="#ff6f00", $borderColor="#ffb300", $shadowing="false", $shape=RoundedBoxShape(), $type="Data Platform", $legendText="Data deployment node", $legendSprite="database", $borderStyle=SolidLine(), $borderThickness="2")
AddRelTag("encrypted_traffic", $textColor="#0d47a1", $lineColor="#1976d2", $lineStyle=SolidLine(), $techn="TLS", $legendText="Encrypted communication", $legendSprite="lock", $lineThickness="2")
AddRelTag("async_flow", $textColor="#4a148c", $lineColor="#8e24aa", $lineStyle=DashedLine(), $techn="Kafka", $legendText="Asynchronous event flow", $legendSprite="queue", $lineThickness="2")
UpdateRelStyle($textColor="#37474f", $lineColor="#546e7a")
LAYOUT_LEFT_RIGHT()
LAYOUT_WITH_LEGEND()
SHOW_PERSON_SPRITE("person")
SHOW_PERSON_OUTLINE()
UpdateLegendTitle("Deployment Legend")
title Online Shop - Production Deployment
Person(customer, "Customer", "Uses the online shop through a browser.", $tags="person")
Container_Ext(payment_gateway, "Payment Gateway", "HTTPS API", "External service that processes card payments.", $tags="external_service")
Node(aws_prod, "AWS Production Account", "Cloud Account", "Production cloud account for the online shop.", $tags="cloud_account") {
Node_L(public_subnet, "Public Subnet", "Network Segment", "Internet-facing network segment.", $tags="public_network") {
Deployment_Node_L(alb, "Application Load Balancer", "Ingress", "Terminates TLS and routes requests to the web tier.", $tags="edge_node") {
Container(web_app, "Web Application", "Next.js", "Serves the storefront UI.", $tags="frontend")
}
}
Node_R(private_subnet, "Private Subnet", "Network Segment", "Internal network segment for application and data services.", $tags="private_network") {
Deployment_Node(app_cluster, "Kubernetes Cluster", "Runtime Environment", "Runs backend services and asynchronous workers.", $tags="runtime_node") {
Container(backend_api, "Backend API", "Python / FastAPI", "Handles catalog, checkout, and order processing.", $tags="backend")
ContainerQueue(order_events, "Order Events", "Kafka", "Internal asynchronous event stream.", $tags="message_bus")
}
Deployment_Node_R(db_service, "Managed PostgreSQL", "Data Platform", "Managed relational database service.", $tags="data_node") {
ContainerDb(orders_db, "Orders Database", "PostgreSQL", "Stores orders, payments, and fulfillment data.", $tags="database")
}
}
}
Rel(customer, alb, "Uses", "HTTPS", $tags="encrypted_traffic")
Rel(alb, app_cluster, "Routes traffic to", "HTTPS", $tags="encrypted_traffic")
Rel(app_cluster, db_service, "Reads and writes", "TLS / SQL", $tags="encrypted_traffic")
Rel(app_cluster, payment_gateway, "Calls", "HTTPS/JSON", $tags="encrypted_traffic")
Rel(backend_api, order_events, "Publishes events to", "Kafka", $tags="async_flow")
Lay_R(customer, alb)
Lay_R(alb, app_cluster)
Lay_D(app_cluster, db_service)
Lay_R(app_cluster, payment_gateway)
SHOW_LEGEND($hideStereotype="false", $details=Normal())
@enduml
