Each example is one agent’s unedited, one-shot answer to a prompt from the repository’s prompt bank, approved after review. It keeps the rendered SVG, the .dgm source, the prompt, and the requirements.json contract the agent wrote before authoring. Review notes flag routing findings that remain. Any of them could be refined further, by asking the agent for changes or by editing in Studio.
Prompts come in three difficulties. Easy and medium prompts describe everyday architectures, and their one-shot diagrams are ready to use as they are. Hard prompts are dense on purpose: they are the benchmark for many interlocking relationships across regions, zones, and failure paths, so some arrow crossings remain.
Same prompts, different models
Dumb Diagrams is not tied to one model. The validator, requirements contract, and layout engine do the checking, so any capable frontier model can produce a meaningful diagram. Runs were made with Codex and Cursor, mostly using OpenAI and Anthropic models. Each card below has a switch between two runs of all 16 prompts:
| Run | Reference | Preferences | Own contract | Routing clean |
|---|---|---|---|---|
| GPT Luna 6 (max reasoning) | 16/16 | 16/16 | 16/16 | 11/16 |
| Claude Sonnet 5.5 (low reasoning) | 16/16 | 16/16 | 16/16 | 12/16 |
The routing findings that remain are crossings in the hard prompts, plus two backward arrows in Luna’s thumbnail pipeline. Both runs are frozen as regression baselines for the engine.
AWS
AWS static website delivery
Create a simple AWS static website delivery diagram. Show a website visitor, DNS, a content delivery service, and the bucket that stores the website files.Download Prompt ↓
dgm 1
diagram aws-easy-static-website-delivery { grammar aws flow lr title "AWS static website delivery"
aws.cloud aws_cloud "AWS Cloud" {
aws.route-53 dns "DNS" {}
aws.cloudfront cdn "Content delivery" {}
aws.simple-storage-service-bucket site_bucket "Website files" {}
}
cloud-agnostic.client visitor "Website visitor" {}
visitor -> dns { id visitor_dns label "site lookup" step 1 }
dns -> cdn { id dns_cdn label "resolve" step 2 }
cdn -> site_bucket { id cdn_bucket label "fetch files" step 3 }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "aws",
"components": [
{
"id": "aws_cloud",
"kind": "group",
"basis": {
"kind": "explicit",
"text": "AWS architecture and AWS services."
},
"type": "aws.cloud"
},
{
"id": "visitor",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "A website visitor requests the static site."
},
"type": "cloud-agnostic.client"
},
{
"id": "dns",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "DNS resolves the website name."
},
"type": "aws.route-53"
},
{
"id": "cdn",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "A content delivery service serves the website."
},
"type": "aws.cloudfront"
},
{
"id": "site_bucket",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "A bucket stores the website files."
},
"type": "aws.simple-storage-service-bucket"
}
],
"relationships": [
{
"id": "visitor_dns",
"source": "visitor",
"target": "dns",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "site lookup"
}
},
{
"id": "dns_cdn",
"source": "dns",
"target": "cdn",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "resolve to delivery"
}
},
{
"id": "cdn_bucket",
"source": "cdn",
"target": "site_bucket",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "fetch site files"
}
}
],
"counts": [
{
"id": "one_visitor",
"kind": "resource",
"type": "cloud-agnostic.client",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "A website visitor."
}
},
{
"id": "one_dns",
"kind": "resource",
"type": "aws.route-53",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "DNS."
}
},
{
"id": "one_cdn",
"kind": "resource",
"type": "aws.cloudfront",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "A content delivery service."
}
},
{
"id": "one_bucket",
"kind": "resource",
"type": "aws.simple-storage-service-bucket",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "The bucket that stores website files."
}
}
],
"placement": [
{
"id": "cloud_root",
"component": "aws_cloud",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "AWS architecture."
}
},
{
"id": "visitor_external",
"component": "visitor",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "A website visitor."
}
},
{
"id": "dns",
"component": "dns",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "AWS service in the AWS architecture."
},
"group": "aws_cloud"
},
{
"id": "cdn",
"component": "cdn",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "AWS service in the AWS architecture."
},
"group": "aws_cloud"
},
{
"id": "site_bucket",
"component": "site_bucket",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "AWS service in the AWS architecture."
},
"group": "aws_cloud"
}
],
"allowAdditionalResources": true
}
Download Requirements ↓ Create a simple AWS static website delivery diagram. Show a website visitor, DNS, a content delivery service, and the bucket that stores the website files.Download Prompt ↓
dgm 1
diagram aws-easy-static-website-delivery {
grammar aws
flow lr
title "AWS static website delivery"
cloud-agnostic.client visitor "Website visitor"
aws.cloud aws "AWS Cloud" {
aws.route-53 dns "DNS"
aws.cloudfront cdn "CDN"
aws.simple-storage-service bucket "Website bucket"
}
visitor -> dns { id lookup step 1 label "Resolve domain" kind flow }
dns -> cdn { id alias step 2 label "Alias to CDN" kind flow }
cdn -> bucket { id origin step 3 label "Fetch files" kind flow }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "aws",
"components": [
{
"id": "visitor",
"kind": "resource",
"type": "cloud-agnostic.client",
"basis": {
"kind": "explicit",
"text": "Show a website visitor, DNS, a content delivery service, and the bucket that stores the website files."
}
},
{
"id": "aws",
"kind": "group",
"type": "aws.cloud",
"basis": {
"kind": "inferred",
"text": "Structurally required to place or group the named resources."
}
},
{
"id": "dns",
"kind": "resource",
"type": "aws.route-53",
"basis": {
"kind": "explicit",
"text": "Show a website visitor, DNS, a content delivery service, and the bucket that stores the website files."
}
},
{
"id": "cdn",
"kind": "resource",
"type": "aws.cloudfront",
"basis": {
"kind": "explicit",
"text": "Show a website visitor, DNS, a content delivery service, and the bucket that stores the website files."
}
},
{
"id": "bucket",
"kind": "resource",
"type": "aws.simple-storage-service",
"basis": {
"kind": "explicit",
"text": "Show a website visitor, DNS, a content delivery service, and the bucket that stores the website files."
}
}
],
"relationships": [
{
"id": "lookup",
"source": "visitor",
"target": "dns",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Resolve domain (visitor to dns) per the request."
}
},
{
"id": "alias",
"source": "dns",
"target": "cdn",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Alias to CDN (dns to cdn) per the request."
}
},
{
"id": "origin",
"source": "cdn",
"target": "bucket",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Fetch files (cdn to bucket) per the request."
}
}
],
"counts": [],
"placement": [
{
"id": "visitor_root",
"component": "visitor",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "aws_root",
"component": "aws",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "dns_in_aws",
"component": "dns",
"relation": "parent",
"group": "aws",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "cdn_in_aws",
"component": "cdn",
"relation": "parent",
"group": "aws",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "bucket_in_aws",
"component": "bucket",
"relation": "parent",
"group": "aws",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
}
],
"allowAdditionalResources": true
}
Download Requirements ↓ Factory IoT telemetry
Draw a left-to-right AWS architecture for factory IoT telemetry. A factory sensor fleet sends readings to AWS IoT Core, which routes them to Kinesis Data Streams. A Lambda consumer normalizes each reading and writes time-series data to Amazon Timestream; it also sends threshold alerts to Amazon SNS. An external operations dashboard reads from Timestream. Show the returned telemetry path from Timestream to the dashboard. Keep the sensor fleet and dashboard outside AWS Cloud, and all AWS services inside AWS Cloud. Use automatic layout and add no other services.Download Prompt ↓
dgm 1
diagram aws-medium-factory-iot-telemetry { grammar aws flow lr title "Factory IoT telemetry"
aws.cloud aws_cloud "AWS Cloud" {
aws.aws-iot-core iot_core "AWS IoT Core" {}
aws.kinesis-data-streams stream "Kinesis Data Streams" {}
aws.aws-lambda normalizer "Normalize readings" {}
aws.timestream timestream "Amazon Timestream" {}
aws.simple-notification-service sns "Amazon SNS" {}
}
cloud-agnostic.client sensor_fleet "Factory sensor fleet" {}
cloud-agnostic.client dashboard "Operations dashboard" {}
sensor_fleet -> iot_core { id sensors_iot label "sensor readings" step 1 }
iot_core -> stream { id iot_stream label "route readings" step 2 }
stream -> normalizer { id stream_lambda label "stream records" step 3 }
normalizer -> timestream { id lambda_timestream label "normalized time-series" step 4 }
normalizer -> sns { id lambda_sns label "threshold alerts" step 4 }
timestream -> dashboard { id timestream_dashboard label "read telemetry" step 5 }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "aws",
"components": [
{
"id": "aws_cloud",
"kind": "group",
"basis": {
"kind": "explicit",
"text": "AWS architecture and AWS services."
},
"type": "aws.cloud"
},
{
"id": "sensor_fleet",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "A factory sensor fleet sends readings into AWS."
},
"type": "cloud-agnostic.client"
},
{
"id": "iot_core",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "AWS IoT Core receives and routes readings."
},
"type": "aws.aws-iot-core"
},
{
"id": "stream",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "Kinesis Data Streams carries readings to a Lambda consumer."
},
"type": "aws.kinesis-data-streams"
},
{
"id": "normalizer",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "The Lambda consumer normalizes each reading."
},
"type": "aws.aws-lambda"
},
{
"id": "timestream",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "Amazon Timestream stores time-series data and serves dashboard reads."
},
"type": "aws.timestream"
},
{
"id": "sns",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "Amazon SNS receives threshold alerts."
},
"type": "aws.simple-notification-service"
},
{
"id": "dashboard",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "An external operations dashboard reads telemetry."
},
"type": "cloud-agnostic.client"
}
],
"relationships": [
{
"id": "sensors_iot",
"source": "sensor_fleet",
"target": "iot_core",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "sensor readings"
}
},
{
"id": "iot_stream",
"source": "iot_core",
"target": "stream",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "route readings"
}
},
{
"id": "stream_lambda",
"source": "stream",
"target": "normalizer",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "consume stream"
}
},
{
"id": "lambda_timestream",
"source": "normalizer",
"target": "timestream",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "normalized time-series"
}
},
{
"id": "lambda_sns",
"source": "normalizer",
"target": "sns",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "threshold alerts"
}
},
{
"id": "timestream_dashboard",
"source": "timestream",
"target": "dashboard",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "returned telemetry"
}
}
],
"counts": [
{
"id": "one_cloud",
"kind": "group",
"type": "aws.cloud",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "All AWS services are inside AWS Cloud."
}
},
{
"id": "one_iot_core",
"kind": "resource",
"type": "aws.aws-iot-core",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "AWS IoT Core"
},
"within": "aws_cloud"
},
{
"id": "one_stream",
"kind": "resource",
"type": "aws.kinesis-data-streams",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "Kinesis Data Streams"
},
"within": "aws_cloud"
},
{
"id": "one_normalizer",
"kind": "resource",
"type": "aws.aws-lambda",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "A Lambda consumer"
},
"within": "aws_cloud"
},
{
"id": "one_timestream",
"kind": "resource",
"type": "aws.timestream",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "Amazon Timestream"
},
"within": "aws_cloud"
},
{
"id": "one_sns",
"kind": "resource",
"type": "aws.simple-notification-service",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "Amazon SNS"
},
"within": "aws_cloud"
},
{
"id": "two_external_actors",
"kind": "resource",
"type": "cloud-agnostic.client",
"min": 2,
"max": 2,
"basis": {
"kind": "explicit",
"text": "A factory sensor fleet and an external operations dashboard."
}
}
],
"placement": [
{
"id": "cloud_root",
"component": "aws_cloud",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "AWS Cloud."
}
},
{
"id": "fleet_external",
"component": "sensor_fleet",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Keep the sensor fleet outside AWS Cloud."
}
},
{
"id": "iot_core_in_cloud",
"component": "iot_core",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "All AWS services are inside AWS Cloud."
},
"group": "aws_cloud"
},
{
"id": "stream_in_cloud",
"component": "stream",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "All AWS services are inside AWS Cloud."
},
"group": "aws_cloud"
},
{
"id": "normalizer_in_cloud",
"component": "normalizer",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "All AWS services are inside AWS Cloud."
},
"group": "aws_cloud"
},
{
"id": "timestream_in_cloud",
"component": "timestream",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "All AWS services are inside AWS Cloud."
},
"group": "aws_cloud"
},
{
"id": "sns_in_cloud",
"component": "sns",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "All AWS services are inside AWS Cloud."
},
"group": "aws_cloud"
},
{
"id": "dashboard_external",
"component": "dashboard",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Keep the dashboard outside AWS Cloud."
}
}
],
"allowAdditionalResources": false
}
Download Requirements ↓ Draw a left-to-right AWS architecture for factory IoT telemetry. A factory sensor fleet sends readings to AWS IoT Core, which routes them to Kinesis Data Streams. A Lambda consumer normalizes each reading and writes time-series data to Amazon Timestream; it also sends threshold alerts to Amazon SNS. An external operations dashboard reads from Timestream. Show the returned telemetry path from Timestream to the dashboard. Keep the sensor fleet and dashboard outside AWS Cloud, and all AWS services inside AWS Cloud. Use automatic layout and add no other services.Download Prompt ↓
dgm 1
diagram aws-medium-factory-iot-telemetry {
grammar aws
flow lr
title "Factory IoT telemetry on AWS"
cloud-agnostic.device sensors "Factory sensor fleet"
aws.cloud aws "AWS Cloud" {
aws.aws-iot-core iot "IoT Core"
aws.kinesis-data-streams stream "Kinesis Data Streams"
aws.aws-lambda consumer "Normalizing consumer"
aws.timestream tsdb "Timestream"
aws.simple-notification-service alerts "Threshold alerts"
}
cloud-agnostic.client dashboard "Operations dashboard"
sensors -> iot { id readings step 1 label "Readings" kind flow }
iot -> stream { id route step 2 label "Route readings" kind flow }
stream -> consumer { id consume step 3 label "Consume" kind flow }
consumer -> tsdb { id write step 4 label "Time-series writes" kind flow }
consumer -> alerts { id alert step 5 label "Threshold alerts" kind flow }
dashboard -> tsdb { id query step 5 label "Read query" kind flow }
tsdb -> dashboard { id telemetry label "Returned telemetry" kind flow style dashed }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "aws",
"components": [
{
"id": "sensors",
"kind": "resource",
"type": "cloud-agnostic.device",
"basis": {
"kind": "explicit",
"text": "Factory sensor fleet sends readings to AWS IoT Core, routed to Kinesis Data Streams; Lambda normalizes to Timestream and sends threshold alerts to SNS; exter..."
}
},
{
"id": "aws",
"kind": "group",
"type": "aws.cloud",
"basis": {
"kind": "explicit",
"text": "Factory sensor fleet sends readings to AWS IoT Core, routed to Kinesis Data Streams; Lambda normalizes to Timestream and sends threshold alerts to SNS; exter..."
}
},
{
"id": "iot",
"kind": "resource",
"type": "aws.aws-iot-core",
"basis": {
"kind": "explicit",
"text": "Factory sensor fleet sends readings to AWS IoT Core, routed to Kinesis Data Streams; Lambda normalizes to Timestream and sends threshold alerts to SNS; exter..."
}
},
{
"id": "stream",
"kind": "resource",
"type": "aws.kinesis-data-streams",
"basis": {
"kind": "explicit",
"text": "Factory sensor fleet sends readings to AWS IoT Core, routed to Kinesis Data Streams; Lambda normalizes to Timestream and sends threshold alerts to SNS; exter..."
}
},
{
"id": "consumer",
"kind": "resource",
"type": "aws.aws-lambda",
"basis": {
"kind": "explicit",
"text": "Factory sensor fleet sends readings to AWS IoT Core, routed to Kinesis Data Streams; Lambda normalizes to Timestream and sends threshold alerts to SNS; exter..."
}
},
{
"id": "tsdb",
"kind": "resource",
"type": "aws.timestream",
"basis": {
"kind": "explicit",
"text": "Factory sensor fleet sends readings to AWS IoT Core, routed to Kinesis Data Streams; Lambda normalizes to Timestream and sends threshold alerts to SNS; exter..."
}
},
{
"id": "alerts",
"kind": "resource",
"type": "aws.simple-notification-service",
"basis": {
"kind": "explicit",
"text": "Factory sensor fleet sends readings to AWS IoT Core, routed to Kinesis Data Streams; Lambda normalizes to Timestream and sends threshold alerts to SNS; exter..."
}
},
{
"id": "dashboard",
"kind": "resource",
"type": "cloud-agnostic.client",
"basis": {
"kind": "explicit",
"text": "Factory sensor fleet sends readings to AWS IoT Core, routed to Kinesis Data Streams; Lambda normalizes to Timestream and sends threshold alerts to SNS; exter..."
}
}
],
"relationships": [
{
"id": "readings",
"source": "sensors",
"target": "iot",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Readings (sensors to iot) per the request."
}
},
{
"id": "route",
"source": "iot",
"target": "stream",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Route readings (iot to stream) per the request."
}
},
{
"id": "consume",
"source": "stream",
"target": "consumer",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Consume (stream to consumer) per the request."
}
},
{
"id": "write",
"source": "consumer",
"target": "tsdb",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Time-series writes (consumer to tsdb) per the request."
}
},
{
"id": "alert",
"source": "consumer",
"target": "alerts",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Threshold alerts (consumer to alerts) per the request."
}
},
{
"id": "query",
"source": "dashboard",
"target": "tsdb",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Read query (dashboard to tsdb) per the request."
}
},
{
"id": "telemetry",
"source": "tsdb",
"target": "dashboard",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Returned telemetry (tsdb to dashboard) per the request."
}
}
],
"counts": [],
"placement": [
{
"id": "sensors_root",
"component": "sensors",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "aws_root",
"component": "aws",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "iot_in_aws",
"component": "iot",
"relation": "parent",
"group": "aws",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "stream_in_aws",
"component": "stream",
"relation": "parent",
"group": "aws",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "consumer_in_aws",
"component": "consumer",
"relation": "parent",
"group": "aws",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "tsdb_in_aws",
"component": "tsdb",
"relation": "parent",
"group": "aws",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "alerts_in_aws",
"component": "alerts",
"relation": "parent",
"group": "aws",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "dashboard_root",
"component": "dashboard",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
}
],
"allowAdditionalResources": false
}
Download Requirements ↓ AWS image thumbnail pipeline
Review note: Strict validation reports 2 routing findings, mostly plain arrow crossings; accepted in review.
Create an AWS image thumbnail pipeline. An uploader submits an image through an API; the upload handler stores the original and queues a thumbnail job; a processor creates a thumbnail; a content delivery service serves both original and thumbnail images.Download Prompt ↓
dgm 1
diagram aws-medium-image-thumbnail-pipeline { grammar aws flow lr title "AWS image thumbnail pipeline"
aws.cloud aws_cloud "AWS Cloud" {
aws.api-gateway api "Upload API" {}
aws.aws-lambda upload_handler "Upload handler" {}
aws.simple-storage-service-bucket assets_bucket "Image assets" {}
aws.simple-queue-service jobs_queue "Thumbnail jobs" {}
aws.aws-lambda processor "Thumbnail processor" {}
aws.cloudfront cdn "Content delivery" {}
}
cloud-agnostic.client uploader "Uploader / viewer" {}
uploader -> api { id uploader_api label "image upload" step 1 }
api -> upload_handler { id api_upload_handler label "upload request" step 2 }
upload_handler -> assets_bucket { id handler_original label "store original" step 3 }
upload_handler -> jobs_queue { id handler_queue label "queue job" step 3 from e to w }
jobs_queue -> processor { id queue_processor label "thumbnail job" step 4 }
processor -> assets_bucket { id processor_thumbnail label "store thumbnail" step 5 from e to w }
cdn -> uploader { id uploader_cdn label "deliver images" step 7 }
assets_bucket -> cdn { id cdn_origin label "serve assets" step 6 from e to w }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "aws",
"components": [
{
"id": "aws_cloud",
"kind": "group",
"basis": {
"kind": "explicit",
"text": "AWS architecture and AWS services."
},
"type": "aws.cloud"
},
{
"id": "uploader",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "An uploader submits an image and receives delivered image assets."
},
"type": "cloud-agnostic.client"
},
{
"id": "api",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "The upload API accepts the image request."
},
"type": "aws.api-gateway"
},
{
"id": "upload_handler",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "The upload handler stores the original and queues a thumbnail job."
},
"type": "aws.aws-lambda"
},
{
"id": "assets_bucket",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "The bucket stores original and thumbnail images."
},
"type": "aws.simple-storage-service-bucket"
},
{
"id": "jobs_queue",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "The thumbnail job queue."
},
"type": "aws.simple-queue-service"
},
{
"id": "processor",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "The processor creates a thumbnail."
},
"type": "aws.aws-lambda"
},
{
"id": "cdn",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "The content delivery service serves both images."
},
"type": "aws.cloudfront"
}
],
"relationships": [
{
"id": "uploader_api",
"source": "uploader",
"target": "api",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "image upload"
}
},
{
"id": "api_upload_handler",
"source": "api",
"target": "upload_handler",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "upload request"
}
},
{
"id": "handler_original",
"source": "upload_handler",
"target": "assets_bucket",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "store original"
}
},
{
"id": "handler_queue",
"source": "upload_handler",
"target": "jobs_queue",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "queue thumbnail job"
}
},
{
"id": "queue_processor",
"source": "jobs_queue",
"target": "processor",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "thumbnail job"
}
},
{
"id": "processor_thumbnail",
"source": "processor",
"target": "assets_bucket",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "store thumbnail"
}
},
{
"id": "uploader_cdn",
"source": "cdn",
"target": "uploader",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "The content delivery service serves original and thumbnail images to the uploader/viewer."
}
},
{
"id": "cdn_origin",
"source": "assets_bucket",
"target": "cdn",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "fetch original or thumbnail"
}
}
],
"counts": [
{
"id": "one_cloud",
"kind": "group",
"type": "aws.cloud",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "AWS image pipeline."
}
},
{
"id": "one_api",
"kind": "resource",
"type": "aws.api-gateway",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "An API"
},
"within": "aws_cloud"
},
{
"id": "one_assets_bucket",
"kind": "resource",
"type": "aws.simple-storage-service-bucket",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "The image bucket"
},
"within": "aws_cloud"
},
{
"id": "one_jobs_queue",
"kind": "resource",
"type": "aws.simple-queue-service",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "A thumbnail job queue"
},
"within": "aws_cloud"
},
{
"id": "one_cdn",
"kind": "resource",
"type": "aws.cloudfront",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "A content delivery service"
},
"within": "aws_cloud"
},
{
"id": "one_uploader",
"kind": "resource",
"type": "cloud-agnostic.client",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "An uploader."
}
},
{
"id": "two_lambda_handlers",
"kind": "resource",
"type": "aws.aws-lambda",
"min": 2,
"max": 2,
"within": "aws_cloud",
"basis": {
"kind": "explicit",
"text": "The upload handler and thumbnail processor."
}
}
],
"placement": [
{
"id": "cloud_root",
"component": "aws_cloud",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "AWS architecture."
}
},
{
"id": "uploader_external",
"component": "uploader",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Uploader is external to AWS."
}
},
{
"id": "api_in_cloud",
"component": "api",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "AWS pipeline service."
},
"group": "aws_cloud"
},
{
"id": "upload_handler_in_cloud",
"component": "upload_handler",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "AWS pipeline service."
},
"group": "aws_cloud"
},
{
"id": "assets_bucket_in_cloud",
"component": "assets_bucket",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "AWS pipeline service."
},
"group": "aws_cloud"
},
{
"id": "jobs_queue_in_cloud",
"component": "jobs_queue",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "AWS pipeline service."
},
"group": "aws_cloud"
},
{
"id": "processor_in_cloud",
"component": "processor",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "AWS pipeline service."
},
"group": "aws_cloud"
},
{
"id": "cdn_in_cloud",
"component": "cdn",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "AWS pipeline service."
},
"group": "aws_cloud"
}
],
"allowAdditionalResources": true
}
Download Requirements ↓ Create an AWS image thumbnail pipeline. An uploader submits an image through an API; the upload handler stores the original and queues a thumbnail job; a processor creates a thumbnail; a content delivery service serves both original and thumbnail images.Download Prompt ↓
dgm 1
diagram aws-medium-image-thumbnail-pipeline {
grammar aws
flow lr
title "AWS image thumbnail pipeline"
cloud-agnostic.client uploader "Uploader"
aws.cloud aws "AWS Cloud" {
aws.cloudfront cdn "CDN"
aws.api-gateway api "Upload API"
aws.aws-lambda handler "Upload handler"
aws.simple-queue-service jobs "Thumbnail jobs"
aws.aws-lambda processor "Thumbnail processor"
aws.simple-storage-service images "Image bucket"
}
uploader -> api { id submit step 1 label "Submit image" kind flow }
api -> handler { id invoke step 2 label "Invoke" kind flow }
handler -> images { id store_original step 3 label "Store original" kind flow }
handler -> jobs { id queue_job step 3 label "Queue job" kind flow }
jobs -> processor { id run_job step 4 label "Thumbnail job" kind flow }
processor -> images { id thumbnail_io step 5 label "Read original, write thumbnail" kind bidirectional }
cdn -> images { id serve step 6 label "Serve original and thumbnail" kind flow }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "aws",
"components": [
{
"id": "uploader",
"kind": "resource",
"type": "cloud-agnostic.client",
"basis": {
"kind": "explicit",
"text": "An uploader submits an image through an API; the upload handler stores the original and queues a thumbnail job; a processor creates a thumbnail; a content de..."
}
},
{
"id": "aws",
"kind": "group",
"type": "aws.cloud",
"basis": {
"kind": "inferred",
"text": "Structurally required to place or group the named resources."
}
},
{
"id": "cdn",
"kind": "resource",
"type": "aws.cloudfront",
"basis": {
"kind": "explicit",
"text": "An uploader submits an image through an API; the upload handler stores the original and queues a thumbnail job; a processor creates a thumbnail; a content de..."
}
},
{
"id": "api",
"kind": "resource",
"type": "aws.api-gateway",
"basis": {
"kind": "explicit",
"text": "An uploader submits an image through an API; the upload handler stores the original and queues a thumbnail job; a processor creates a thumbnail; a content de..."
}
},
{
"id": "handler",
"kind": "resource",
"type": "aws.aws-lambda",
"basis": {
"kind": "explicit",
"text": "An uploader submits an image through an API; the upload handler stores the original and queues a thumbnail job; a processor creates a thumbnail; a content de..."
}
},
{
"id": "jobs",
"kind": "resource",
"type": "aws.simple-queue-service",
"basis": {
"kind": "explicit",
"text": "An uploader submits an image through an API; the upload handler stores the original and queues a thumbnail job; a processor creates a thumbnail; a content de..."
}
},
{
"id": "processor",
"kind": "resource",
"type": "aws.aws-lambda",
"basis": {
"kind": "explicit",
"text": "An uploader submits an image through an API; the upload handler stores the original and queues a thumbnail job; a processor creates a thumbnail; a content de..."
}
},
{
"id": "images",
"kind": "resource",
"type": "aws.simple-storage-service",
"basis": {
"kind": "inferred",
"text": "Structurally required to place or group the named resources."
}
}
],
"relationships": [
{
"id": "submit",
"source": "uploader",
"target": "api",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Submit image (uploader to api) per the request."
}
},
{
"id": "invoke",
"source": "api",
"target": "handler",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Invoke (api to handler) per the request."
}
},
{
"id": "store_original",
"source": "handler",
"target": "images",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Store original (handler to images) per the request."
}
},
{
"id": "queue_job",
"source": "handler",
"target": "jobs",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Queue job (handler to jobs) per the request."
}
},
{
"id": "run_job",
"source": "jobs",
"target": "processor",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Thumbnail job (jobs to processor) per the request."
}
},
{
"id": "thumbnail_io",
"source": "processor",
"target": "images",
"kind": "bidirectional",
"basis": {
"kind": "explicit",
"text": "Read original, write thumbnail (processor to images) per the request."
}
},
{
"id": "serve",
"source": "cdn",
"target": "images",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Serve original and thumbnail (cdn to images) per the request."
}
}
],
"counts": [],
"placement": [
{
"id": "uploader_root",
"component": "uploader",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "aws_root",
"component": "aws",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "cdn_in_aws",
"component": "cdn",
"relation": "parent",
"group": "aws",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "api_in_aws",
"component": "api",
"relation": "parent",
"group": "aws",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "handler_in_aws",
"component": "handler",
"relation": "parent",
"group": "aws",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "jobs_in_aws",
"component": "jobs",
"relation": "parent",
"group": "aws",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "processor_in_aws",
"component": "processor",
"relation": "parent",
"group": "aws",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "images_in_aws",
"component": "images",
"relation": "parent",
"group": "aws",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
}
],
"allowAdditionalResources": true
}
Download Requirements ↓ AWS document processing
Review note: Strict validation reports 15 routing findings, mostly plain arrow crossings; accepted in review.
Create an AWS document processing architecture. A document intake client submits documents through API Gateway to a Lambda intake handler, which stores originals in an input S3 bucket and queues jobs in SQS. The jobs queue is consumed by two Fargate workers in two Availability Zones, each in a private subnet of one VPC. Both workers read input S3, write processed files to output S3, update DynamoDB status, and publish completion to SNS. The client downloads outputs through CloudFront, with request flow client -> CloudFront -> output S3 origin. Failed jobs move to a dead-letter queue after the maximum attempts; an operations user inspects the dead-letter queue and DynamoDB and can redrive messages from the DLQ to the jobs queue. SNS sends completion notifications to operations. Keep clients outside AWS and managed services outside the VPC. Show one cloud, one region, one VPC, two AZs, and one private subnet group per AZ. Add no other services.Download Prompt ↓
dgm 1
diagram aws-hard-document-processing { grammar aws flow lr title "AWS document processing"
aws.cloud aws_cloud "AWS Cloud" {
aws.region primary_region "Region" {
aws.vpc processing_vpc "VPC" {
aws.az az_a "Availability Zone A" {
aws.subnet.private private_subnet_a "Private subnet group A" {
aws.aws-fargate worker_a "Fargate worker A" {}
}
}
aws.az az_b "Availability Zone B" {
aws.subnet.private private_subnet_b "Private subnet group B" {
aws.aws-fargate worker_b "Fargate worker B" {}
}
}
}
aws.api-gateway api_gateway "API Gateway" {}
aws.aws-lambda intake "Intake handler" {}
aws.simple-storage-service-bucket input_s3 "Input S3" {}
aws.simple-queue-service jobs_queue "Jobs queue" {}
aws.simple-queue-service dlq "Dead-letter queue" {}
aws.simple-storage-service-bucket output_s3 "Output S3" {}
aws.dynamodb dynamodb "DynamoDB status" {}
aws.simple-notification-service sns "SNS completion" {}
aws.cloudfront cloudfront "CloudFront" {}
}
}
cloud-agnostic.client client "Document client" {}
cloud-agnostic.client operations "Operations user" {}
client -> api_gateway { id client_api label "submit document" step 1 from e to w }
api_gateway -> intake { id api_intake label "intake request" step 2 from e to w }
intake -> input_s3 { id intake_input label "store original" step 3 from e to w }
intake -> jobs_queue { id intake_jobs label "enqueue job" step 3 from e to w }
jobs_queue -> worker_a { id jobs_worker_a label "consume job" step 4 from e to w }
jobs_queue -> worker_b { id jobs_worker_b label "consume job" step 4 from e to w }
input_s3 -> worker_a { id input_worker_a label "read input" step 4 from e to w }
input_s3 -> worker_b { id input_worker_b label "read input" step 4 from e to w }
worker_a -> output_s3 { id worker_a_output label "write file" step 5 from n to w }
worker_a -> dynamodb { id worker_a_status label "update status" step 5 from n to w }
worker_a -> sns { id worker_a_sns label "publish completion" step 5 from n to w }
worker_b -> output_s3 { id worker_b_output label "write file" step 5 from s to w }
worker_b -> dynamodb { id worker_b_status label "update status" step 5 from s to w }
worker_b -> sns { id worker_b_sns label "publish completion" step 5 from s to w }
client -> cloudfront { id client_cloudfront label "download request" step 1 from e to w }
cloudfront -> output_s3 { id cloudfront_origin label "origin request" step 2 from e to w }
jobs_queue -> dlq { id jobs_dlq label "retry limit" style dashed kind fail from w to e }
operations -> dlq { id ops_dlq label "inspect dead letters" style dashed kind peer from e to w }
operations -> dynamodb { id ops_dynamo label "inspect status" style dashed kind peer from s to s }
operations -> jobs_queue { id ops_redrive label "trigger redrive" style dashed kind peer from s to n }
dlq -> jobs_queue { id dlq_redrive label "redrive messages" style dashed kind peer from e to w }
sns -> operations { id sns_ops label "completion notice" style dashed kind flow from s to s }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "aws",
"components": [
{
"id": "aws_cloud",
"kind": "group",
"basis": {
"kind": "explicit",
"text": "One AWS Cloud contains the AWS architecture."
},
"type": "aws.cloud"
},
{
"id": "primary_region",
"kind": "group",
"basis": {
"kind": "explicit",
"text": "The architecture has one region."
},
"type": "aws.region"
},
{
"id": "processing_vpc",
"kind": "group",
"basis": {
"kind": "explicit",
"text": "The two workers run in one VPC."
},
"type": "aws.vpc"
},
{
"id": "az_a",
"kind": "group",
"basis": {
"kind": "explicit",
"text": "The first worker runs in one Availability Zone."
},
"type": "aws.az"
},
{
"id": "az_b",
"kind": "group",
"basis": {
"kind": "explicit",
"text": "The second worker runs in another Availability Zone."
},
"type": "aws.az"
},
{
"id": "private_subnet_a",
"kind": "group",
"basis": {
"kind": "explicit",
"text": "The first AZ has one private subnet group."
},
"type": "aws.subnet.private"
},
{
"id": "private_subnet_b",
"kind": "group",
"basis": {
"kind": "explicit",
"text": "The second AZ has one private subnet group."
},
"type": "aws.subnet.private"
},
{
"id": "client",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "An external document intake/download client."
},
"type": "cloud-agnostic.client"
},
{
"id": "api_gateway",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "API Gateway accepts document submissions."
},
"type": "aws.api-gateway"
},
{
"id": "intake",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "The intake handler stores originals and queues jobs."
},
"type": "aws.aws-lambda"
},
{
"id": "input_s3",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "Input S3 stores original documents."
},
"type": "aws.simple-storage-service-bucket"
},
{
"id": "jobs_queue",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "The jobs queue feeds workers and receives redriven jobs."
},
"type": "aws.simple-queue-service"
},
{
"id": "worker_a",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "The first Fargate worker runs in the first private subnet."
},
"type": "aws.aws-fargate"
},
{
"id": "worker_b",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "The second Fargate worker runs in the second private subnet."
},
"type": "aws.aws-fargate"
},
{
"id": "output_s3",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "Output S3 stores processed files and serves as the CloudFront origin."
},
"type": "aws.simple-storage-service-bucket"
},
{
"id": "dynamodb",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "DynamoDB stores job status."
},
"type": "aws.dynamodb"
},
{
"id": "sns",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "SNS publishes completion notifications."
},
"type": "aws.simple-notification-service"
},
{
"id": "cloudfront",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "CloudFront serves output downloads from the output S3 origin."
},
"type": "aws.cloudfront"
},
{
"id": "dlq",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "The dead-letter queue receives jobs after maximum attempts."
},
"type": "aws.simple-queue-service"
},
{
"id": "operations",
"kind": "resource",
"basis": {
"kind": "explicit",
"text": "Operations inspects the DLQ and DynamoDB and triggers redrive."
},
"type": "cloud-agnostic.client"
}
],
"relationships": [
{
"id": "client_api",
"source": "client",
"target": "api_gateway",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "document submission"
}
},
{
"id": "api_intake",
"source": "api_gateway",
"target": "intake",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "intake request"
}
},
{
"id": "intake_input",
"source": "intake",
"target": "input_s3",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "store original"
}
},
{
"id": "intake_jobs",
"source": "intake",
"target": "jobs_queue",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "enqueue job"
}
},
{
"id": "jobs_worker_a",
"source": "jobs_queue",
"target": "worker_a",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "consume job"
}
},
{
"id": "jobs_worker_b",
"source": "jobs_queue",
"target": "worker_b",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "consume job"
}
},
{
"id": "input_worker_a",
"source": "input_s3",
"target": "worker_a",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "read input"
}
},
{
"id": "input_worker_b",
"source": "input_s3",
"target": "worker_b",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "read input"
}
},
{
"id": "worker_a_output",
"source": "worker_a",
"target": "output_s3",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "write processed file"
}
},
{
"id": "worker_a_status",
"source": "worker_a",
"target": "dynamodb",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "update status"
}
},
{
"id": "worker_a_sns",
"source": "worker_a",
"target": "sns",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "publish completion"
}
},
{
"id": "worker_b_output",
"source": "worker_b",
"target": "output_s3",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "write processed file"
}
},
{
"id": "worker_b_status",
"source": "worker_b",
"target": "dynamodb",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "update status"
}
},
{
"id": "worker_b_sns",
"source": "worker_b",
"target": "sns",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "publish completion"
}
},
{
"id": "client_cloudfront",
"source": "client",
"target": "cloudfront",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "download request"
}
},
{
"id": "cloudfront_origin",
"source": "cloudfront",
"target": "output_s3",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "origin request"
}
},
{
"id": "jobs_dlq",
"source": "jobs_queue",
"target": "dlq",
"kind": "fail",
"basis": {
"kind": "explicit",
"text": "retry limit exceeded"
}
},
{
"id": "ops_dlq",
"source": "operations",
"target": "dlq",
"kind": "peer",
"basis": {
"kind": "explicit",
"text": "inspect dead letters"
}
},
{
"id": "ops_dynamo",
"source": "operations",
"target": "dynamodb",
"kind": "peer",
"basis": {
"kind": "explicit",
"text": "inspect status"
}
},
{
"id": "ops_redrive",
"source": "operations",
"target": "jobs_queue",
"kind": "peer",
"basis": {
"kind": "explicit",
"text": "Operations can trigger redrive back to the jobs queue."
}
},
{
"id": "dlq_redrive",
"source": "dlq",
"target": "jobs_queue",
"kind": "peer",
"basis": {
"kind": "explicit",
"text": "redrive messages"
}
},
{
"id": "sns_ops",
"source": "sns",
"target": "operations",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "completion notification"
}
}
],
"counts": [
{
"id": "one_cloud",
"kind": "group",
"type": "aws.cloud",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "Show one cloud."
}
},
{
"id": "one_region",
"kind": "group",
"type": "aws.region",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "Show one region."
}
},
{
"id": "one_vpc",
"kind": "group",
"type": "aws.vpc",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "Show one VPC."
}
},
{
"id": "two_azs",
"kind": "group",
"type": "aws.az",
"min": 2,
"max": 2,
"basis": {
"kind": "explicit",
"text": "Workers run in two Availability Zones."
}
},
{
"id": "two_private_subnets",
"kind": "group",
"type": "aws.subnet.private",
"min": 2,
"max": 2,
"basis": {
"kind": "explicit",
"text": "One private subnet group per AZ."
}
},
{
"id": "two_workers",
"kind": "resource",
"type": "aws.aws-fargate",
"min": 2,
"max": 2,
"basis": {
"kind": "explicit",
"text": "Two Fargate workers in two Availability Zones."
},
"within": "processing_vpc"
},
{
"id": "two_buckets",
"kind": "resource",
"type": "aws.simple-storage-service-bucket",
"min": 2,
"max": 2,
"basis": {
"kind": "explicit",
"text": "Input S3 and output S3 buckets."
},
"within": "aws_cloud"
},
{
"id": "two_queues",
"kind": "resource",
"type": "aws.simple-queue-service",
"min": 2,
"max": 2,
"basis": {
"kind": "explicit",
"text": "Jobs queue and dead-letter queue."
},
"within": "aws_cloud"
}
],
"placement": [
{
"id": "cloud_root",
"component": "aws_cloud",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "One cloud."
}
},
{
"id": "region_in_cloud",
"component": "primary_region",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "One region inside the cloud."
},
"group": "aws_cloud"
},
{
"id": "vpc_in_region",
"component": "processing_vpc",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "One VPC in the region."
},
"group": "primary_region"
},
{
"id": "az_a_in_vpc",
"component": "az_a",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "AZ A in the VPC."
},
"group": "processing_vpc"
},
{
"id": "az_b_in_vpc",
"component": "az_b",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "AZ B in the VPC."
},
"group": "processing_vpc"
},
{
"id": "subnet_a_in_az",
"component": "private_subnet_a",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "One private subnet group in AZ A."
},
"group": "az_a"
},
{
"id": "subnet_b_in_az",
"component": "private_subnet_b",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "One private subnet group in AZ B."
},
"group": "az_b"
},
{
"id": "worker_a_in_subnet",
"component": "worker_a",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "Worker A in its private subnet."
},
"group": "private_subnet_a"
},
{
"id": "worker_b_in_subnet",
"component": "worker_b",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "Worker B in its private subnet."
},
"group": "private_subnet_b"
},
{
"id": "client_external",
"component": "client",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Keep clients outside AWS."
}
},
{
"id": "ops_external",
"component": "operations",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Operations user is external to AWS."
}
},
{
"id": "api_gateway_in_region",
"component": "api_gateway",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "Managed AWS service outside the VPC and within the region."
},
"group": "primary_region"
},
{
"id": "intake_in_region",
"component": "intake",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "Managed AWS service outside the VPC and within the region."
},
"group": "primary_region"
},
{
"id": "input_s3_in_region",
"component": "input_s3",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "Managed AWS service outside the VPC and within the region."
},
"group": "primary_region"
},
{
"id": "jobs_queue_in_region",
"component": "jobs_queue",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "Managed AWS service outside the VPC and within the region."
},
"group": "primary_region"
},
{
"id": "output_s3_in_region",
"component": "output_s3",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "Managed AWS service outside the VPC and within the region."
},
"group": "primary_region"
},
{
"id": "dynamodb_in_region",
"component": "dynamodb",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "Managed AWS service outside the VPC and within the region."
},
"group": "primary_region"
},
{
"id": "sns_in_region",
"component": "sns",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "Managed AWS service outside the VPC and within the region."
},
"group": "primary_region"
},
{
"id": "cloudfront_in_region",
"component": "cloudfront",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "Managed AWS service outside the VPC and within the region."
},
"group": "primary_region"
},
{
"id": "dlq_in_region",
"component": "dlq",
"relation": "inside",
"basis": {
"kind": "explicit",
"text": "Managed AWS service outside the VPC and within the region."
},
"group": "primary_region"
}
],
"allowAdditionalResources": false
}
Download Requirements ↓ Review note: Strict validation reports 12 routing findings, mostly plain arrow crossings; accepted in review.
Create an AWS document processing architecture. A document intake client submits documents through API Gateway to a Lambda intake handler, which stores originals in an input S3 bucket and queues jobs in SQS. The jobs queue is consumed by two Fargate workers in two Availability Zones, each in a private subnet of one VPC. Both workers read input S3, write processed files to output S3, update DynamoDB status, and publish completion to SNS. The client downloads outputs through CloudFront, with request flow client -> CloudFront -> output S3 origin. Failed jobs move to a dead-letter queue after the maximum attempts; an operations user inspects the dead-letter queue and DynamoDB and can redrive messages from the DLQ to the jobs queue. SNS sends completion notifications to operations. Keep clients outside AWS and managed services outside the VPC. Show one cloud, one region, one VPC, two AZs, and one private subnet group per AZ. Add no other services.Download Prompt ↓
dgm 1
diagram aws-hard-document-processing {
grammar aws
flow lr
title "AWS document processing"
cloud-agnostic.client client "Document intake client"
cloud-agnostic.actor ops "Operations user"
aws.cloud aws "AWS Cloud" {
aws.region region "AWS Region" {
aws.api-gateway apigw "API Gateway"
aws.aws-lambda intake "Intake handler"
aws.simple-storage-service s3_in "Input bucket"
aws.simple-queue-service jobs "Jobs queue"
aws.simple-queue-service dlq "Dead-letter queue"
aws.vpc vpc "VPC" {
aws.az az1 "Availability Zone 1" {
aws.subnet.private sub1 "Private subnet 1" {
aws.aws-fargate worker1 "Worker 1"
}
}
aws.az az2 "Availability Zone 2" {
aws.subnet.private sub2 "Private subnet 2" {
aws.aws-fargate worker2 "Worker 2"
}
}
}
aws.simple-storage-service s3_out "Output bucket"
aws.dynamodb status "Job status"
aws.simple-notification-service done "Completion topic"
aws.cloudfront cdn "CloudFront"
}
}
client -> apigw { id submit step 1 label "Submit documents" kind flow }
apigw -> intake { id invoke step 2 label "Invoke" kind flow }
intake -> s3_in { id store_input step 3 label "Store originals" kind flow }
intake -> jobs { id queue_job step 3 label "Queue jobs" kind flow }
jobs -> worker1 { id jobs_w1 step 4 label "Jobs" kind flow }
jobs -> worker2 { id jobs_w2 step 4 label "Jobs" kind flow }
s3_in -> worker1 { id read_w1 step 5 label "Read input" kind flow }
s3_in -> worker2 { id read_w2 step 5 label "Read input" kind flow }
worker1 -> s3_out { id out_w1 step 6 label "Write output" kind flow }
worker2 -> s3_out { id out_w2 step 6 label "Write output" kind flow }
worker1 -> status { id status_w1 step 6 label "Update status" kind flow }
worker2 -> status { id status_w2 step 6 label "Update status" kind flow }
worker1 -> done { id done_w1 step 6 label "Publish completion" kind flow }
worker2 -> done { id done_w2 step 6 label "Publish completion" kind flow }
done -> ops { id notify step 7 label "Completion notice" kind flow }
client -> cdn { id download step 1 label "Download" kind flow }
cdn -> s3_out { id origin step 7 label "Origin fetch" kind flow }
jobs -> dlq { id dead_letter label "Max attempts" kind fail }
ops -> dlq { id inspect_dlq label "Inspect" kind peer style dashed }
ops -> status { id inspect_status label "Inspect" kind peer style dashed }
dlq -> jobs { id redrive label "Redrive" kind flow style dashed }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "aws",
"components": [
{
"id": "client",
"kind": "resource",
"type": "cloud-agnostic.client",
"basis": {
"kind": "explicit",
"text": "Client submits via API Gateway to Lambda intake handler -> input S3 and SQS jobs; two Fargate workers in two AZs/private subnets of one VPC read input S3, wr..."
}
},
{
"id": "ops",
"kind": "resource",
"type": "cloud-agnostic.actor",
"basis": {
"kind": "explicit",
"text": "Client submits via API Gateway to Lambda intake handler -> input S3 and SQS jobs; two Fargate workers in two AZs/private subnets of one VPC read input S3, wr..."
}
},
{
"id": "aws",
"kind": "group",
"type": "aws.cloud",
"basis": {
"kind": "explicit",
"text": "Client submits via API Gateway to Lambda intake handler -> input S3 and SQS jobs; two Fargate workers in two AZs/private subnets of one VPC read input S3, wr..."
}
},
{
"id": "region",
"kind": "group",
"type": "aws.region",
"basis": {
"kind": "explicit",
"text": "Client submits via API Gateway to Lambda intake handler -> input S3 and SQS jobs; two Fargate workers in two AZs/private subnets of one VPC read input S3, wr..."
}
},
{
"id": "apigw",
"kind": "resource",
"type": "aws.api-gateway",
"basis": {
"kind": "explicit",
"text": "Client submits via API Gateway to Lambda intake handler -> input S3 and SQS jobs; two Fargate workers in two AZs/private subnets of one VPC read input S3, wr..."
}
},
{
"id": "intake",
"kind": "resource",
"type": "aws.aws-lambda",
"basis": {
"kind": "explicit",
"text": "Client submits via API Gateway to Lambda intake handler -> input S3 and SQS jobs; two Fargate workers in two AZs/private subnets of one VPC read input S3, wr..."
}
},
{
"id": "s3_in",
"kind": "resource",
"type": "aws.simple-storage-service",
"basis": {
"kind": "explicit",
"text": "Client submits via API Gateway to Lambda intake handler -> input S3 and SQS jobs; two Fargate workers in two AZs/private subnets of one VPC read input S3, wr..."
}
},
{
"id": "jobs",
"kind": "resource",
"type": "aws.simple-queue-service",
"basis": {
"kind": "explicit",
"text": "Client submits via API Gateway to Lambda intake handler -> input S3 and SQS jobs; two Fargate workers in two AZs/private subnets of one VPC read input S3, wr..."
}
},
{
"id": "dlq",
"kind": "resource",
"type": "aws.simple-queue-service",
"basis": {
"kind": "explicit",
"text": "Client submits via API Gateway to Lambda intake handler -> input S3 and SQS jobs; two Fargate workers in two AZs/private subnets of one VPC read input S3, wr..."
}
},
{
"id": "vpc",
"kind": "group",
"type": "aws.vpc",
"basis": {
"kind": "explicit",
"text": "Client submits via API Gateway to Lambda intake handler -> input S3 and SQS jobs; two Fargate workers in two AZs/private subnets of one VPC read input S3, wr..."
}
},
{
"id": "az1",
"kind": "group",
"type": "aws.az",
"basis": {
"kind": "explicit",
"text": "Client submits via API Gateway to Lambda intake handler -> input S3 and SQS jobs; two Fargate workers in two AZs/private subnets of one VPC read input S3, wr..."
}
},
{
"id": "sub1",
"kind": "group",
"type": "aws.subnet.private",
"basis": {
"kind": "explicit",
"text": "Client submits via API Gateway to Lambda intake handler -> input S3 and SQS jobs; two Fargate workers in two AZs/private subnets of one VPC read input S3, wr..."
}
},
{
"id": "worker1",
"kind": "resource",
"type": "aws.aws-fargate",
"basis": {
"kind": "explicit",
"text": "Client submits via API Gateway to Lambda intake handler -> input S3 and SQS jobs; two Fargate workers in two AZs/private subnets of one VPC read input S3, wr..."
}
},
{
"id": "az2",
"kind": "group",
"type": "aws.az",
"basis": {
"kind": "explicit",
"text": "Client submits via API Gateway to Lambda intake handler -> input S3 and SQS jobs; two Fargate workers in two AZs/private subnets of one VPC read input S3, wr..."
}
},
{
"id": "sub2",
"kind": "group",
"type": "aws.subnet.private",
"basis": {
"kind": "explicit",
"text": "Client submits via API Gateway to Lambda intake handler -> input S3 and SQS jobs; two Fargate workers in two AZs/private subnets of one VPC read input S3, wr..."
}
},
{
"id": "worker2",
"kind": "resource",
"type": "aws.aws-fargate",
"basis": {
"kind": "explicit",
"text": "Client submits via API Gateway to Lambda intake handler -> input S3 and SQS jobs; two Fargate workers in two AZs/private subnets of one VPC read input S3, wr..."
}
},
{
"id": "s3_out",
"kind": "resource",
"type": "aws.simple-storage-service",
"basis": {
"kind": "explicit",
"text": "Client submits via API Gateway to Lambda intake handler -> input S3 and SQS jobs; two Fargate workers in two AZs/private subnets of one VPC read input S3, wr..."
}
},
{
"id": "status",
"kind": "resource",
"type": "aws.dynamodb",
"basis": {
"kind": "explicit",
"text": "Client submits via API Gateway to Lambda intake handler -> input S3 and SQS jobs; two Fargate workers in two AZs/private subnets of one VPC read input S3, wr..."
}
},
{
"id": "done",
"kind": "resource",
"type": "aws.simple-notification-service",
"basis": {
"kind": "explicit",
"text": "Client submits via API Gateway to Lambda intake handler -> input S3 and SQS jobs; two Fargate workers in two AZs/private subnets of one VPC read input S3, wr..."
}
},
{
"id": "cdn",
"kind": "resource",
"type": "aws.cloudfront",
"basis": {
"kind": "explicit",
"text": "Client submits via API Gateway to Lambda intake handler -> input S3 and SQS jobs; two Fargate workers in two AZs/private subnets of one VPC read input S3, wr..."
}
}
],
"relationships": [
{
"id": "submit",
"source": "client",
"target": "apigw",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Submit documents (client to apigw) per the request."
}
},
{
"id": "invoke",
"source": "apigw",
"target": "intake",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Invoke (apigw to intake) per the request."
}
},
{
"id": "store_input",
"source": "intake",
"target": "s3_in",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Store originals (intake to s3_in) per the request."
}
},
{
"id": "queue_job",
"source": "intake",
"target": "jobs",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Queue jobs (intake to jobs) per the request."
}
},
{
"id": "jobs_w1",
"source": "jobs",
"target": "worker1",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Jobs (jobs to worker1) per the request."
}
},
{
"id": "jobs_w2",
"source": "jobs",
"target": "worker2",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Jobs (jobs to worker2) per the request."
}
},
{
"id": "read_w1",
"source": "s3_in",
"target": "worker1",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Read input (s3_in to worker1) per the request."
}
},
{
"id": "read_w2",
"source": "s3_in",
"target": "worker2",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Read input (s3_in to worker2) per the request."
}
},
{
"id": "out_w1",
"source": "worker1",
"target": "s3_out",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Write output (worker1 to s3_out) per the request."
}
},
{
"id": "out_w2",
"source": "worker2",
"target": "s3_out",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Write output (worker2 to s3_out) per the request."
}
},
{
"id": "status_w1",
"source": "worker1",
"target": "status",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Update status (worker1 to status) per the request."
}
},
{
"id": "status_w2",
"source": "worker2",
"target": "status",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Update status (worker2 to status) per the request."
}
},
{
"id": "done_w1",
"source": "worker1",
"target": "done",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Publish completion (worker1 to done) per the request."
}
},
{
"id": "done_w2",
"source": "worker2",
"target": "done",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Publish completion (worker2 to done) per the request."
}
},
{
"id": "notify",
"source": "done",
"target": "ops",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Completion notice (done to ops) per the request."
}
},
{
"id": "download",
"source": "client",
"target": "cdn",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Download (client to cdn) per the request."
}
},
{
"id": "origin",
"source": "cdn",
"target": "s3_out",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Origin fetch (cdn to s3_out) per the request."
}
},
{
"id": "dead_letter",
"source": "jobs",
"target": "dlq",
"kind": "fail",
"basis": {
"kind": "explicit",
"text": "Max attempts (jobs to dlq) per the request."
}
},
{
"id": "inspect_dlq",
"source": "ops",
"target": "dlq",
"kind": "peer",
"basis": {
"kind": "explicit",
"text": "Inspect (ops to dlq) per the request."
}
},
{
"id": "inspect_status",
"source": "ops",
"target": "status",
"kind": "peer",
"basis": {
"kind": "explicit",
"text": "Inspect (ops to status) per the request."
}
},
{
"id": "redrive",
"source": "dlq",
"target": "jobs",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Redrive (dlq to jobs) per the request."
}
}
],
"counts": [
{
"id": "workers",
"kind": "resource",
"type": "aws.aws-fargate",
"min": 2,
"max": 2,
"within": "vpc",
"basis": {
"kind": "explicit",
"text": "Two workers requested."
}
}
],
"placement": [
{
"id": "client_root",
"component": "client",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "ops_root",
"component": "ops",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "aws_root",
"component": "aws",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "region_in_aws",
"component": "region",
"relation": "parent",
"group": "aws",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "apigw_in_region",
"component": "apigw",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "intake_in_region",
"component": "intake",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "s3_in_in_region",
"component": "s3_in",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "jobs_in_region",
"component": "jobs",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "dlq_in_region",
"component": "dlq",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "vpc_in_region",
"component": "vpc",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "az1_in_vpc",
"component": "az1",
"relation": "parent",
"group": "vpc",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "sub1_in_az1",
"component": "sub1",
"relation": "parent",
"group": "az1",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "worker1_in_sub1",
"component": "worker1",
"relation": "parent",
"group": "sub1",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "az2_in_vpc",
"component": "az2",
"relation": "parent",
"group": "vpc",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "sub2_in_az2",
"component": "sub2",
"relation": "parent",
"group": "az2",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "worker2_in_sub2",
"component": "worker2",
"relation": "parent",
"group": "sub2",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "s3_out_in_region",
"component": "s3_out",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "status_in_region",
"component": "status",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "done_in_region",
"component": "done",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "cdn_in_region",
"component": "cdn",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "apigw_outside_vpc",
"component": "apigw",
"relation": "outside",
"group": "vpc",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
},
{
"id": "intake_outside_vpc",
"component": "intake",
"relation": "outside",
"group": "vpc",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
},
{
"id": "s3_in_outside_vpc",
"component": "s3_in",
"relation": "outside",
"group": "vpc",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
},
{
"id": "jobs_outside_vpc",
"component": "jobs",
"relation": "outside",
"group": "vpc",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
},
{
"id": "dlq_outside_vpc",
"component": "dlq",
"relation": "outside",
"group": "vpc",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
},
{
"id": "s3_out_outside_vpc",
"component": "s3_out",
"relation": "outside",
"group": "vpc",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
},
{
"id": "status_outside_vpc",
"component": "status",
"relation": "outside",
"group": "vpc",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
},
{
"id": "done_outside_vpc",
"component": "done",
"relation": "outside",
"group": "vpc",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
},
{
"id": "cdn_outside_vpc",
"component": "cdn",
"relation": "outside",
"group": "vpc",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
}
],
"allowAdditionalResources": false
}
Download Requirements ↓ Azure
Azure Private Application API
Create a simple Azure private application API. A client calls API Management, which routes requests to an Azure Function; the function accesses an Azure SQL database through a private endpoint in the application network.Download Prompt ↓
dgm 1
diagram azure_easy_private_application_api {
grammar azure
flow lr
title "Azure Private Application API"
azure.subscription subscription "Azure subscription" {
azure.region region "Region" {
azure.resource-group resource_group "Application resource group" {
azure.api-management-services api_management "API Management" {}
azure.sql-database sql_database "SQL Database" {}
azure.vnet app_vnet "Application network" {
azure.subnet app_subnet "Application subnet" {
azure.function-apps function_app "Function App" {}
}
azure.subnet data_subnet "Private endpoint subnet" {
azure.private-endpoints sql_private_endpoint "SQL private endpoint" {}
}
}
}
}
}
cloud-agnostic.client client "Client" {}
client -> api_management {
id client_to_apim
label "API request"
step 1
}
api_management -> function_app {
id apim_to_function
label "Route request"
step 2
}
function_app -> sql_private_endpoint {
id function_to_sql_endpoint
label "SQL read/write"
step 3
}
sql_private_endpoint -> sql_database {
id endpoint_to_sql
label "Private endpoint to SQL"
step 4
}
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "azure",
"components": [
{ "id": "subscription", "kind": "group", "type": "azure.subscription", "basis": { "kind": "inferred", "text": "Azure scope boundary for the resources." } },
{ "id": "region", "kind": "group", "type": "azure.region", "basis": { "kind": "inferred", "text": "Azure scope boundary for the resources; no region was named." } },
{ "id": "resource_group", "kind": "group", "type": "azure.resource-group", "basis": { "kind": "inferred", "text": "A resource group scopes the application and network resources." } },
{ "id": "app_vnet", "kind": "group", "type": "azure.vnet", "basis": { "kind": "explicit", "text": "private endpoint in the application network" } },
{ "id": "app_subnet", "kind": "group", "type": "azure.subnet", "basis": { "kind": "inferred", "text": "Application subnet for the private Function App placement." } },
{ "id": "data_subnet", "kind": "group", "type": "azure.subnet", "basis": { "kind": "inferred", "text": "A subnet is required to place the private endpoint in the VNet." } },
{ "id": "client", "kind": "resource", "type": "cloud-agnostic.client", "basis": { "kind": "explicit", "text": "A client calls API Management." } },
{ "id": "api_management", "kind": "resource", "type": "azure.api-management-services", "basis": { "kind": "explicit", "text": "API Management" } },
{ "id": "function_app", "kind": "resource", "type": "azure.function-apps", "basis": { "kind": "explicit", "text": "an Azure Function" } },
{ "id": "sql_private_endpoint", "kind": "resource", "type": "azure.private-endpoints", "basis": { "kind": "explicit", "text": "through a private endpoint in the application network" } },
{ "id": "sql_database", "kind": "resource", "type": "azure.sql-database", "basis": { "kind": "explicit", "text": "an Azure SQL database" } }
],
"relationships": [
{ "id": "client_to_apim", "source": "client", "target": "api_management", "kind": "flow", "basis": { "kind": "explicit", "text": "A client calls API Management." } },
{ "id": "apim_to_function", "source": "api_management", "target": "function_app", "kind": "flow", "basis": { "kind": "explicit", "text": "API Management routes requests to an Azure Function." } },
{ "id": "function_to_sql_endpoint", "source": "function_app", "target": "sql_private_endpoint", "kind": "flow", "basis": { "kind": "explicit", "text": "The function accesses SQL through a private endpoint." } },
{ "id": "endpoint_to_sql", "source": "sql_private_endpoint", "target": "sql_database", "kind": "flow", "basis": { "kind": "explicit", "text": "The private endpoint provides the route to Azure SQL." } }
],
"counts": [
{ "id": "one_subscription", "kind": "group", "type": "azure.subscription", "min": 1, "max": 1, "basis": { "kind": "inferred", "text": "One Azure scope for this simple architecture." } },
{ "id": "one_region", "kind": "group", "type": "azure.region", "min": 1, "max": 1, "within": "subscription", "basis": { "kind": "inferred", "text": "One region; none was specified." } },
{ "id": "one_resource_group", "kind": "group", "type": "azure.resource-group", "min": 1, "max": 1, "within": "region", "basis": { "kind": "inferred", "text": "One group scopes the application resources." } },
{ "id": "one_vnet", "kind": "group", "type": "azure.vnet", "min": 1, "max": 1, "within": "resource_group", "basis": { "kind": "explicit", "text": "one application network" } },
{ "id": "two_subnets", "kind": "group", "type": "azure.subnet", "min": 2, "max": 2, "within": "app_vnet", "basis": { "kind": "inferred", "text": "Application and private-endpoint subnets make placement readable." } },
{ "id": "one_client", "kind": "resource", "type": "cloud-agnostic.client", "min": 1, "max": 1, "basis": { "kind": "explicit", "text": "A client." } },
{ "id": "one_api_management", "kind": "resource", "type": "azure.api-management-services", "min": 1, "max": 1, "within": "resource_group", "basis": { "kind": "explicit", "text": "API Management" } },
{ "id": "one_function_app", "kind": "resource", "type": "azure.function-apps", "min": 1, "max": 1, "within": "resource_group", "basis": { "kind": "explicit", "text": "an Azure Function" } },
{ "id": "one_sql_private_endpoint", "kind": "resource", "type": "azure.private-endpoints", "min": 1, "max": 1, "within": "resource_group", "basis": { "kind": "explicit", "text": "a private endpoint" } },
{ "id": "one_sql_database", "kind": "resource", "type": "azure.sql-database", "min": 1, "max": 1, "within": "resource_group", "basis": { "kind": "explicit", "text": "an Azure SQL database" } }
],
"placement": [
{ "id": "region_under_subscription", "component": "region", "relation": "parent", "group": "subscription", "basis": { "kind": "inferred", "text": "Azure region nested under subscription." } },
{ "id": "resource_group_in_region", "component": "resource_group", "relation": "parent", "group": "region", "basis": { "kind": "inferred", "text": "Resource group nested under the region." } },
{ "id": "vnet_in_resource_group", "component": "app_vnet", "relation": "parent", "group": "resource_group", "basis": { "kind": "explicit", "text": "The application network contains the private endpoint." } },
{ "id": "app_subnet_in_vnet", "component": "app_subnet", "relation": "parent", "group": "app_vnet", "basis": { "kind": "inferred", "text": "Application subnet within the VNet." } },
{ "id": "data_subnet_in_vnet", "component": "data_subnet", "relation": "parent", "group": "app_vnet", "basis": { "kind": "inferred", "text": "Private-endpoint subnet within the VNet." } },
{ "id": "client_root", "component": "client", "relation": "root", "basis": { "kind": "explicit", "text": "Client actor outside the Azure resource scope." } },
{ "id": "apim_in_resource_group", "component": "api_management", "relation": "inside", "group": "resource_group", "basis": { "kind": "explicit", "text": "API Management is an Azure resource in the scoped resource group." } },
{ "id": "apim_outside_vnet", "component": "api_management", "relation": "outside", "group": "app_vnet", "basis": { "kind": "inferred", "text": "Place the client-facing API entry point outside the application VNet." } },
{ "id": "function_in_app_subnet", "component": "function_app", "relation": "inside", "group": "app_subnet", "basis": { "kind": "inferred", "text": "The private application Function uses the application subnet." } },
{ "id": "endpoint_in_data_subnet", "component": "sql_private_endpoint", "relation": "inside", "group": "data_subnet", "basis": { "kind": "explicit", "text": "Private endpoint in the application network." } },
{ "id": "sql_in_resource_group", "component": "sql_database", "relation": "inside", "group": "resource_group", "basis": { "kind": "explicit", "text": "Azure SQL resource in the same application scope." } },
{ "id": "sql_outside_vnet", "component": "sql_database", "relation": "outside", "group": "app_vnet", "basis": { "kind": "inferred", "text": "The Private Endpoint connects the VNet to the managed SQL service." } }
]
}
Download Requirements ↓ Create a simple Azure private application API. A client calls API Management, which routes requests to an Azure Function; the function accesses an Azure SQL database through a private endpoint in the application network.Download Prompt ↓
dgm 1
diagram azure-easy-private-application-api {
grammar azure
flow lr
title "Azure private application API"
cloud-agnostic.client client "Client"
azure.subscription sub "Azure subscription" {
azure.region region "Azure region" {
azure.api-management-services apim "API Management"
azure.function-apps func "Function"
azure.vnet vnet "Application network" {
azure.private-endpoints sql_pe "SQL private endpoint"
}
azure.sql-database sql "Azure SQL"
}
}
client -> apim { id call step 1 label "HTTPS" kind flow }
apim -> func { id route step 2 label "Route" kind flow }
func -> sql_pe { id access step 3 label "Private access" kind flow }
sql_pe -> sql { id link step 4 label "Private link" kind flow }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "azure",
"components": [
{
"id": "client",
"kind": "resource",
"type": "cloud-agnostic.client",
"basis": {
"kind": "explicit",
"text": "A client calls API Management, which routes to an Azure Function; the function accesses an Azure SQL database through a private endpoint in the application n..."
}
},
{
"id": "sub",
"kind": "group",
"type": "azure.subscription",
"basis": {
"kind": "inferred",
"text": "Structurally required to place or group the named resources."
}
},
{
"id": "region",
"kind": "group",
"type": "azure.region",
"basis": {
"kind": "inferred",
"text": "Structurally required to place or group the named resources."
}
},
{
"id": "apim",
"kind": "resource",
"type": "azure.api-management-services",
"basis": {
"kind": "explicit",
"text": "A client calls API Management, which routes to an Azure Function; the function accesses an Azure SQL database through a private endpoint in the application n..."
}
},
{
"id": "func",
"kind": "resource",
"type": "azure.function-apps",
"basis": {
"kind": "explicit",
"text": "A client calls API Management, which routes to an Azure Function; the function accesses an Azure SQL database through a private endpoint in the application n..."
}
},
{
"id": "vnet",
"kind": "group",
"type": "azure.vnet",
"basis": {
"kind": "explicit",
"text": "A client calls API Management, which routes to an Azure Function; the function accesses an Azure SQL database through a private endpoint in the application n..."
}
},
{
"id": "sql_pe",
"kind": "resource",
"type": "azure.private-endpoints",
"basis": {
"kind": "explicit",
"text": "A client calls API Management, which routes to an Azure Function; the function accesses an Azure SQL database through a private endpoint in the application n..."
}
},
{
"id": "sql",
"kind": "resource",
"type": "azure.sql-database",
"basis": {
"kind": "explicit",
"text": "A client calls API Management, which routes to an Azure Function; the function accesses an Azure SQL database through a private endpoint in the application n..."
}
}
],
"relationships": [
{
"id": "call",
"source": "client",
"target": "apim",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "HTTPS (client to apim) per the request."
}
},
{
"id": "route",
"source": "apim",
"target": "func",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Route (apim to func) per the request."
}
},
{
"id": "access",
"source": "func",
"target": "sql_pe",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Private access (func to sql_pe) per the request."
}
},
{
"id": "link",
"source": "sql_pe",
"target": "sql",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Private link (sql_pe to sql) per the request."
}
}
],
"counts": [],
"placement": [
{
"id": "client_root",
"component": "client",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "sub_root",
"component": "sub",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "region_in_sub",
"component": "region",
"relation": "parent",
"group": "sub",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "apim_in_region",
"component": "apim",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "func_in_region",
"component": "func",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "vnet_in_region",
"component": "vnet",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "sql_pe_in_vnet",
"component": "sql_pe",
"relation": "parent",
"group": "vnet",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "sql_in_region",
"component": "sql",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
}
],
"allowAdditionalResources": true
}
Download Requirements ↓ Asynchronous Order Processing
Create an Azure asynchronous order processing diagram. A storefront submits orders through an API; an intake function validates each order, queues it for processing, and archives the request. A processor consumes queued orders and archive events, saves completed orders in SQL, and sends processing metrics to Azure Monitor.Download Prompt ↓
dgm 1
diagram azure_order_processing {
grammar azure
flow lr
title "Asynchronous Order Processing"
cloud-agnostic.client storefront "Storefront"
azure.subscription subscription "Azure Subscription" {
azure.region region "Region" {
azure.api-management-services api "Order API"
azure.function-apps intake "Order Intake"
azure.azure-service-bus queue "Order Queue"
azure.storage-accounts archive "Request Archive"
azure.event-grid-subscriptions archive_events "Archive Events"
azure.function-apps processor "Order Processor"
azure.sql-database orders_db "Orders SQL"
azure.monitor monitor "Azure Monitor"
}
}
storefront -> api { id submit_order label "Submit order" step 1 }
api -> intake { id api_to_intake label "Order request" step 2 }
intake -> queue { id queue_order label "Validated order" step 3 }
intake -> archive { id archive_request label "Archive request" step 3 }
archive -> archive_events { id publish_archive_event label "Archive event" step 4 }
queue -> processor { id deliver_queued_order label "Queued order" step 4 }
archive_events -> processor { id deliver_archive_event label "Archive event" step 5 }
processor -> orders_db { id save_order label "Save completed order" step 6 }
processor -> monitor { id send_metrics label "Processing metrics" style dashed }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "azure",
"components": [
{
"id": "storefront",
"kind": "resource",
"type": "cloud-agnostic.client",
"basis": {
"kind": "explicit",
"text": "storefront submits orders"
}
},
{
"id": "subscription",
"kind": "group",
"type": "azure.subscription",
"basis": {
"kind": "inferred",
"text": "Azure resources need subscription scope"
}
},
{
"id": "region",
"kind": "group",
"type": "azure.region",
"basis": {
"kind": "inferred",
"text": "Azure subscription contains a region per provider conventions"
}
},
{
"id": "api",
"kind": "resource",
"type": "azure.api-management-services",
"basis": {
"kind": "inferred",
"text": "Azure API Management represents the generic API ingress"
}
},
{
"id": "intake",
"kind": "resource",
"type": "azure.function-apps",
"basis": {
"kind": "explicit",
"text": "an intake function validates each order"
}
},
{
"id": "queue",
"kind": "resource",
"type": "azure.azure-service-bus",
"basis": {
"kind": "explicit",
"text": "queues it for processing"
}
},
{
"id": "archive",
"kind": "resource",
"type": "azure.storage-accounts",
"basis": {
"kind": "inferred",
"text": "Storage Account is the archive destination"
}
},
{
"id": "archive_events",
"kind": "resource",
"type": "azure.event-grid-subscriptions",
"basis": {
"kind": "inferred",
"text": "Event Grid subscription delivers archive events to the processor"
}
},
{
"id": "processor",
"kind": "resource",
"type": "azure.function-apps",
"basis": {
"kind": "inferred",
"text": "a distinct Function App represents the processor role"
}
},
{
"id": "orders_db",
"kind": "resource",
"type": "azure.sql-database",
"basis": {
"kind": "explicit",
"text": "saves completed orders in SQL"
}
},
{
"id": "monitor",
"kind": "resource",
"type": "azure.monitor",
"basis": {
"kind": "explicit",
"text": "sends processing metrics to Azure Monitor"
}
}
],
"relationships": [
{
"id": "submit_order",
"source": "storefront",
"target": "api",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "storefront submits orders through an API"
}
},
{
"id": "api_to_intake",
"source": "api",
"target": "intake",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "orders pass from API to intake function"
}
},
{
"id": "queue_order",
"source": "intake",
"target": "queue",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "intake queues each order for processing"
}
},
{
"id": "archive_request",
"source": "intake",
"target": "archive",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "intake archives the request"
}
},
{
"id": "publish_archive_event",
"source": "archive",
"target": "archive_events",
"kind": "flow",
"basis": {
"kind": "inferred",
"text": "Event Grid carries archive-generated events to the processor."
}
},
{
"id": "deliver_archive_event",
"source": "archive_events",
"target": "processor",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "processor consumes archive events"
}
},
{
"id": "deliver_queued_order",
"source": "queue",
"target": "processor",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "processor consumes queued orders"
}
},
{
"id": "save_order",
"source": "processor",
"target": "orders_db",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "saves completed orders in SQL"
}
},
{
"id": "send_metrics",
"source": "processor",
"target": "monitor",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "sends processing metrics to Azure Monitor"
}
}
],
"counts": [
{
"id": "one_storefront",
"kind": "resource",
"type": "cloud-agnostic.client",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "the storefront"
}
},
{
"id": "one_subscription",
"kind": "group",
"type": "azure.subscription",
"min": 1,
"max": 1,
"basis": {
"kind": "inferred",
"text": "provider-required Azure subscription scope"
}
},
{
"id": "one_region",
"kind": "group",
"type": "azure.region",
"min": 1,
"max": 1,
"within": "subscription",
"basis": {
"kind": "inferred",
"text": "one region to contain the Azure resources"
}
},
{
"id": "one_api",
"kind": "resource",
"type": "azure.api-management-services",
"min": 1,
"max": 1,
"within": "region",
"basis": {
"kind": "inferred",
"text": "one API ingress component"
}
},
{
"id": "one_queue",
"kind": "resource",
"type": "azure.azure-service-bus",
"min": 1,
"max": 1,
"within": "region",
"basis": {
"kind": "explicit",
"text": "the processing queue"
}
},
{
"id": "one_archive",
"kind": "resource",
"type": "azure.storage-accounts",
"min": 1,
"max": 1,
"within": "region",
"basis": {
"kind": "inferred",
"text": "one archive storage destination"
}
},
{
"id": "one_event_subscription",
"kind": "resource",
"type": "azure.event-grid-subscriptions",
"min": 1,
"max": 1,
"within": "region",
"basis": {
"kind": "inferred",
"text": "one archive event delivery subscription"
}
},
{
"id": "two_functions",
"kind": "resource",
"type": "azure.function-apps",
"min": 2,
"max": 2,
"within": "region",
"basis": {
"kind": "inferred",
"text": "One Function App represents intake and a second represents the distinct processor role."
}
},
{
"id": "one_sql",
"kind": "resource",
"type": "azure.sql-database",
"min": 1,
"max": 1,
"within": "region",
"basis": {
"kind": "explicit",
"text": "SQL"
}
},
{
"id": "one_monitor",
"kind": "resource",
"type": "azure.monitor",
"min": 1,
"max": 1,
"within": "region",
"basis": {
"kind": "explicit",
"text": "Azure Monitor"
}
}
],
"placement": [
{
"id": "storefront_root",
"component": "storefront",
"relation": "root",
"basis": {
"kind": "inferred",
"text": "storefront is an external actor outside Azure scope"
}
},
{
"id": "region_in_subscription",
"component": "region",
"relation": "inside",
"group": "subscription",
"basis": {
"kind": "inferred",
"text": "Azure subscription contains a region"
}
},
{
"id": "api_in_region",
"component": "api",
"relation": "inside",
"group": "region",
"basis": {
"kind": "inferred",
"text": "API ingress is an Azure resource"
}
},
{
"id": "intake_in_region",
"component": "intake",
"relation": "inside",
"group": "region",
"basis": {
"kind": "explicit",
"text": "intake function is part of the Azure system"
}
},
{
"id": "queue_in_region",
"component": "queue",
"relation": "inside",
"group": "region",
"basis": {
"kind": "explicit",
"text": "processing queue is part of the Azure system"
}
},
{
"id": "archive_in_region",
"component": "archive",
"relation": "inside",
"group": "region",
"basis": {
"kind": "inferred",
"text": "archive storage is an Azure resource"
}
},
{
"id": "events_in_region",
"component": "archive_events",
"relation": "inside",
"group": "region",
"basis": {
"kind": "inferred",
"text": "Event Grid subscription is an Azure resource"
}
},
{
"id": "processor_in_region",
"component": "processor",
"relation": "inside",
"group": "region",
"basis": {
"kind": "explicit",
"text": "processor is part of the Azure system"
}
},
{
"id": "sql_in_region",
"component": "orders_db",
"relation": "inside",
"group": "region",
"basis": {
"kind": "explicit",
"text": "SQL database is part of the Azure system"
}
},
{
"id": "monitor_in_region",
"component": "monitor",
"relation": "inside",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Azure Monitor is part of the Azure system"
}
}
]
}
Download Requirements ↓ Create an Azure asynchronous order processing diagram. A storefront submits orders through an API; an intake function validates each order, queues it for processing, and archives the request. A processor consumes queued orders and archive events, saves completed orders in SQL, and sends processing metrics to Azure Monitor.Download Prompt ↓
dgm 1
diagram azure-medium-asynchronous-order-processing {
grammar azure
flow lr
title "Azure asynchronous order processing"
cloud-agnostic.client storefront "Storefront"
azure.subscription sub "Azure subscription" {
azure.region region "Azure region" {
azure.api-management-services api "Order API"
azure.function-apps intake "Intake function"
azure.storage-queue queue "Order queue"
azure.storage-accounts archive "Request archive"
azure.function-apps processor "Processor"
azure.sql-database sql "Orders SQL"
azure.monitor monitor "Azure Monitor"
}
}
storefront -> api { id submit step 1 label "Submit order" kind flow }
api -> intake { id invoke step 2 label "Validate" kind flow }
intake -> queue { id enqueue step 3 label "Queue order" kind flow }
intake -> archive { id archive_req step 3 label "Archive request" kind flow }
queue -> processor { id consume_orders step 4 label "Queued orders" kind flow }
archive -> processor { id archive_events step 4 label "Archive events" kind flow }
processor -> sql { id save step 5 label "Save orders" kind flow }
processor -> monitor { id metrics step 5 label "Metrics" kind flow }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "azure",
"components": [
{
"id": "storefront",
"kind": "resource",
"type": "cloud-agnostic.client",
"basis": {
"kind": "explicit",
"text": "A storefront submits orders through an API; an intake function validates, queues, and archives the request. A processor consumes queued orders and archive ev..."
}
},
{
"id": "sub",
"kind": "group",
"type": "azure.subscription",
"basis": {
"kind": "inferred",
"text": "Structurally required to place or group the named resources."
}
},
{
"id": "region",
"kind": "group",
"type": "azure.region",
"basis": {
"kind": "inferred",
"text": "Structurally required to place or group the named resources."
}
},
{
"id": "api",
"kind": "resource",
"type": "azure.api-management-services",
"basis": {
"kind": "explicit",
"text": "A storefront submits orders through an API; an intake function validates, queues, and archives the request. A processor consumes queued orders and archive ev..."
}
},
{
"id": "intake",
"kind": "resource",
"type": "azure.function-apps",
"basis": {
"kind": "explicit",
"text": "A storefront submits orders through an API; an intake function validates, queues, and archives the request. A processor consumes queued orders and archive ev..."
}
},
{
"id": "queue",
"kind": "resource",
"type": "azure.storage-queue",
"basis": {
"kind": "inferred",
"text": "Structurally required to place or group the named resources."
}
},
{
"id": "archive",
"kind": "resource",
"type": "azure.storage-accounts",
"basis": {
"kind": "inferred",
"text": "Structurally required to place or group the named resources."
}
},
{
"id": "processor",
"kind": "resource",
"type": "azure.function-apps",
"basis": {
"kind": "explicit",
"text": "A storefront submits orders through an API; an intake function validates, queues, and archives the request. A processor consumes queued orders and archive ev..."
}
},
{
"id": "sql",
"kind": "resource",
"type": "azure.sql-database",
"basis": {
"kind": "explicit",
"text": "A storefront submits orders through an API; an intake function validates, queues, and archives the request. A processor consumes queued orders and archive ev..."
}
},
{
"id": "monitor",
"kind": "resource",
"type": "azure.monitor",
"basis": {
"kind": "explicit",
"text": "A storefront submits orders through an API; an intake function validates, queues, and archives the request. A processor consumes queued orders and archive ev..."
}
}
],
"relationships": [
{
"id": "submit",
"source": "storefront",
"target": "api",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Submit order (storefront to api) per the request."
}
},
{
"id": "invoke",
"source": "api",
"target": "intake",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Validate (api to intake) per the request."
}
},
{
"id": "enqueue",
"source": "intake",
"target": "queue",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Queue order (intake to queue) per the request."
}
},
{
"id": "archive_req",
"source": "intake",
"target": "archive",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Archive request (intake to archive) per the request."
}
},
{
"id": "consume_orders",
"source": "queue",
"target": "processor",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Queued orders (queue to processor) per the request."
}
},
{
"id": "archive_events",
"source": "archive",
"target": "processor",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Archive events (archive to processor) per the request."
}
},
{
"id": "save",
"source": "processor",
"target": "sql",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Save orders (processor to sql) per the request."
}
},
{
"id": "metrics",
"source": "processor",
"target": "monitor",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Metrics (processor to monitor) per the request."
}
}
],
"counts": [],
"placement": [
{
"id": "storefront_root",
"component": "storefront",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "sub_root",
"component": "sub",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "region_in_sub",
"component": "region",
"relation": "parent",
"group": "sub",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "api_in_region",
"component": "api",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "intake_in_region",
"component": "intake",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "queue_in_region",
"component": "queue",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "archive_in_region",
"component": "archive",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "processor_in_region",
"component": "processor",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "sql_in_region",
"component": "sql",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "monitor_in_region",
"component": "monitor",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
}
],
"allowAdditionalResources": true
}
Download Requirements ↓ Industrial IoT telemetry
Create a left-to-right Azure IoT telemetry architecture. An industrial sensor fleet sends readings to Azure IoT Hub. IoT Hub routes readings to Event Hubs for processing and to a Storage Account for a raw archive. An Azure Function App consumes the event stream, normalizes readings, and writes current equipment status to Cosmos DB. An external operations dashboard reads the current status. Nest Azure resources in a subscription, region, and resource group. Add no other services and use automatic routing.Download Prompt ↓
dgm 1
diagram azure-industrial-iot-telemetry {
grammar azure
flow lr
title "Industrial IoT telemetry"
cloud-agnostic.device sensor_fleet "Industrial sensor fleet" {}
azure.subscription subscription "Azure subscription" {
azure.region region "Azure region" {
azure.resource-group resource_group "Telemetry resource group" {
azure.iot-hub iot_hub "IoT Hub" {}
azure.event-hubs event_hubs "Event Hubs" {}
azure.storage-accounts raw_archive "Raw telemetry archive" {}
azure.function-apps normalizer "Reading normalizer" {}
azure.azure-cosmos-db status_db "Current equipment status" {}
}
}
}
cloud-agnostic.client operations_dashboard "Operations dashboard" {}
sensor_fleet -> iot_hub { id telemetry_to_hub label "Telemetry readings" step 1 }
iot_hub -> event_hubs { id hub_to_events label "Processing stream" step 2 }
iot_hub -> raw_archive { id hub_to_archive label "Raw archive" step 2 }
event_hubs -> normalizer { id events_to_function label "Event stream" step 3 }
normalizer -> status_db { id function_to_status label "Normalized status" step 4 }
status_db -> operations_dashboard { id status_to_dashboard label "Current status" step 5 }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "azure",
"components": [
{ "id": "subscription", "kind": "group", "type": "azure.subscription", "basis": { "kind": "explicit", "text": "one subscription" } },
{ "id": "region", "kind": "group", "type": "azure.region", "basis": { "kind": "explicit", "text": "one region" } },
{ "id": "resource_group", "kind": "group", "type": "azure.resource-group", "basis": { "kind": "explicit", "text": "one resource group" } },
{ "id": "sensor_fleet", "kind": "resource", "type": "cloud-agnostic.device", "basis": { "kind": "explicit", "text": "industrial sensor fleet" } },
{ "id": "iot_hub", "kind": "resource", "type": "azure.iot-hub", "basis": { "kind": "explicit", "text": "Azure IoT Hub" } },
{ "id": "event_hubs", "kind": "resource", "type": "azure.event-hubs", "basis": { "kind": "explicit", "text": "Event Hubs for processing" } },
{ "id": "raw_archive", "kind": "resource", "type": "azure.storage-accounts", "basis": { "kind": "explicit", "text": "Storage Account raw archive" } },
{ "id": "normalizer", "kind": "resource", "type": "azure.function-apps", "basis": { "kind": "explicit", "text": "Azure Function App consumes the event stream, normalizes readings" } },
{ "id": "status_db", "kind": "resource", "type": "azure.azure-cosmos-db", "basis": { "kind": "explicit", "text": "writes current equipment status to Cosmos DB" } },
{ "id": "operations_dashboard", "kind": "resource", "type": "cloud-agnostic.client", "basis": { "kind": "explicit", "text": "external operations dashboard reads current status" } }
],
"relationships": [
{ "id": "telemetry_to_hub", "source": "sensor_fleet", "target": "iot_hub", "kind": "flow", "basis": { "kind": "explicit", "text": "sensor fleet -> Azure IoT Hub" } },
{ "id": "hub_to_events", "source": "iot_hub", "target": "event_hubs", "kind": "flow", "basis": { "kind": "explicit", "text": "IoT Hub routes readings to Event Hubs for processing" } },
{ "id": "hub_to_archive", "source": "iot_hub", "target": "raw_archive", "kind": "flow", "basis": { "kind": "explicit", "text": "IoT Hub routes readings to a Storage Account raw archive" } },
{ "id": "events_to_function", "source": "event_hubs", "target": "normalizer", "kind": "flow", "basis": { "kind": "explicit", "text": "Function App consumes the event stream" } },
{ "id": "function_to_status", "source": "normalizer", "target": "status_db", "kind": "flow", "basis": { "kind": "explicit", "text": "normalizes readings, writes current equipment status to Cosmos DB" } },
{ "id": "status_to_dashboard", "source": "status_db", "target": "operations_dashboard", "kind": "flow", "basis": { "kind": "explicit", "text": "external operations dashboard reads current status" } }
],
"counts": [
{ "id": "one_subscription", "kind": "group", "type": "azure.subscription", "min": 1, "max": 1, "basis": { "kind": "explicit", "text": "one subscription" } },
{ "id": "one_region", "kind": "group", "type": "azure.region", "min": 1, "max": 1, "within": "subscription", "basis": { "kind": "explicit", "text": "one region" } },
{ "id": "one_resource_group", "kind": "group", "type": "azure.resource-group", "min": 1, "max": 1, "within": "region", "basis": { "kind": "explicit", "text": "one resource group" } },
{ "id": "one_sensor_fleet", "kind": "resource", "type": "cloud-agnostic.device", "min": 1, "max": 1, "basis": { "kind": "explicit", "text": "industrial sensor fleet" } },
{ "id": "one_iot_hub", "kind": "resource", "type": "azure.iot-hub", "min": 1, "max": 1, "within": "resource_group", "basis": { "kind": "explicit", "text": "Azure IoT Hub" } },
{ "id": "one_event_hubs", "kind": "resource", "type": "azure.event-hubs", "min": 1, "max": 1, "within": "resource_group", "basis": { "kind": "explicit", "text": "Event Hubs for processing" } },
{ "id": "one_archive", "kind": "resource", "type": "azure.storage-accounts", "min": 1, "max": 1, "within": "resource_group", "basis": { "kind": "explicit", "text": "Storage Account raw archive" } },
{ "id": "one_function", "kind": "resource", "type": "azure.function-apps", "min": 1, "max": 1, "within": "resource_group", "basis": { "kind": "explicit", "text": "Azure Function App" } },
{ "id": "one_cosmos_db", "kind": "resource", "type": "azure.azure-cosmos-db", "min": 1, "max": 1, "within": "resource_group", "basis": { "kind": "explicit", "text": "Cosmos DB" } },
{ "id": "one_dashboard", "kind": "resource", "type": "cloud-agnostic.client", "min": 1, "max": 1, "basis": { "kind": "explicit", "text": "external operations dashboard" } }
],
"placement": [
{ "id": "region_inside_subscription", "component": "region", "relation": "inside", "group": "subscription", "basis": { "kind": "explicit", "text": "one region inside one subscription" } },
{ "id": "rg_inside_region", "component": "resource_group", "relation": "inside", "group": "region", "basis": { "kind": "explicit", "text": "one resource group inside the region" } },
{ "id": "iot_hub_in_rg", "component": "iot_hub", "relation": "inside", "group": "resource_group", "basis": { "kind": "explicit", "text": "Nest all Azure resources in one subscription, region, and resource group." } },
{ "id": "event_hubs_in_rg", "component": "event_hubs", "relation": "inside", "group": "resource_group", "basis": { "kind": "explicit", "text": "Nest all Azure resources in one subscription, region, and resource group." } },
{ "id": "archive_in_rg", "component": "raw_archive", "relation": "inside", "group": "resource_group", "basis": { "kind": "explicit", "text": "Nest all Azure resources in one subscription, region, and resource group." } },
{ "id": "function_in_rg", "component": "normalizer", "relation": "inside", "group": "resource_group", "basis": { "kind": "explicit", "text": "Nest all Azure resources in one subscription, region, and resource group." } },
{ "id": "cosmos_in_rg", "component": "status_db", "relation": "inside", "group": "resource_group", "basis": { "kind": "explicit", "text": "Nest all Azure resources in one subscription, region, and resource group." } },
{ "id": "sensor_outside_azure", "component": "sensor_fleet", "relation": "root", "basis": { "kind": "explicit", "text": "device/dashboard outside Azure scope" } },
{ "id": "dashboard_outside_azure", "component": "operations_dashboard", "relation": "root", "basis": { "kind": "explicit", "text": "device/dashboard outside Azure scope" } }
],
"allowAdditionalResources": false
}
Download Requirements ↓ Create a left-to-right Azure IoT telemetry architecture. An industrial sensor fleet sends readings to Azure IoT Hub. IoT Hub routes readings to Event Hubs for processing and to a Storage Account for a raw archive. An Azure Function App consumes the event stream, normalizes readings, and writes current equipment status to Cosmos DB. An external operations dashboard reads the current status. Nest Azure resources in a subscription, region, and resource group. Add no other services and use automatic routing.Download Prompt ↓
dgm 1
diagram azure-medium-industrial-iot-telemetry {
grammar azure
flow lr
title "Azure industrial IoT telemetry"
cloud-agnostic.client dashboard "Operations dashboard"
cloud-agnostic.device sensors "Industrial sensor fleet"
azure.subscription sub "Subscription" {
azure.region region "Region" {
azure.resource-group rg "Resource group" {
azure.iot-hub hub "IoT Hub"
azure.storage-accounts archive "Raw archive"
azure.event-hubs events "Event Hubs"
azure.function-apps func "Function App"
azure.azure-cosmos-db cosmos "Equipment status"
}
}
}
sensors -> hub { id readings step 1 label "Readings" kind flow }
hub -> events { id route_events step 2 label "Route events" kind flow }
hub -> archive { id route_archive step 2 label "Raw archive" kind flow }
events -> func { id consume step 3 label "Consume stream" kind flow }
func -> cosmos { id status step 4 label "Current status" kind flow }
dashboard -> cosmos { id read_status step 5 label "Read status" kind flow }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "azure",
"components": [
{
"id": "dashboard",
"kind": "resource",
"type": "cloud-agnostic.client",
"basis": {
"kind": "explicit",
"text": "Sensor fleet -> IoT Hub -> Event Hubs and Storage Account archive; Function App consumes, normalizes, writes status to Cosmos DB; external dashboard reads st..."
}
},
{
"id": "sensors",
"kind": "resource",
"type": "cloud-agnostic.device",
"basis": {
"kind": "explicit",
"text": "Sensor fleet -> IoT Hub -> Event Hubs and Storage Account archive; Function App consumes, normalizes, writes status to Cosmos DB; external dashboard reads st..."
}
},
{
"id": "sub",
"kind": "group",
"type": "azure.subscription",
"basis": {
"kind": "explicit",
"text": "Sensor fleet -> IoT Hub -> Event Hubs and Storage Account archive; Function App consumes, normalizes, writes status to Cosmos DB; external dashboard reads st..."
}
},
{
"id": "region",
"kind": "group",
"type": "azure.region",
"basis": {
"kind": "explicit",
"text": "Sensor fleet -> IoT Hub -> Event Hubs and Storage Account archive; Function App consumes, normalizes, writes status to Cosmos DB; external dashboard reads st..."
}
},
{
"id": "rg",
"kind": "group",
"type": "azure.resource-group",
"basis": {
"kind": "explicit",
"text": "Sensor fleet -> IoT Hub -> Event Hubs and Storage Account archive; Function App consumes, normalizes, writes status to Cosmos DB; external dashboard reads st..."
}
},
{
"id": "hub",
"kind": "resource",
"type": "azure.iot-hub",
"basis": {
"kind": "explicit",
"text": "Sensor fleet -> IoT Hub -> Event Hubs and Storage Account archive; Function App consumes, normalizes, writes status to Cosmos DB; external dashboard reads st..."
}
},
{
"id": "archive",
"kind": "resource",
"type": "azure.storage-accounts",
"basis": {
"kind": "explicit",
"text": "Sensor fleet -> IoT Hub -> Event Hubs and Storage Account archive; Function App consumes, normalizes, writes status to Cosmos DB; external dashboard reads st..."
}
},
{
"id": "events",
"kind": "resource",
"type": "azure.event-hubs",
"basis": {
"kind": "explicit",
"text": "Sensor fleet -> IoT Hub -> Event Hubs and Storage Account archive; Function App consumes, normalizes, writes status to Cosmos DB; external dashboard reads st..."
}
},
{
"id": "func",
"kind": "resource",
"type": "azure.function-apps",
"basis": {
"kind": "explicit",
"text": "Sensor fleet -> IoT Hub -> Event Hubs and Storage Account archive; Function App consumes, normalizes, writes status to Cosmos DB; external dashboard reads st..."
}
},
{
"id": "cosmos",
"kind": "resource",
"type": "azure.azure-cosmos-db",
"basis": {
"kind": "explicit",
"text": "Sensor fleet -> IoT Hub -> Event Hubs and Storage Account archive; Function App consumes, normalizes, writes status to Cosmos DB; external dashboard reads st..."
}
}
],
"relationships": [
{
"id": "readings",
"source": "sensors",
"target": "hub",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Readings (sensors to hub) per the request."
}
},
{
"id": "route_events",
"source": "hub",
"target": "events",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Route events (hub to events) per the request."
}
},
{
"id": "route_archive",
"source": "hub",
"target": "archive",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Raw archive (hub to archive) per the request."
}
},
{
"id": "consume",
"source": "events",
"target": "func",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Consume stream (events to func) per the request."
}
},
{
"id": "status",
"source": "func",
"target": "cosmos",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Current status (func to cosmos) per the request."
}
},
{
"id": "read_status",
"source": "dashboard",
"target": "cosmos",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Read status (dashboard to cosmos) per the request."
}
}
],
"counts": [],
"placement": [
{
"id": "dashboard_root",
"component": "dashboard",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "sensors_root",
"component": "sensors",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "sub_root",
"component": "sub",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "region_in_sub",
"component": "region",
"relation": "parent",
"group": "sub",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "rg_in_region",
"component": "rg",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "hub_in_rg",
"component": "hub",
"relation": "parent",
"group": "rg",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "archive_in_rg",
"component": "archive",
"relation": "parent",
"group": "rg",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "events_in_rg",
"component": "events",
"relation": "parent",
"group": "rg",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "func_in_rg",
"component": "func",
"relation": "parent",
"group": "rg",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "cosmos_in_rg",
"component": "cosmos",
"relation": "parent",
"group": "rg",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
}
],
"allowAdditionalResources": false
}
Download Requirements ↓ Private Azure Order Processing
Review note: Strict validation reports 19 routing findings, mostly plain arrow crossings; accepted in review.
Create an Azure private order processing architecture. A public client enters through Front Door and API Management to an App Service API. The API reads and writes Azure SQL through a SQL private endpoint and enqueues work in Service Bus. A Function worker consumes Service Bus work, writes files through a Storage private endpoint, and writes order status to the Azure SQL database through the shared SQL private endpoint. The API and Function read Key Vault and emit telemetry to Azure Monitor. Service Bus work that reaches its retry limit moves to a dead-letter queue; an operations client inspects the DLQ and triggers redrive back to the work queue. Show API and Function VNet integration in an application subnet, and place private endpoints in a data subnet. SQL, Storage, Service Bus, Key Vault, and Monitor are managed services outside the VNet but within one subscription, region, and resource group. Show private endpoint relation direction explicitly. Add no other services.Download Prompt ↓
dgm 1
diagram azure_hard_private_order_processing {
grammar azure
flow lr
title "Private Azure Order Processing"
azure.subscription subscription "Azure subscription" {
azure.region region "Region" {
azure.resource-group resource_group "Order processing resource group" {
azure.front-door-and-cdn-profiles front_door "Front Door" {}
azure.api-management-services api_management "API Management" {}
azure.vnet app_vnet "Application VNet" {
azure.subnet application_subnet "Application subnet" {
azure.app-services api "Order API" {}
azure.function-apps worker "Function worker" {}
}
azure.subnet data_subnet "Data subnet" {
azure.private-endpoints sql_private_endpoint "SQL private endpoint" {}
azure.private-endpoints storage_private_endpoint "Storage private endpoint" {}
}
}
cloud-agnostic.boundary service_bus_scope "Service Bus queues" {
azure.azure-service-bus work_queue "Work queue" {}
azure.azure-service-bus dead_letter_queue "Dead-letter queue" {}
}
cloud-agnostic.boundary data_services_scope "SQL and Storage" {
azure.sql-database sql_database "SQL Database" {}
azure.storage-accounts storage_account "Storage Account" {}
}
cloud-agnostic.boundary support_scope "Secrets and telemetry" {
azure.key-vaults key_vault "Key Vault" {}
azure.monitor monitor "Azure Monitor" {}
}
}
}
}
cloud-agnostic.client public_client "Public client" {}
cloud-agnostic.client operations_client "Operations client" {}
public_client -> front_door {
id client_to_front_door
label "Order request"
step 1
from e
to w
}
front_door -> api_management {
id front_door_to_apim
label "Forward request"
step 2
from e
to w
}
api_management -> api {
id apim_to_api
label "Route request"
step 3
from e
to w
}
api -> sql_private_endpoint {
id api_to_sql_endpoint
label "SQL read/write"
step 4
from s
to n
}
api -> work_queue {
id api_to_work_queue
label "Enqueue work"
step 4
from e
to w
}
work_queue -> worker {
id work_queue_to_worker
label "Dequeue work"
step 5
from w
to e
}
worker -> storage_private_endpoint {
id worker_to_storage_endpoint
label "Write files"
step 6
from s
to n
}
worker -> sql_private_endpoint {
id worker_to_sql_endpoint
label "Write order status"
step 6
from s
to n
}
sql_private_endpoint -> sql_database {
id sql_endpoint_to_database
label "Private endpoint to SQL"
step 7
from e
to w
}
storage_private_endpoint -> storage_account {
id storage_endpoint_to_account
label "Private endpoint to Storage"
step 7
from e
to w
}
work_queue -> dead_letter_queue {
id work_queue_to_dlq
label "Retry limit reached"
style dashed
kind fail
from s
to n
}
operations_client -> dead_letter_queue {
id ops_to_dlq
label "Inspect DLQ"
style dashed
kind flow
from e
to w
}
operations_client -> work_queue {
id ops_to_work_queue
label "Redrive work"
style dashed
kind flow
from e
to w
}
api -> key_vault {
id api_to_key_vault
label "Read secrets"
style dashed
kind flow
from w
to e
}
worker -> key_vault {
id worker_to_key_vault
label "Read secrets"
style dashed
kind flow
from w
to e
}
api -> monitor {
id api_to_monitor
label "Telemetry"
style dashed
kind flow
from w
to e
}
worker -> monitor {
id worker_to_monitor
label "Telemetry"
style dashed
kind flow
from w
to e
}
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "azure",
"components": [
{ "id": "subscription", "kind": "group", "type": "azure.subscription", "basis": { "kind": "explicit", "text": "within one subscription" } },
{ "id": "region", "kind": "group", "type": "azure.region", "basis": { "kind": "explicit", "text": "within one region" } },
{ "id": "resource_group", "kind": "group", "type": "azure.resource-group", "basis": { "kind": "explicit", "text": "within one resource group" } },
{ "id": "app_vnet", "kind": "group", "type": "azure.vnet", "basis": { "kind": "explicit", "text": "VNet integration in an application subnet" } },
{ "id": "application_subnet", "kind": "group", "type": "azure.subnet", "basis": { "kind": "explicit", "text": "application subnet" } },
{ "id": "data_subnet", "kind": "group", "type": "azure.subnet", "basis": { "kind": "explicit", "text": "data subnet for Private Endpoints" } },
{ "id": "service_bus_scope", "kind": "group", "type": "cloud-agnostic.boundary", "basis": { "kind": "inferred", "text": "Logical container to show the work queue and DLQ under one Service Bus service." } },
{ "id": "support_scope", "kind": "group", "type": "cloud-agnostic.boundary", "basis": { "kind": "inferred", "text": "Logical grouping for the requested Key Vault and Monitor support services." } },
{ "id": "data_services_scope", "kind": "group", "type": "cloud-agnostic.boundary", "basis": { "kind": "inferred", "text": "Logical grouping for the SQL and Storage targets outside the VNet." } },
{ "id": "public_client", "kind": "resource", "type": "cloud-agnostic.client", "basis": { "kind": "explicit", "text": "A public client enters through Front Door." } },
{ "id": "operations_client", "kind": "resource", "type": "cloud-agnostic.client", "basis": { "kind": "explicit", "text": "An operations client inspects the DLQ and triggers redrive." } },
{ "id": "front_door", "kind": "resource", "type": "azure.front-door-and-cdn-profiles", "basis": { "kind": "explicit", "text": "Front Door" } },
{ "id": "api_management", "kind": "resource", "type": "azure.api-management-services", "basis": { "kind": "explicit", "text": "API Management" } },
{ "id": "api", "kind": "resource", "type": "azure.app-services", "basis": { "kind": "explicit", "text": "an App Service API" } },
{ "id": "worker", "kind": "resource", "type": "azure.function-apps", "basis": { "kind": "explicit", "text": "A Function worker" } },
{ "id": "sql_private_endpoint", "kind": "resource", "type": "azure.private-endpoints", "basis": { "kind": "explicit", "text": "a SQL private endpoint" } },
{ "id": "sql_database", "kind": "resource", "type": "azure.sql-database", "basis": { "kind": "explicit", "text": "Azure SQL" } },
{ "id": "storage_private_endpoint", "kind": "resource", "type": "azure.private-endpoints", "basis": { "kind": "explicit", "text": "a Storage private endpoint" } },
{ "id": "storage_account", "kind": "resource", "type": "azure.storage-accounts", "basis": { "kind": "explicit", "text": "writes files through a Storage private endpoint" } },
{ "id": "work_queue", "kind": "resource", "type": "azure.azure-service-bus", "basis": { "kind": "explicit", "text": "enqueues work in Service Bus" } },
{ "id": "dead_letter_queue", "kind": "resource", "type": "azure.azure-service-bus", "basis": { "kind": "explicit", "text": "moves to a dead-letter queue" } },
{ "id": "key_vault", "kind": "resource", "type": "azure.key-vaults", "basis": { "kind": "explicit", "text": "The API and Function read Key Vault." } },
{ "id": "monitor", "kind": "resource", "type": "azure.monitor", "basis": { "kind": "explicit", "text": "The API and Function emit telemetry to Azure Monitor." } }
],
"relationships": [
{ "id": "client_to_front_door", "source": "public_client", "target": "front_door", "kind": "flow", "basis": { "kind": "explicit", "text": "A public client enters through Front Door." } },
{ "id": "front_door_to_apim", "source": "front_door", "target": "api_management", "kind": "flow", "basis": { "kind": "explicit", "text": "Front Door and API Management form the entry path." } },
{ "id": "apim_to_api", "source": "api_management", "target": "api", "kind": "flow", "basis": { "kind": "explicit", "text": "API Management routes to an App Service API." } },
{ "id": "api_to_sql_endpoint", "source": "api", "target": "sql_private_endpoint", "kind": "flow", "basis": { "kind": "explicit", "text": "The API reads and writes Azure SQL through a SQL Private Endpoint." } },
{ "id": "sql_endpoint_to_database", "source": "sql_private_endpoint", "target": "sql_database", "kind": "flow", "basis": { "kind": "explicit", "text": "SQL Private Endpoint to Azure SQL; show relation direction explicitly." } },
{ "id": "api_to_work_queue", "source": "api", "target": "work_queue", "kind": "flow", "basis": { "kind": "explicit", "text": "The API enqueues work in Service Bus." } },
{ "id": "work_queue_to_worker", "source": "work_queue", "target": "worker", "kind": "flow", "basis": { "kind": "explicit", "text": "The Function worker consumes Service Bus work." } },
{ "id": "work_queue_to_dlq", "source": "work_queue", "target": "dead_letter_queue", "kind": "fail", "basis": { "kind": "explicit", "text": "Service Bus work reaching its retry limit moves to a dead-letter queue." } },
{ "id": "worker_to_storage_endpoint", "source": "worker", "target": "storage_private_endpoint", "kind": "flow", "basis": { "kind": "explicit", "text": "The Function writes files through a Storage Private Endpoint." } },
{ "id": "storage_endpoint_to_account", "source": "storage_private_endpoint", "target": "storage_account", "kind": "flow", "basis": { "kind": "explicit", "text": "Storage Private Endpoint to Storage Account; show relation direction explicitly." } },
{ "id": "worker_to_sql_endpoint", "source": "worker", "target": "sql_private_endpoint", "kind": "flow", "basis": { "kind": "explicit", "text": "The Function writes order status through the shared SQL Private Endpoint." } },
{ "id": "api_to_key_vault", "source": "api", "target": "key_vault", "kind": "flow", "basis": { "kind": "explicit", "text": "The API reads Key Vault." } },
{ "id": "worker_to_key_vault", "source": "worker", "target": "key_vault", "kind": "flow", "basis": { "kind": "explicit", "text": "The Function reads Key Vault." } },
{ "id": "api_to_monitor", "source": "api", "target": "monitor", "kind": "flow", "basis": { "kind": "explicit", "text": "The API emits telemetry to Azure Monitor." } },
{ "id": "worker_to_monitor", "source": "worker", "target": "monitor", "kind": "flow", "basis": { "kind": "explicit", "text": "The Function emits telemetry to Azure Monitor." } },
{ "id": "ops_to_dlq", "source": "operations_client", "target": "dead_letter_queue", "kind": "flow", "basis": { "kind": "explicit", "text": "The operations client inspects the DLQ." } },
{ "id": "ops_to_work_queue", "source": "operations_client", "target": "work_queue", "kind": "flow", "basis": { "kind": "explicit", "text": "The operations client triggers redrive to the work queue." } }
],
"counts": [
{ "id": "one_subscription", "kind": "group", "type": "azure.subscription", "min": 1, "max": 1, "basis": { "kind": "explicit", "text": "one subscription" } },
{ "id": "one_region", "kind": "group", "type": "azure.region", "min": 1, "max": 1, "within": "subscription", "basis": { "kind": "explicit", "text": "one region" } },
{ "id": "one_resource_group", "kind": "group", "type": "azure.resource-group", "min": 1, "max": 1, "within": "region", "basis": { "kind": "explicit", "text": "one resource group" } },
{ "id": "one_vnet", "kind": "group", "type": "azure.vnet", "min": 1, "max": 1, "within": "resource_group", "basis": { "kind": "explicit", "text": "one application VNet" } },
{ "id": "two_subnets", "kind": "group", "type": "azure.subnet", "min": 2, "max": 2, "within": "app_vnet", "basis": { "kind": "explicit", "text": "application subnet and data subnet" } },
{ "id": "two_clients", "kind": "resource", "type": "cloud-agnostic.client", "min": 2, "max": 2, "basis": { "kind": "explicit", "text": "public client and operations client" } },
{ "id": "one_front_door", "kind": "resource", "type": "azure.front-door-and-cdn-profiles", "min": 1, "max": 1, "within": "resource_group", "basis": { "kind": "explicit", "text": "Front Door" } },
{ "id": "one_apim", "kind": "resource", "type": "azure.api-management-services", "min": 1, "max": 1, "within": "resource_group", "basis": { "kind": "explicit", "text": "API Management" } },
{ "id": "one_api", "kind": "resource", "type": "azure.app-services", "min": 1, "max": 1, "within": "resource_group", "basis": { "kind": "explicit", "text": "an App Service API" } },
{ "id": "one_worker", "kind": "resource", "type": "azure.function-apps", "min": 1, "max": 1, "within": "resource_group", "basis": { "kind": "explicit", "text": "a Function worker" } },
{ "id": "two_private_endpoints", "kind": "resource", "type": "azure.private-endpoints", "min": 2, "max": 2, "within": "data_subnet", "basis": { "kind": "explicit", "text": "SQL and Storage Private Endpoints" } },
{ "id": "one_sql_database", "kind": "resource", "type": "azure.sql-database", "min": 1, "max": 1, "within": "resource_group", "basis": { "kind": "explicit", "text": "Azure SQL" } },
{ "id": "one_storage_account", "kind": "resource", "type": "azure.storage-accounts", "min": 1, "max": 1, "within": "resource_group", "basis": { "kind": "explicit", "text": "Storage" } },
{ "id": "two_service_bus_queues", "kind": "resource", "type": "azure.azure-service-bus", "min": 2, "max": 2, "within": "service_bus_scope", "basis": { "kind": "explicit", "text": "work queue and dead-letter queue under Service Bus" } },
{ "id": "one_key_vault", "kind": "resource", "type": "azure.key-vaults", "min": 1, "max": 1, "within": "resource_group", "basis": { "kind": "explicit", "text": "Key Vault" } },
{ "id": "one_monitor", "kind": "resource", "type": "azure.monitor", "min": 1, "max": 1, "within": "resource_group", "basis": { "kind": "explicit", "text": "Azure Monitor" } }
],
"placement": [
{ "id": "region_parent", "component": "region", "relation": "parent", "group": "subscription", "basis": { "kind": "explicit", "text": "within one subscription and region" } },
{ "id": "resource_group_parent", "component": "resource_group", "relation": "parent", "group": "region", "basis": { "kind": "explicit", "text": "within one region and resource group" } },
{ "id": "vnet_in_resource_group", "component": "app_vnet", "relation": "parent", "group": "resource_group", "basis": { "kind": "explicit", "text": "application VNet is in the resource group" } },
{ "id": "application_subnet_in_vnet", "component": "application_subnet", "relation": "parent", "group": "app_vnet", "basis": { "kind": "explicit", "text": "application subnet" } },
{ "id": "data_subnet_in_vnet", "component": "data_subnet", "relation": "parent", "group": "app_vnet", "basis": { "kind": "explicit", "text": "data subnet" } },
{ "id": "service_bus_scope_in_resource_group", "component": "service_bus_scope", "relation": "parent", "group": "resource_group", "basis": { "kind": "inferred", "text": "Logical grouping for the Service Bus queue artifacts." } },
{ "id": "support_scope_in_resource_group", "component": "support_scope", "relation": "parent", "group": "resource_group", "basis": { "kind": "inferred", "text": "Logical grouping for requested support services." } },
{ "id": "data_services_scope_in_resource_group", "component": "data_services_scope", "relation": "parent", "group": "resource_group", "basis": { "kind": "inferred", "text": "Logical grouping for the two private endpoint targets." } },
{ "id": "public_client_root", "component": "public_client", "relation": "root", "basis": { "kind": "explicit", "text": "public client" } },
{ "id": "operations_client_root", "component": "operations_client", "relation": "root", "basis": { "kind": "explicit", "text": "operations client" } },
{ "id": "front_door_in_resource_group", "component": "front_door", "relation": "inside", "group": "resource_group", "basis": { "kind": "explicit", "text": "Front Door within the same resource group" } },
{ "id": "front_door_outside_vnet", "component": "front_door", "relation": "outside", "group": "app_vnet", "basis": { "kind": "explicit", "text": "Front Door is a managed service outside the VNet." } },
{ "id": "apim_in_resource_group", "component": "api_management", "relation": "inside", "group": "resource_group", "basis": { "kind": "explicit", "text": "API Management within the same resource group" } },
{ "id": "apim_outside_vnet", "component": "api_management", "relation": "outside", "group": "app_vnet", "basis": { "kind": "inferred", "text": "No API Management VNet integration was requested." } },
{ "id": "api_in_app_subnet", "component": "api", "relation": "inside", "group": "application_subnet", "basis": { "kind": "explicit", "text": "Show API VNet integration in an application subnet." } },
{ "id": "worker_in_app_subnet", "component": "worker", "relation": "inside", "group": "application_subnet", "basis": { "kind": "explicit", "text": "Show Function VNet integration in an application subnet." } },
{ "id": "sql_endpoint_in_data_subnet", "component": "sql_private_endpoint", "relation": "inside", "group": "data_subnet", "basis": { "kind": "explicit", "text": "Private Endpoints are in a data subnet." } },
{ "id": "storage_endpoint_in_data_subnet", "component": "storage_private_endpoint", "relation": "inside", "group": "data_subnet", "basis": { "kind": "explicit", "text": "Private Endpoints are in a data subnet." } },
{ "id": "sql_in_data_services", "component": "sql_database", "relation": "inside", "group": "data_services_scope", "basis": { "kind": "inferred", "text": "Group SQL beside the Storage private endpoint target." } },
{ "id": "sql_in_resource_group", "component": "sql_database", "relation": "inside", "group": "resource_group", "basis": { "kind": "explicit", "text": "SQL is within one subscription, region, and resource group." } },
{ "id": "sql_outside_vnet", "component": "sql_database", "relation": "outside", "group": "app_vnet", "basis": { "kind": "explicit", "text": "SQL is a managed service outside the VNet." } },
{ "id": "storage_in_data_services", "component": "storage_account", "relation": "inside", "group": "data_services_scope", "basis": { "kind": "inferred", "text": "Group Storage beside the SQL private endpoint target." } },
{ "id": "storage_in_resource_group", "component": "storage_account", "relation": "inside", "group": "resource_group", "basis": { "kind": "explicit", "text": "Storage is within one subscription, region, and resource group." } },
{ "id": "storage_outside_vnet", "component": "storage_account", "relation": "outside", "group": "app_vnet", "basis": { "kind": "explicit", "text": "Storage is a managed service outside the VNet." } },
{ "id": "work_queue_in_bus_scope", "component": "work_queue", "relation": "inside", "group": "service_bus_scope", "basis": { "kind": "explicit", "text": "Service Bus work queue." } },
{ "id": "dlq_in_bus_scope", "component": "dead_letter_queue", "relation": "inside", "group": "service_bus_scope", "basis": { "kind": "explicit", "text": "Service Bus dead-letter queue." } },
{ "id": "work_queue_outside_vnet", "component": "work_queue", "relation": "outside", "group": "app_vnet", "basis": { "kind": "explicit", "text": "Service Bus is a managed service outside the VNet." } },
{ "id": "dlq_outside_vnet", "component": "dead_letter_queue", "relation": "outside", "group": "app_vnet", "basis": { "kind": "explicit", "text": "Service Bus is a managed service outside the VNet." } },
{ "id": "key_vault_in_support", "component": "key_vault", "relation": "inside", "group": "support_scope", "basis": { "kind": "explicit", "text": "Key Vault support service in the resource group." } },
{ "id": "monitor_in_support", "component": "monitor", "relation": "inside", "group": "support_scope", "basis": { "kind": "explicit", "text": "Monitor support service in the resource group." } },
{ "id": "key_vault_outside_vnet", "component": "key_vault", "relation": "outside", "group": "app_vnet", "basis": { "kind": "explicit", "text": "Key Vault is a managed service outside the VNet." } },
{ "id": "monitor_outside_vnet", "component": "monitor", "relation": "outside", "group": "app_vnet", "basis": { "kind": "explicit", "text": "Monitor is a managed service outside the VNet." } }
],
"allowAdditionalResources": false
}
Download Requirements ↓ Review note: Strict validation reports 21 routing findings, mostly plain arrow crossings; accepted in review.
Create an Azure private order processing architecture. A public client enters through Front Door and API Management to an App Service API. The API reads and writes Azure SQL through a SQL private endpoint and enqueues work in Service Bus. A Function worker consumes Service Bus work, writes files through a Storage private endpoint, and writes order status to the Azure SQL database through the shared SQL private endpoint. The API and Function read Key Vault and emit telemetry to Azure Monitor. Service Bus work that reaches its retry limit moves to a dead-letter queue; an operations client inspects the DLQ and triggers redrive back to the work queue. Show API and Function VNet integration in an application subnet, and place private endpoints in a data subnet. SQL, Storage, Service Bus, Key Vault, and Monitor are managed services outside the VNet but within one subscription, region, and resource group. Show private endpoint relation direction explicitly. Add no other services.Download Prompt ↓
dgm 1
diagram azure-hard-private-order-processing {
grammar azure
flow lr
title "Azure private order processing"
cloud-agnostic.client client "Public client"
cloud-agnostic.client ops "Operations client"
azure.subscription sub "Subscription" {
azure.region region "Region" {
azure.resource-group rg "Resource group" {
azure.front-door-and-cdn-profiles fd "Front Door"
azure.api-management-services apim "API Management"
azure.vnet vnet "VNet" {
azure.subnet app_subnet "Application subnet" {
azure.app-services api "API"
azure.function-apps func "Function worker"
}
azure.subnet data_subnet "Data subnet" {
azure.private-endpoints sql_pe "SQL private endpoint"
azure.private-endpoints storage_pe "Storage private endpoint"
}
}
azure.sql-database sql "Azure SQL"
azure.storage-accounts storage "Storage"
azure.azure-service-bus work "Work queue"
azure.azure-service-bus dlq "Dead-letter queue"
azure.key-vaults kv "Key Vault"
azure.monitor monitor "Azure Monitor"
}
}
}
client -> fd { id enter step 1 label "HTTPS" kind flow }
fd -> apim { id front step 2 label "Forward" kind flow }
apim -> api { id route step 3 label "Route" kind flow }
api -> sql_pe { id sql_access step 4 label "Read/write" kind flow }
api -> work { id enqueue step 4 label "Enqueue work" kind flow }
work -> func { id consume step 5 label "Consume work" kind flow }
func -> storage_pe { id files step 6 label "Write files" kind flow }
func -> sql_pe { id status step 6 label "Order status" kind flow }
sql_pe -> sql { id sql_link step 7 label "Private link" kind flow }
storage_pe -> storage { id storage_link step 7 label "Private link" kind flow }
work -> dlq { id retry_limit label "Retry limit" kind fail }
ops -> dlq { id inspect label "Inspect" kind peer style dashed }
dlq -> work { id redrive label "Redrive" kind flow style dashed }
api -> kv { id api_kv label "Read secrets" kind peer style dashed }
func -> kv { id func_kv label "Read secrets" kind peer style dashed }
api -> monitor { id api_mon label "Telemetry" kind peer style dashed }
func -> monitor { id func_mon label "Telemetry" kind peer style dashed }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "azure",
"components": [
{
"id": "client",
"kind": "resource",
"type": "cloud-agnostic.client",
"basis": {
"kind": "explicit",
"text": "Public client via Front Door and APIM to App Service API; SQL via private endpoint and Service Bus; Function worker writes Storage via private endpoint and S..."
}
},
{
"id": "ops",
"kind": "resource",
"type": "cloud-agnostic.client",
"basis": {
"kind": "explicit",
"text": "Public client via Front Door and APIM to App Service API; SQL via private endpoint and Service Bus; Function worker writes Storage via private endpoint and S..."
}
},
{
"id": "sub",
"kind": "group",
"type": "azure.subscription",
"basis": {
"kind": "explicit",
"text": "Public client via Front Door and APIM to App Service API; SQL via private endpoint and Service Bus; Function worker writes Storage via private endpoint and S..."
}
},
{
"id": "region",
"kind": "group",
"type": "azure.region",
"basis": {
"kind": "explicit",
"text": "Public client via Front Door and APIM to App Service API; SQL via private endpoint and Service Bus; Function worker writes Storage via private endpoint and S..."
}
},
{
"id": "rg",
"kind": "group",
"type": "azure.resource-group",
"basis": {
"kind": "explicit",
"text": "Public client via Front Door and APIM to App Service API; SQL via private endpoint and Service Bus; Function worker writes Storage via private endpoint and S..."
}
},
{
"id": "fd",
"kind": "resource",
"type": "azure.front-door-and-cdn-profiles",
"basis": {
"kind": "explicit",
"text": "Public client via Front Door and APIM to App Service API; SQL via private endpoint and Service Bus; Function worker writes Storage via private endpoint and S..."
}
},
{
"id": "apim",
"kind": "resource",
"type": "azure.api-management-services",
"basis": {
"kind": "explicit",
"text": "Public client via Front Door and APIM to App Service API; SQL via private endpoint and Service Bus; Function worker writes Storage via private endpoint and S..."
}
},
{
"id": "vnet",
"kind": "group",
"type": "azure.vnet",
"basis": {
"kind": "explicit",
"text": "Public client via Front Door and APIM to App Service API; SQL via private endpoint and Service Bus; Function worker writes Storage via private endpoint and S..."
}
},
{
"id": "app_subnet",
"kind": "group",
"type": "azure.subnet",
"basis": {
"kind": "explicit",
"text": "Public client via Front Door and APIM to App Service API; SQL via private endpoint and Service Bus; Function worker writes Storage via private endpoint and S..."
}
},
{
"id": "api",
"kind": "resource",
"type": "azure.app-services",
"basis": {
"kind": "explicit",
"text": "Public client via Front Door and APIM to App Service API; SQL via private endpoint and Service Bus; Function worker writes Storage via private endpoint and S..."
}
},
{
"id": "func",
"kind": "resource",
"type": "azure.function-apps",
"basis": {
"kind": "explicit",
"text": "Public client via Front Door and APIM to App Service API; SQL via private endpoint and Service Bus; Function worker writes Storage via private endpoint and S..."
}
},
{
"id": "data_subnet",
"kind": "group",
"type": "azure.subnet",
"basis": {
"kind": "explicit",
"text": "Public client via Front Door and APIM to App Service API; SQL via private endpoint and Service Bus; Function worker writes Storage via private endpoint and S..."
}
},
{
"id": "sql_pe",
"kind": "resource",
"type": "azure.private-endpoints",
"basis": {
"kind": "explicit",
"text": "Public client via Front Door and APIM to App Service API; SQL via private endpoint and Service Bus; Function worker writes Storage via private endpoint and S..."
}
},
{
"id": "storage_pe",
"kind": "resource",
"type": "azure.private-endpoints",
"basis": {
"kind": "explicit",
"text": "Public client via Front Door and APIM to App Service API; SQL via private endpoint and Service Bus; Function worker writes Storage via private endpoint and S..."
}
},
{
"id": "sql",
"kind": "resource",
"type": "azure.sql-database",
"basis": {
"kind": "explicit",
"text": "Public client via Front Door and APIM to App Service API; SQL via private endpoint and Service Bus; Function worker writes Storage via private endpoint and S..."
}
},
{
"id": "storage",
"kind": "resource",
"type": "azure.storage-accounts",
"basis": {
"kind": "explicit",
"text": "Public client via Front Door and APIM to App Service API; SQL via private endpoint and Service Bus; Function worker writes Storage via private endpoint and S..."
}
},
{
"id": "work",
"kind": "resource",
"type": "azure.azure-service-bus",
"basis": {
"kind": "explicit",
"text": "Public client via Front Door and APIM to App Service API; SQL via private endpoint and Service Bus; Function worker writes Storage via private endpoint and S..."
}
},
{
"id": "dlq",
"kind": "resource",
"type": "azure.azure-service-bus",
"basis": {
"kind": "explicit",
"text": "Public client via Front Door and APIM to App Service API; SQL via private endpoint and Service Bus; Function worker writes Storage via private endpoint and S..."
}
},
{
"id": "kv",
"kind": "resource",
"type": "azure.key-vaults",
"basis": {
"kind": "explicit",
"text": "Public client via Front Door and APIM to App Service API; SQL via private endpoint and Service Bus; Function worker writes Storage via private endpoint and S..."
}
},
{
"id": "monitor",
"kind": "resource",
"type": "azure.monitor",
"basis": {
"kind": "explicit",
"text": "Public client via Front Door and APIM to App Service API; SQL via private endpoint and Service Bus; Function worker writes Storage via private endpoint and S..."
}
}
],
"relationships": [
{
"id": "enter",
"source": "client",
"target": "fd",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "HTTPS (client to fd) per the request."
}
},
{
"id": "front",
"source": "fd",
"target": "apim",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Forward (fd to apim) per the request."
}
},
{
"id": "route",
"source": "apim",
"target": "api",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Route (apim to api) per the request."
}
},
{
"id": "sql_access",
"source": "api",
"target": "sql_pe",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Read/write (api to sql_pe) per the request."
}
},
{
"id": "enqueue",
"source": "api",
"target": "work",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Enqueue work (api to work) per the request."
}
},
{
"id": "consume",
"source": "work",
"target": "func",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Consume work (work to func) per the request."
}
},
{
"id": "files",
"source": "func",
"target": "storage_pe",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Write files (func to storage_pe) per the request."
}
},
{
"id": "status",
"source": "func",
"target": "sql_pe",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Order status (func to sql_pe) per the request."
}
},
{
"id": "sql_link",
"source": "sql_pe",
"target": "sql",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Private link (sql_pe to sql) per the request."
}
},
{
"id": "storage_link",
"source": "storage_pe",
"target": "storage",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Private link (storage_pe to storage) per the request."
}
},
{
"id": "retry_limit",
"source": "work",
"target": "dlq",
"kind": "fail",
"basis": {
"kind": "explicit",
"text": "Retry limit (work to dlq) per the request."
}
},
{
"id": "inspect",
"source": "ops",
"target": "dlq",
"kind": "peer",
"basis": {
"kind": "explicit",
"text": "Inspect (ops to dlq) per the request."
}
},
{
"id": "redrive",
"source": "dlq",
"target": "work",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Redrive (dlq to work) per the request."
}
},
{
"id": "api_kv",
"source": "api",
"target": "kv",
"kind": "peer",
"basis": {
"kind": "explicit",
"text": "Read secrets (api to kv) per the request."
}
},
{
"id": "func_kv",
"source": "func",
"target": "kv",
"kind": "peer",
"basis": {
"kind": "explicit",
"text": "Read secrets (func to kv) per the request."
}
},
{
"id": "api_mon",
"source": "api",
"target": "monitor",
"kind": "peer",
"basis": {
"kind": "explicit",
"text": "Telemetry (api to monitor) per the request."
}
},
{
"id": "func_mon",
"source": "func",
"target": "monitor",
"kind": "peer",
"basis": {
"kind": "explicit",
"text": "Telemetry (func to monitor) per the request."
}
}
],
"counts": [],
"placement": [
{
"id": "client_root",
"component": "client",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "ops_root",
"component": "ops",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "sub_root",
"component": "sub",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "region_in_sub",
"component": "region",
"relation": "parent",
"group": "sub",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "rg_in_region",
"component": "rg",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "fd_in_rg",
"component": "fd",
"relation": "parent",
"group": "rg",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "apim_in_rg",
"component": "apim",
"relation": "parent",
"group": "rg",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "vnet_in_rg",
"component": "vnet",
"relation": "parent",
"group": "rg",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "app_subnet_in_vnet",
"component": "app_subnet",
"relation": "parent",
"group": "vnet",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "api_in_app_subnet",
"component": "api",
"relation": "parent",
"group": "app_subnet",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "func_in_app_subnet",
"component": "func",
"relation": "parent",
"group": "app_subnet",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "data_subnet_in_vnet",
"component": "data_subnet",
"relation": "parent",
"group": "vnet",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "sql_pe_in_data_subnet",
"component": "sql_pe",
"relation": "parent",
"group": "data_subnet",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "storage_pe_in_data_subnet",
"component": "storage_pe",
"relation": "parent",
"group": "data_subnet",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "sql_in_rg",
"component": "sql",
"relation": "parent",
"group": "rg",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "storage_in_rg",
"component": "storage",
"relation": "parent",
"group": "rg",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "work_in_rg",
"component": "work",
"relation": "parent",
"group": "rg",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "dlq_in_rg",
"component": "dlq",
"relation": "parent",
"group": "rg",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "kv_in_rg",
"component": "kv",
"relation": "parent",
"group": "rg",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "monitor_in_rg",
"component": "monitor",
"relation": "parent",
"group": "rg",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "sql_outside_vnet",
"component": "sql",
"relation": "outside",
"group": "vnet",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
},
{
"id": "storage_outside_vnet",
"component": "storage",
"relation": "outside",
"group": "vnet",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
},
{
"id": "work_outside_vnet",
"component": "work",
"relation": "outside",
"group": "vnet",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
},
{
"id": "dlq_outside_vnet",
"component": "dlq",
"relation": "outside",
"group": "vnet",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
},
{
"id": "kv_outside_vnet",
"component": "kv",
"relation": "outside",
"group": "vnet",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
},
{
"id": "monitor_outside_vnet",
"component": "monitor",
"relation": "outside",
"group": "vnet",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
}
],
"allowAdditionalResources": false
}
Download Requirements ↓ Google Cloud
GCP Customer Record API
Draw a left-to-right Google Cloud diagram for a small customer-record API. Show an external web client sending HTTPS requests through Cloud Load Balancing to a Cloud Run API, which reads and writes customer records in Cloud SQL. Nest a project and primary region inside a Google Cloud organization, and place the three Google Cloud services in the region. Keep the client outside the organization. Do not add other services, and use automatic routing.Download Prompt ↓
dgm 1
diagram gcp-easy-customer-record-api {
grammar gcp
flow lr
title "GCP Customer Record API"
gcp.organization organization "Google Cloud Organization" {
gcp.project project "Customer API Project" {
gcp.region region "Primary Region" {
gcp.cloud-load-balancing load_balancing "Cloud Load Balancing" {}
gcp.cloud-run customer_api "Cloud Run API" {}
gcp.cloud-sql customer_db "Cloud SQL" {}
}
}
}
cloud-agnostic.client web_client "External Web Client" {}
web_client -> load_balancing { id https_request label "HTTPS request" step 1 }
load_balancing -> customer_api { id route_to_api label "forward request" step 2 }
customer_api -> customer_db { id read_write_records label "read/write records" step 3 }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "gcp",
"components": [
{
"id": "organization",
"kind": "group",
"type": "gcp.organization",
"basis": {
"kind": "explicit",
"text": "Nest a project inside a Google Cloud organization."
}
},
{
"id": "project",
"kind": "group",
"type": "gcp.project",
"basis": {
"kind": "explicit",
"text": "Nest a project inside a Google Cloud organization."
}
},
{
"id": "region",
"kind": "group",
"type": "gcp.region",
"basis": {
"kind": "explicit",
"text": "Nest the primary region in the project."
}
},
{
"id": "web_client",
"kind": "resource",
"type": "cloud-agnostic.client",
"basis": {
"kind": "explicit",
"text": "Keep the web client outside the organization."
}
},
{
"id": "load_balancing",
"kind": "resource",
"type": "gcp.cloud-load-balancing",
"basis": {
"kind": "explicit",
"text": "Place all three Google Cloud services in the primary region."
}
},
{
"id": "customer_api",
"kind": "resource",
"type": "gcp.cloud-run",
"basis": {
"kind": "explicit",
"text": "Place all three Google Cloud services in the primary region."
}
},
{
"id": "customer_db",
"kind": "resource",
"type": "gcp.cloud-sql",
"basis": {
"kind": "explicit",
"text": "Place all three Google Cloud services in the primary region."
}
}
],
"relationships": [
{
"id": "https_request",
"source": "web_client",
"target": "load_balancing",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "route_to_api",
"source": "load_balancing",
"target": "customer_api",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "read_write_records",
"source": "customer_api",
"target": "customer_db",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
}
],
"counts": [
{
"id": "count_gcp_organization",
"kind": "group",
"type": "gcp.organization",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.organization component(s) as requested."
}
},
{
"id": "count_gcp_project_in_organization",
"kind": "group",
"type": "gcp.project",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.project component(s) as requested."
},
"within": "organization"
},
{
"id": "count_gcp_region_in_project",
"kind": "group",
"type": "gcp.region",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.region component(s) as requested."
},
"within": "project"
},
{
"id": "count_cloud-agnostic_client",
"kind": "resource",
"type": "cloud-agnostic.client",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 cloud-agnostic.client component(s) as requested."
}
},
{
"id": "count_gcp_cloud-load-balancing_in_region",
"kind": "resource",
"type": "gcp.cloud-load-balancing",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.cloud-load-balancing component(s) as requested."
},
"within": "region"
},
{
"id": "count_gcp_cloud-run_in_region",
"kind": "resource",
"type": "gcp.cloud-run",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.cloud-run component(s) as requested."
},
"within": "region"
},
{
"id": "count_gcp_cloud-sql_in_region",
"kind": "resource",
"type": "gcp.cloud-sql",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.cloud-sql component(s) as requested."
},
"within": "region"
}
],
"placement": [
{
"id": "organization_root",
"component": "organization",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Nest a project inside a Google Cloud organization."
}
},
{
"id": "project_parent",
"component": "project",
"relation": "parent",
"group": "organization",
"basis": {
"kind": "explicit",
"text": "Nest a project inside a Google Cloud organization."
}
},
{
"id": "region_parent",
"component": "region",
"relation": "parent",
"group": "project",
"basis": {
"kind": "explicit",
"text": "Nest the primary region in the project."
}
},
{
"id": "web_client_root",
"component": "web_client",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Keep the web client outside the organization."
}
},
{
"id": "load_balancing_parent",
"component": "load_balancing",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Place all three Google Cloud services in the primary region."
}
},
{
"id": "customer_api_parent",
"component": "customer_api",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Place all three Google Cloud services in the primary region."
}
},
{
"id": "customer_db_parent",
"component": "customer_db",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Place all three Google Cloud services in the primary region."
}
}
],
"allowAdditionalResources": false
}
Download Requirements ↓ Draw a left-to-right Google Cloud diagram for a small customer-record API. Show an external web client sending HTTPS requests through Cloud Load Balancing to a Cloud Run API, which reads and writes customer records in Cloud SQL. Nest a project and primary region inside a Google Cloud organization, and place the three Google Cloud services in the region. Keep the client outside the organization. Do not add other services, and use automatic routing.Download Prompt ↓
dgm 1
diagram gcp-easy-customer-record-api {
grammar gcp
flow lr
title "Google Cloud customer-record API"
cloud-agnostic.client client "Web client"
gcp.organization org "Google Cloud organization" {
gcp.project project "Project" {
gcp.region region "Primary region" {
gcp.cloud-load-balancing lb "Load balancer"
gcp.cloud-run api "Customer API"
gcp.cloud-sql db "Customer records"
}
}
}
client -> lb { id https step 1 label "HTTPS" kind flow }
lb -> api { id route step 2 label "Route" kind flow }
api -> db { id records step 3 label "Read/write records" kind flow }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "gcp",
"components": [
{
"id": "client",
"kind": "resource",
"type": "cloud-agnostic.client",
"basis": {
"kind": "explicit",
"text": "External web client sends HTTPS through Cloud Load Balancing to a Cloud Run API, which reads and writes Cloud SQL. Project and region inside organization; cl..."
}
},
{
"id": "org",
"kind": "group",
"type": "gcp.organization",
"basis": {
"kind": "explicit",
"text": "External web client sends HTTPS through Cloud Load Balancing to a Cloud Run API, which reads and writes Cloud SQL. Project and region inside organization; cl..."
}
},
{
"id": "project",
"kind": "group",
"type": "gcp.project",
"basis": {
"kind": "explicit",
"text": "External web client sends HTTPS through Cloud Load Balancing to a Cloud Run API, which reads and writes Cloud SQL. Project and region inside organization; cl..."
}
},
{
"id": "region",
"kind": "group",
"type": "gcp.region",
"basis": {
"kind": "explicit",
"text": "External web client sends HTTPS through Cloud Load Balancing to a Cloud Run API, which reads and writes Cloud SQL. Project and region inside organization; cl..."
}
},
{
"id": "lb",
"kind": "resource",
"type": "gcp.cloud-load-balancing",
"basis": {
"kind": "explicit",
"text": "External web client sends HTTPS through Cloud Load Balancing to a Cloud Run API, which reads and writes Cloud SQL. Project and region inside organization; cl..."
}
},
{
"id": "api",
"kind": "resource",
"type": "gcp.cloud-run",
"basis": {
"kind": "explicit",
"text": "External web client sends HTTPS through Cloud Load Balancing to a Cloud Run API, which reads and writes Cloud SQL. Project and region inside organization; cl..."
}
},
{
"id": "db",
"kind": "resource",
"type": "gcp.cloud-sql",
"basis": {
"kind": "explicit",
"text": "External web client sends HTTPS through Cloud Load Balancing to a Cloud Run API, which reads and writes Cloud SQL. Project and region inside organization; cl..."
}
}
],
"relationships": [
{
"id": "https",
"source": "client",
"target": "lb",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "HTTPS (client to lb) per the request."
}
},
{
"id": "route",
"source": "lb",
"target": "api",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Route (lb to api) per the request."
}
},
{
"id": "records",
"source": "api",
"target": "db",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Read/write records (api to db) per the request."
}
}
],
"counts": [],
"placement": [
{
"id": "client_root",
"component": "client",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "org_root",
"component": "org",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "project_in_org",
"component": "project",
"relation": "parent",
"group": "org",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "region_in_project",
"component": "region",
"relation": "parent",
"group": "project",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "lb_in_region",
"component": "lb",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "api_in_region",
"component": "api",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "db_in_region",
"component": "db",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
}
],
"allowAdditionalResources": false
}
Download Requirements ↓ GCP Document Processing
Draw a left-to-right Google Cloud document-processing architecture. A partner uploads documents through a Cloud Run intake service, which stores original files in a Cloud Storage source bucket. Object notifications from the source bucket publish to Pub/Sub; a second Cloud Run service consumes those events, reads the original file, stores normalized output in a separate Cloud Storage bucket, and writes processing status and metadata to Cloud SQL. Nest the project and primary region inside a Google Cloud organization, with all Google Cloud services in the region. Keep the partner outside the organization. Add no other services and use automatic routing.Download Prompt ↓
dgm 1
diagram gcp-medium-document-processing {
grammar gcp
flow lr
title "GCP Document Processing"
gcp.organization organization "Google Cloud Organization" {
gcp.project project "Document Processing Project" {
gcp.region region "Primary Region" {
gcp.cloud-run intake "Cloud Run Intake" {}
gcp.cloud-storage source_bucket "Source Bucket" {}
gcp.pub-sub notifications "Pub/Sub Object Notifications" {}
gcp.cloud-run processor "Cloud Run Processor" {}
gcp.cloud-storage output_bucket "Output Bucket" {}
gcp.cloud-sql status_db "Cloud SQL Status and Metadata" {}
}
}
}
cloud-agnostic.actor partner "Partner" {}
partner -> intake { id upload_document label "upload document" step 1 }
intake -> source_bucket { id store_original label "store original" step 2 }
source_bucket -> notifications { id publish_object_notification label "object notification" step 3 }
notifications -> processor { id deliver_event label "deliver event" step 4 }
source_bucket -> processor { id read_original label "original file" step 5 }
processor -> output_bucket { id store_normalized label "store normalized output" step 6 }
processor -> status_db { id write_status_metadata label "write status and metadata" step 6 }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "gcp",
"components": [
{
"id": "organization",
"kind": "group",
"type": "gcp.organization",
"basis": {
"kind": "explicit",
"text": "Nest project and primary region inside a Google Cloud organization."
}
},
{
"id": "project",
"kind": "group",
"type": "gcp.project",
"basis": {
"kind": "explicit",
"text": "Nest project and primary region inside a Google Cloud organization."
}
},
{
"id": "region",
"kind": "group",
"type": "gcp.region",
"basis": {
"kind": "explicit",
"text": "Nest project and primary region inside a Google Cloud organization."
}
},
{
"id": "partner",
"kind": "resource",
"type": "cloud-agnostic.actor",
"basis": {
"kind": "explicit",
"text": "Keep the partner outside the organization."
}
},
{
"id": "intake",
"kind": "resource",
"type": "gcp.cloud-run",
"basis": {
"kind": "explicit",
"text": "Place all Google Cloud services in the primary region."
}
},
{
"id": "source_bucket",
"kind": "resource",
"type": "gcp.cloud-storage",
"basis": {
"kind": "explicit",
"text": "Place all Google Cloud services in the primary region."
}
},
{
"id": "notifications",
"kind": "resource",
"type": "gcp.pub-sub",
"basis": {
"kind": "explicit",
"text": "Place all Google Cloud services in the primary region."
}
},
{
"id": "processor",
"kind": "resource",
"type": "gcp.cloud-run",
"basis": {
"kind": "explicit",
"text": "Place all Google Cloud services in the primary region."
}
},
{
"id": "output_bucket",
"kind": "resource",
"type": "gcp.cloud-storage",
"basis": {
"kind": "explicit",
"text": "Place all Google Cloud services in the primary region."
}
},
{
"id": "status_db",
"kind": "resource",
"type": "gcp.cloud-sql",
"basis": {
"kind": "explicit",
"text": "Place all Google Cloud services in the primary region."
}
}
],
"relationships": [
{
"id": "upload_document",
"source": "partner",
"target": "intake",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "store_original",
"source": "intake",
"target": "source_bucket",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "publish_object_notification",
"source": "source_bucket",
"target": "notifications",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "deliver_event",
"source": "notifications",
"target": "processor",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "read_original",
"source": "source_bucket",
"target": "processor",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "store_normalized",
"source": "processor",
"target": "output_bucket",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "write_status_metadata",
"source": "processor",
"target": "status_db",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
}
],
"counts": [
{
"id": "count_gcp_organization",
"kind": "group",
"type": "gcp.organization",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.organization component(s) as requested."
}
},
{
"id": "count_gcp_project_in_organization",
"kind": "group",
"type": "gcp.project",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.project component(s) as requested."
},
"within": "organization"
},
{
"id": "count_gcp_region_in_project",
"kind": "group",
"type": "gcp.region",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.region component(s) as requested."
},
"within": "project"
},
{
"id": "count_cloud-agnostic_actor",
"kind": "resource",
"type": "cloud-agnostic.actor",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 cloud-agnostic.actor component(s) as requested."
}
},
{
"id": "count_gcp_cloud-run_in_region",
"kind": "resource",
"type": "gcp.cloud-run",
"min": 2,
"max": 2,
"basis": {
"kind": "explicit",
"text": "2 gcp.cloud-run component(s) as requested."
},
"within": "region"
},
{
"id": "count_gcp_cloud-storage_in_region",
"kind": "resource",
"type": "gcp.cloud-storage",
"min": 2,
"max": 2,
"basis": {
"kind": "explicit",
"text": "2 gcp.cloud-storage component(s) as requested."
},
"within": "region"
},
{
"id": "count_gcp_pub-sub_in_region",
"kind": "resource",
"type": "gcp.pub-sub",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.pub-sub component(s) as requested."
},
"within": "region"
},
{
"id": "count_gcp_cloud-sql_in_region",
"kind": "resource",
"type": "gcp.cloud-sql",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.cloud-sql component(s) as requested."
},
"within": "region"
}
],
"placement": [
{
"id": "organization_root",
"component": "organization",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Nest project and primary region inside a Google Cloud organization."
}
},
{
"id": "project_parent",
"component": "project",
"relation": "parent",
"group": "organization",
"basis": {
"kind": "explicit",
"text": "Nest project and primary region inside a Google Cloud organization."
}
},
{
"id": "region_parent",
"component": "region",
"relation": "parent",
"group": "project",
"basis": {
"kind": "explicit",
"text": "Nest project and primary region inside a Google Cloud organization."
}
},
{
"id": "partner_root",
"component": "partner",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Keep the partner outside the organization."
}
},
{
"id": "intake_parent",
"component": "intake",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Place all Google Cloud services in the primary region."
}
},
{
"id": "source_bucket_parent",
"component": "source_bucket",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Place all Google Cloud services in the primary region."
}
},
{
"id": "notifications_parent",
"component": "notifications",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Place all Google Cloud services in the primary region."
}
},
{
"id": "processor_parent",
"component": "processor",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Place all Google Cloud services in the primary region."
}
},
{
"id": "output_bucket_parent",
"component": "output_bucket",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Place all Google Cloud services in the primary region."
}
},
{
"id": "status_db_parent",
"component": "status_db",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Place all Google Cloud services in the primary region."
}
}
],
"allowAdditionalResources": false
}
Download Requirements ↓ Draw a left-to-right Google Cloud document-processing architecture. A partner uploads documents through a Cloud Run intake service, which stores original files in a Cloud Storage source bucket. Object notifications from the source bucket publish to Pub/Sub; a second Cloud Run service consumes those events, reads the original file, stores normalized output in a separate Cloud Storage bucket, and writes processing status and metadata to Cloud SQL. Nest the project and primary region inside a Google Cloud organization, with all Google Cloud services in the region. Keep the partner outside the organization. Add no other services and use automatic routing.Download Prompt ↓
dgm 1
diagram gcp-medium-document-processing {
grammar gcp
flow lr
title "Google Cloud document processing"
cloud-agnostic.client partner "Partner"
gcp.organization org "Google Cloud organization" {
gcp.project project "Project" {
gcp.region region "Primary region" {
gcp.cloud-run intake "Intake service"
gcp.cloud-storage source "Source bucket"
gcp.pub-sub events "Object events"
gcp.cloud-run processor "Processing service"
gcp.cloud-storage output "Normalized bucket"
gcp.cloud-sql db "Status and metadata"
}
}
}
partner -> intake { id upload step 1 label "Upload" kind flow }
intake -> source { id store step 2 label "Store original" kind flow }
source -> events { id notify step 3 label "Object notifications" kind flow }
events -> processor { id deliver step 4 label "Events" kind flow }
source -> processor { id read step 4 label "Read original" kind flow }
processor -> output { id write step 5 label "Normalized output" kind flow }
processor -> db { id status step 5 label "Status and metadata" kind flow }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "gcp",
"components": [
{
"id": "partner",
"kind": "resource",
"type": "cloud-agnostic.client",
"basis": {
"kind": "explicit",
"text": "Partner uploads via Cloud Run intake to source bucket; notifications publish to Pub/Sub; second Cloud Run reads the original, stores normalized output in a s..."
}
},
{
"id": "org",
"kind": "group",
"type": "gcp.organization",
"basis": {
"kind": "explicit",
"text": "Partner uploads via Cloud Run intake to source bucket; notifications publish to Pub/Sub; second Cloud Run reads the original, stores normalized output in a s..."
}
},
{
"id": "project",
"kind": "group",
"type": "gcp.project",
"basis": {
"kind": "explicit",
"text": "Partner uploads via Cloud Run intake to source bucket; notifications publish to Pub/Sub; second Cloud Run reads the original, stores normalized output in a s..."
}
},
{
"id": "region",
"kind": "group",
"type": "gcp.region",
"basis": {
"kind": "explicit",
"text": "Partner uploads via Cloud Run intake to source bucket; notifications publish to Pub/Sub; second Cloud Run reads the original, stores normalized output in a s..."
}
},
{
"id": "intake",
"kind": "resource",
"type": "gcp.cloud-run",
"basis": {
"kind": "explicit",
"text": "Partner uploads via Cloud Run intake to source bucket; notifications publish to Pub/Sub; second Cloud Run reads the original, stores normalized output in a s..."
}
},
{
"id": "source",
"kind": "resource",
"type": "gcp.cloud-storage",
"basis": {
"kind": "explicit",
"text": "Partner uploads via Cloud Run intake to source bucket; notifications publish to Pub/Sub; second Cloud Run reads the original, stores normalized output in a s..."
}
},
{
"id": "events",
"kind": "resource",
"type": "gcp.pub-sub",
"basis": {
"kind": "explicit",
"text": "Partner uploads via Cloud Run intake to source bucket; notifications publish to Pub/Sub; second Cloud Run reads the original, stores normalized output in a s..."
}
},
{
"id": "processor",
"kind": "resource",
"type": "gcp.cloud-run",
"basis": {
"kind": "explicit",
"text": "Partner uploads via Cloud Run intake to source bucket; notifications publish to Pub/Sub; second Cloud Run reads the original, stores normalized output in a s..."
}
},
{
"id": "output",
"kind": "resource",
"type": "gcp.cloud-storage",
"basis": {
"kind": "explicit",
"text": "Partner uploads via Cloud Run intake to source bucket; notifications publish to Pub/Sub; second Cloud Run reads the original, stores normalized output in a s..."
}
},
{
"id": "db",
"kind": "resource",
"type": "gcp.cloud-sql",
"basis": {
"kind": "explicit",
"text": "Partner uploads via Cloud Run intake to source bucket; notifications publish to Pub/Sub; second Cloud Run reads the original, stores normalized output in a s..."
}
}
],
"relationships": [
{
"id": "upload",
"source": "partner",
"target": "intake",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Upload (partner to intake) per the request."
}
},
{
"id": "store",
"source": "intake",
"target": "source",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Store original (intake to source) per the request."
}
},
{
"id": "notify",
"source": "source",
"target": "events",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Object notifications (source to events) per the request."
}
},
{
"id": "deliver",
"source": "events",
"target": "processor",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Events (events to processor) per the request."
}
},
{
"id": "read",
"source": "source",
"target": "processor",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Read original (source to processor) per the request."
}
},
{
"id": "write",
"source": "processor",
"target": "output",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Normalized output (processor to output) per the request."
}
},
{
"id": "status",
"source": "processor",
"target": "db",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Status and metadata (processor to db) per the request."
}
}
],
"counts": [],
"placement": [
{
"id": "partner_root",
"component": "partner",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "org_root",
"component": "org",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "project_in_org",
"component": "project",
"relation": "parent",
"group": "org",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "region_in_project",
"component": "region",
"relation": "parent",
"group": "project",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "intake_in_region",
"component": "intake",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "source_in_region",
"component": "source",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "events_in_region",
"component": "events",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "processor_in_region",
"component": "processor",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "output_in_region",
"component": "output",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "db_in_region",
"component": "db",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
}
],
"allowAdditionalResources": false
}
Download Requirements ↓ GCP Webhook Event Pipeline
Draw a left-to-right Google Cloud webhook event pipeline. A partner sends webhook events through Cloud Load Balancing to a Cloud Functions ingress handler. The handler publishes to a Pub/Sub topic; Pub/Sub sends events to Dataflow for processing. Dataflow writes processed records to BigQuery and raw event files to Cloud Storage. Keep the partner outside the Google Cloud organization. Nest the event-processing project and primary region in the organization, and place all services in the region. Add no other services and use automatic routing.Download Prompt ↓
dgm 1
diagram gcp-medium-webhook-event-pipeline {
grammar gcp
flow lr
title "GCP Webhook Event Pipeline"
gcp.organization organization "Google Cloud Organization" {
gcp.project project "Event Processing Project" {
gcp.region region "Primary Region" {
gcp.cloud-load-balancing load_balancing "Cloud Load Balancing" {}
gcp.cloud-functions ingress "Cloud Functions Ingress" {}
gcp.pub-sub topic "Pub/Sub Topic" {}
gcp.dataflow dataflow "Dataflow" {}
gcp.bigquery bigquery "BigQuery" {}
gcp.cloud-storage raw_storage "Cloud Storage Raw Events" {}
}
}
}
cloud-agnostic.actor partner "Partner" {}
partner -> load_balancing { id send_webhook label "webhook event" step 1 }
load_balancing -> ingress { id forward_to_ingress label "forward event" step 2 }
ingress -> topic { id publish_event label "publish event" step 3 }
topic -> dataflow { id stream_to_dataflow label "process events" step 4 }
dataflow -> bigquery { id write_records label "processed records" step 5 }
dataflow -> raw_storage { id write_raw_files label "raw event files" step 5 }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "gcp",
"components": [
{
"id": "organization",
"kind": "group",
"type": "gcp.organization",
"basis": {
"kind": "explicit",
"text": "Nest the project and primary region in the organization."
}
},
{
"id": "project",
"kind": "group",
"type": "gcp.project",
"basis": {
"kind": "explicit",
"text": "Nest the event-processing project in the organization."
}
},
{
"id": "region",
"kind": "group",
"type": "gcp.region",
"basis": {
"kind": "explicit",
"text": "Nest the primary region in the project."
}
},
{
"id": "partner",
"kind": "resource",
"type": "cloud-agnostic.actor",
"basis": {
"kind": "explicit",
"text": "Keep the partner outside the organization."
}
},
{
"id": "load_balancing",
"kind": "resource",
"type": "gcp.cloud-load-balancing",
"basis": {
"kind": "explicit",
"text": "Place all services in the primary region."
}
},
{
"id": "ingress",
"kind": "resource",
"type": "gcp.cloud-functions",
"basis": {
"kind": "explicit",
"text": "Place all services in the primary region."
}
},
{
"id": "topic",
"kind": "resource",
"type": "gcp.pub-sub",
"basis": {
"kind": "explicit",
"text": "Place all services in the primary region."
}
},
{
"id": "dataflow",
"kind": "resource",
"type": "gcp.dataflow",
"basis": {
"kind": "explicit",
"text": "Place all services in the primary region."
}
},
{
"id": "bigquery",
"kind": "resource",
"type": "gcp.bigquery",
"basis": {
"kind": "explicit",
"text": "Place all services in the primary region."
}
},
{
"id": "raw_storage",
"kind": "resource",
"type": "gcp.cloud-storage",
"basis": {
"kind": "explicit",
"text": "Place all services in the primary region."
}
}
],
"relationships": [
{
"id": "send_webhook",
"source": "partner",
"target": "load_balancing",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "forward_to_ingress",
"source": "load_balancing",
"target": "ingress",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "publish_event",
"source": "ingress",
"target": "topic",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "stream_to_dataflow",
"source": "topic",
"target": "dataflow",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "write_records",
"source": "dataflow",
"target": "bigquery",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "write_raw_files",
"source": "dataflow",
"target": "raw_storage",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
}
],
"counts": [
{
"id": "count_gcp_organization",
"kind": "group",
"type": "gcp.organization",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.organization component(s) as requested."
}
},
{
"id": "count_gcp_project_in_organization",
"kind": "group",
"type": "gcp.project",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.project component(s) as requested."
},
"within": "organization"
},
{
"id": "count_gcp_region_in_project",
"kind": "group",
"type": "gcp.region",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.region component(s) as requested."
},
"within": "project"
},
{
"id": "count_cloud-agnostic_actor",
"kind": "resource",
"type": "cloud-agnostic.actor",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 cloud-agnostic.actor component(s) as requested."
}
},
{
"id": "count_gcp_cloud-load-balancing_in_region",
"kind": "resource",
"type": "gcp.cloud-load-balancing",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.cloud-load-balancing component(s) as requested."
},
"within": "region"
},
{
"id": "count_gcp_cloud-functions_in_region",
"kind": "resource",
"type": "gcp.cloud-functions",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.cloud-functions component(s) as requested."
},
"within": "region"
},
{
"id": "count_gcp_pub-sub_in_region",
"kind": "resource",
"type": "gcp.pub-sub",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.pub-sub component(s) as requested."
},
"within": "region"
},
{
"id": "count_gcp_dataflow_in_region",
"kind": "resource",
"type": "gcp.dataflow",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.dataflow component(s) as requested."
},
"within": "region"
},
{
"id": "count_gcp_bigquery_in_region",
"kind": "resource",
"type": "gcp.bigquery",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.bigquery component(s) as requested."
},
"within": "region"
},
{
"id": "count_gcp_cloud-storage_in_region",
"kind": "resource",
"type": "gcp.cloud-storage",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.cloud-storage component(s) as requested."
},
"within": "region"
}
],
"placement": [
{
"id": "organization_root",
"component": "organization",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Nest the project and primary region in the organization."
}
},
{
"id": "project_parent",
"component": "project",
"relation": "parent",
"group": "organization",
"basis": {
"kind": "explicit",
"text": "Nest the event-processing project in the organization."
}
},
{
"id": "region_parent",
"component": "region",
"relation": "parent",
"group": "project",
"basis": {
"kind": "explicit",
"text": "Nest the primary region in the project."
}
},
{
"id": "partner_root",
"component": "partner",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Keep the partner outside the organization."
}
},
{
"id": "load_balancing_parent",
"component": "load_balancing",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Place all services in the primary region."
}
},
{
"id": "ingress_parent",
"component": "ingress",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Place all services in the primary region."
}
},
{
"id": "topic_parent",
"component": "topic",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Place all services in the primary region."
}
},
{
"id": "dataflow_parent",
"component": "dataflow",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Place all services in the primary region."
}
},
{
"id": "bigquery_parent",
"component": "bigquery",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Place all services in the primary region."
}
},
{
"id": "raw_storage_parent",
"component": "raw_storage",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Place all services in the primary region."
}
}
],
"allowAdditionalResources": false
}
Download Requirements ↓ Draw a left-to-right Google Cloud webhook event pipeline. A partner sends webhook events through Cloud Load Balancing to a Cloud Functions ingress handler. The handler publishes to a Pub/Sub topic; Pub/Sub sends events to Dataflow for processing. Dataflow writes processed records to BigQuery and raw event files to Cloud Storage. Keep the partner outside the Google Cloud organization. Nest the event-processing project and primary region in the organization, and place all services in the region. Add no other services and use automatic routing.Download Prompt ↓
dgm 1
diagram gcp-medium-webhook-event-pipeline {
grammar gcp
flow lr
title "Google Cloud webhook event pipeline"
cloud-agnostic.client partner "Partner"
gcp.organization org "Google Cloud organization" {
gcp.project project "Project" {
gcp.region region "Primary region" {
gcp.cloud-load-balancing lb "Load balancer"
gcp.cloud-functions ingress "Ingress handler"
gcp.pub-sub topic "Event topic"
gcp.dataflow dataflow "Event processing"
gcp.bigquery bq "Processed records"
gcp.cloud-storage raw "Raw event files"
}
}
}
partner -> lb { id webhook step 1 label "Webhook events" kind flow }
lb -> ingress { id route step 2 label "Route" kind flow }
ingress -> topic { id publish step 3 label "Publish" kind flow }
topic -> dataflow { id process step 4 label "Events" kind flow }
dataflow -> bq { id records step 5 label "Processed records" kind flow }
dataflow -> raw { id raw_files step 5 label "Raw files" kind flow }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "gcp",
"components": [
{
"id": "partner",
"kind": "resource",
"type": "cloud-agnostic.client",
"basis": {
"kind": "explicit",
"text": "Partner webhooks via Cloud Load Balancing to Cloud Functions ingress; publishes to Pub/Sub; Dataflow writes records to BigQuery and raw files to Cloud Storage."
}
},
{
"id": "org",
"kind": "group",
"type": "gcp.organization",
"basis": {
"kind": "explicit",
"text": "Partner webhooks via Cloud Load Balancing to Cloud Functions ingress; publishes to Pub/Sub; Dataflow writes records to BigQuery and raw files to Cloud Storage."
}
},
{
"id": "project",
"kind": "group",
"type": "gcp.project",
"basis": {
"kind": "explicit",
"text": "Partner webhooks via Cloud Load Balancing to Cloud Functions ingress; publishes to Pub/Sub; Dataflow writes records to BigQuery and raw files to Cloud Storage."
}
},
{
"id": "region",
"kind": "group",
"type": "gcp.region",
"basis": {
"kind": "explicit",
"text": "Partner webhooks via Cloud Load Balancing to Cloud Functions ingress; publishes to Pub/Sub; Dataflow writes records to BigQuery and raw files to Cloud Storage."
}
},
{
"id": "lb",
"kind": "resource",
"type": "gcp.cloud-load-balancing",
"basis": {
"kind": "explicit",
"text": "Partner webhooks via Cloud Load Balancing to Cloud Functions ingress; publishes to Pub/Sub; Dataflow writes records to BigQuery and raw files to Cloud Storage."
}
},
{
"id": "ingress",
"kind": "resource",
"type": "gcp.cloud-functions",
"basis": {
"kind": "explicit",
"text": "Partner webhooks via Cloud Load Balancing to Cloud Functions ingress; publishes to Pub/Sub; Dataflow writes records to BigQuery and raw files to Cloud Storage."
}
},
{
"id": "topic",
"kind": "resource",
"type": "gcp.pub-sub",
"basis": {
"kind": "explicit",
"text": "Partner webhooks via Cloud Load Balancing to Cloud Functions ingress; publishes to Pub/Sub; Dataflow writes records to BigQuery and raw files to Cloud Storage."
}
},
{
"id": "dataflow",
"kind": "resource",
"type": "gcp.dataflow",
"basis": {
"kind": "explicit",
"text": "Partner webhooks via Cloud Load Balancing to Cloud Functions ingress; publishes to Pub/Sub; Dataflow writes records to BigQuery and raw files to Cloud Storage."
}
},
{
"id": "bq",
"kind": "resource",
"type": "gcp.bigquery",
"basis": {
"kind": "explicit",
"text": "Partner webhooks via Cloud Load Balancing to Cloud Functions ingress; publishes to Pub/Sub; Dataflow writes records to BigQuery and raw files to Cloud Storage."
}
},
{
"id": "raw",
"kind": "resource",
"type": "gcp.cloud-storage",
"basis": {
"kind": "explicit",
"text": "Partner webhooks via Cloud Load Balancing to Cloud Functions ingress; publishes to Pub/Sub; Dataflow writes records to BigQuery and raw files to Cloud Storage."
}
}
],
"relationships": [
{
"id": "webhook",
"source": "partner",
"target": "lb",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Webhook events (partner to lb) per the request."
}
},
{
"id": "route",
"source": "lb",
"target": "ingress",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Route (lb to ingress) per the request."
}
},
{
"id": "publish",
"source": "ingress",
"target": "topic",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Publish (ingress to topic) per the request."
}
},
{
"id": "process",
"source": "topic",
"target": "dataflow",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Events (topic to dataflow) per the request."
}
},
{
"id": "records",
"source": "dataflow",
"target": "bq",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Processed records (dataflow to bq) per the request."
}
},
{
"id": "raw_files",
"source": "dataflow",
"target": "raw",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Raw files (dataflow to raw) per the request."
}
}
],
"counts": [],
"placement": [
{
"id": "partner_root",
"component": "partner",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "org_root",
"component": "org",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "project_in_org",
"component": "project",
"relation": "parent",
"group": "org",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "region_in_project",
"component": "region",
"relation": "parent",
"group": "project",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "lb_in_region",
"component": "lb",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "ingress_in_region",
"component": "ingress",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "topic_in_region",
"component": "topic",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "dataflow_in_region",
"component": "dataflow",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "bq_in_region",
"component": "bq",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "raw_in_region",
"component": "raw",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
}
],
"allowAdditionalResources": false
}
Download Requirements ↓ GCP Media Processing
Review note: Strict validation reports 4 routing findings, mostly plain arrow crossings; accepted in review.
Create a GCP media processing architecture. An external media producer sends uploads through Cloud Load Balancing to a regional Cloud Run ingest service. Ingest writes the input object to Cloud Storage and publishes a job to a global Pub/Sub jobs topic. Two Compute Engine workers in separate regional subnets of one VPC consume jobs. Each worker reads input objects, writes processed objects, updates Cloud SQL job status, and publishes completion to a global Pub/Sub topic. Cloud Run notification service delivers completion to an external operations client. Jobs dead-letter to a second Pub/Sub topic. The operations client can inspect dead letters and deliberately redrive them to the jobs topic. Keep global services at project scope, regional services in their region, and show the organization/project. Do not treat a subnet as an availability zone.Download Prompt ↓
dgm 1
diagram gcp-hard-media-processing {
grammar gcp
flow lr
title "GCP Media Processing"
gcp.organization organization "Google Cloud Organization" {
gcp.project project "Media Processing Project" {
gcp.region region "Primary Region" {
gcp.cloud-run ingest "Cloud Run Ingest" {}
gcp.cloud-storage input_bucket "Input Objects" {}
gcp.vpc vpc "Worker VPC" {
gcp.subnet subnet_b "Worker Subnet B" {
gcp.compute-engine worker_b "Compute Engine Worker B" {}
}
gcp.subnet subnet_a "Worker Subnet A" {
gcp.compute-engine worker_a "Compute Engine Worker A" {}
}
}
gcp.cloud-storage output_bucket "Processed Objects" {}
gcp.cloud-sql status_db "Cloud SQL Job Status" {}
gcp.cloud-run notification "Cloud Run Notification Service" {}
}
gcp.cloud-load-balancing load_balancer "Cloud Load Balancing" {}
gcp.pub-sub jobs_topic "Global Jobs Topic" {}
gcp.pub-sub completion_topic "Global Completion Topic" {}
gcp.pub-sub dead_letter_topic "Global Dead Letter Topic" {}
}
}
cloud-agnostic.actor producer "Media Producer" {}
cloud-agnostic.client operations_client "Operations Client" {}
producer -> load_balancer { id producer_upload label "media upload" step 1 }
load_balancer -> ingest { id route_ingest label "route upload" step 2 }
ingest -> input_bucket { id store_input label "store input object" step 3 }
ingest -> jobs_topic { id publish_job label "publish job" step 3 }
jobs_topic -> worker_a { id dispatch_worker_a label "consume job" step 4 }
jobs_topic -> worker_b { id dispatch_worker_b label "consume job" step 4 }
input_bucket -> worker_a { id read_input_a label "input object" step 5 }
input_bucket -> worker_b { id read_input_b label "input object" step 5 }
worker_a -> output_bucket { id write_output_a label "write processed object" step 6 }
worker_b -> output_bucket { id write_output_b label "write processed object" step 6 }
worker_a -> status_db { id update_status_a label "update job status" step 6 }
worker_b -> status_db { id update_status_b label "update job status" step 6 }
worker_a -> completion_topic { id publish_completion_a label "publish completion" step 6 }
worker_b -> completion_topic { id publish_completion_b label "publish completion" step 6 }
completion_topic -> notification { id deliver_completion label "deliver completion" step 7 }
notification -> operations_client { id notify_operations label "completion notice" step 8 }
jobs_topic -> dead_letter_topic { id dead_letter_failed label "retry limit reached" style dashed kind fail }
operations_client -> dead_letter_topic { id inspect_dead_letters label "inspect dead letters" style dashed kind peer }
operations_client -> jobs_topic { id trigger_redrive label "trigger redrive" style dashed kind peer }
dead_letter_topic -> jobs_topic { id redrive_jobs label "redrive messages" style dashed kind peer }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "gcp",
"components": [
{
"id": "organization",
"kind": "group",
"type": "gcp.organization",
"basis": {
"kind": "explicit",
"text": "Show the Google Cloud organization and project."
}
},
{
"id": "project",
"kind": "group",
"type": "gcp.project",
"basis": {
"kind": "explicit",
"text": "Show the Google Cloud organization and project."
}
},
{
"id": "region",
"kind": "group",
"type": "gcp.region",
"basis": {
"kind": "explicit",
"text": "Use regional placement for regional services."
}
},
{
"id": "producer",
"kind": "resource",
"type": "cloud-agnostic.actor",
"basis": {
"kind": "explicit",
"text": "Keep the media producer outside the organization."
}
},
{
"id": "operations_client",
"kind": "resource",
"type": "cloud-agnostic.client",
"basis": {
"kind": "explicit",
"text": "Keep the operations client outside the organization."
}
},
{
"id": "load_balancer",
"kind": "resource",
"type": "gcp.cloud-load-balancing",
"basis": {
"kind": "explicit",
"text": "The Cloud Run ingest is regional; global services are at project scope."
}
},
{
"id": "ingest",
"kind": "resource",
"type": "gcp.cloud-run",
"basis": {
"kind": "explicit",
"text": "The ingest service is regional."
}
},
{
"id": "input_bucket",
"kind": "resource",
"type": "gcp.cloud-storage",
"basis": {
"kind": "explicit",
"text": "Ingest writes input objects; workers read them."
}
},
{
"id": "jobs_topic",
"kind": "resource",
"type": "gcp.pub-sub",
"basis": {
"kind": "explicit",
"text": "Keep global Pub/Sub services at project scope."
}
},
{
"id": "vpc",
"kind": "group",
"type": "gcp.vpc",
"basis": {
"kind": "explicit",
"text": "Both workers are in separate regional subnets of one VPC."
}
},
{
"id": "subnet_b",
"kind": "group",
"type": "gcp.subnet",
"basis": {
"kind": "explicit",
"text": "Workers use separate regional subnets of one VPC."
}
},
{
"id": "worker_b",
"kind": "resource",
"type": "gcp.compute-engine",
"basis": {
"kind": "explicit",
"text": "Two Compute Engine workers run in separate regional subnets of one VPC."
}
},
{
"id": "subnet_a",
"kind": "group",
"type": "gcp.subnet",
"basis": {
"kind": "explicit",
"text": "Workers use separate regional subnets of one VPC."
}
},
{
"id": "worker_a",
"kind": "resource",
"type": "gcp.compute-engine",
"basis": {
"kind": "explicit",
"text": "Two Compute Engine workers run in separate regional subnets of one VPC."
}
},
{
"id": "output_bucket",
"kind": "resource",
"type": "gcp.cloud-storage",
"basis": {
"kind": "explicit",
"text": "Workers write processed objects to object storage."
}
},
{
"id": "status_db",
"kind": "resource",
"type": "gcp.cloud-sql",
"basis": {
"kind": "explicit",
"text": "Workers update Cloud SQL job status."
}
},
{
"id": "completion_topic",
"kind": "resource",
"type": "gcp.pub-sub",
"basis": {
"kind": "explicit",
"text": "Keep global Pub/Sub services at project scope."
}
},
{
"id": "notification",
"kind": "resource",
"type": "gcp.cloud-run",
"basis": {
"kind": "explicit",
"text": "Cloud Run notification service is regional."
}
},
{
"id": "dead_letter_topic",
"kind": "resource",
"type": "gcp.pub-sub",
"basis": {
"kind": "explicit",
"text": "Keep global Pub/Sub services at project scope."
}
}
],
"relationships": [
{
"id": "producer_upload",
"source": "producer",
"target": "load_balancer",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "route_ingest",
"source": "load_balancer",
"target": "ingest",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "store_input",
"source": "ingest",
"target": "input_bucket",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "publish_job",
"source": "ingest",
"target": "jobs_topic",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "dispatch_worker_a",
"source": "jobs_topic",
"target": "worker_a",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "dispatch_worker_b",
"source": "jobs_topic",
"target": "worker_b",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "read_input_a",
"source": "input_bucket",
"target": "worker_a",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "read_input_b",
"source": "input_bucket",
"target": "worker_b",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "write_output_a",
"source": "worker_a",
"target": "output_bucket",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "write_output_b",
"source": "worker_b",
"target": "output_bucket",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "update_status_a",
"source": "worker_a",
"target": "status_db",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "update_status_b",
"source": "worker_b",
"target": "status_db",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "publish_completion_a",
"source": "worker_a",
"target": "completion_topic",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "publish_completion_b",
"source": "worker_b",
"target": "completion_topic",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "deliver_completion",
"source": "completion_topic",
"target": "notification",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "notify_operations",
"source": "notification",
"target": "operations_client",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Explicitly requested relationship."
}
},
{
"id": "dead_letter_failed",
"source": "jobs_topic",
"target": "dead_letter_topic",
"kind": "fail",
"basis": {
"kind": "explicit",
"text": "Jobs that reach their retry limit move to a second Pub/Sub dead-letter topic."
}
},
{
"id": "inspect_dead_letters",
"source": "operations_client",
"target": "dead_letter_topic",
"kind": "peer",
"basis": {
"kind": "explicit",
"text": "The operations client can inspect dead letters."
}
},
{
"id": "trigger_redrive",
"source": "operations_client",
"target": "jobs_topic",
"kind": "peer",
"basis": {
"kind": "explicit",
"text": "The operations client deliberately triggers redrive to the jobs topic."
}
},
{
"id": "redrive_jobs",
"source": "dead_letter_topic",
"target": "jobs_topic",
"kind": "peer",
"basis": {
"kind": "explicit",
"text": "The operations client can deliberately redrive dead letters to the jobs topic."
}
}
],
"counts": [
{
"id": "count_gcp_organization",
"kind": "group",
"type": "gcp.organization",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.organization component(s) as requested."
}
},
{
"id": "count_gcp_project_in_organization",
"kind": "group",
"type": "gcp.project",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.project component(s) as requested."
},
"within": "organization"
},
{
"id": "count_gcp_region_in_project",
"kind": "group",
"type": "gcp.region",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.region component(s) as requested."
},
"within": "project"
},
{
"id": "count_cloud-agnostic_actor",
"kind": "resource",
"type": "cloud-agnostic.actor",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 cloud-agnostic.actor component(s) as requested."
}
},
{
"id": "count_cloud-agnostic_client",
"kind": "resource",
"type": "cloud-agnostic.client",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 cloud-agnostic.client component(s) as requested."
}
},
{
"id": "count_gcp_cloud-load-balancing_in_project",
"kind": "resource",
"type": "gcp.cloud-load-balancing",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.cloud-load-balancing component(s) as requested."
},
"within": "project"
},
{
"id": "count_gcp_cloud-run_in_region",
"kind": "resource",
"type": "gcp.cloud-run",
"min": 2,
"max": 2,
"basis": {
"kind": "explicit",
"text": "2 gcp.cloud-run component(s) as requested."
},
"within": "region"
},
{
"id": "count_gcp_cloud-storage_in_region",
"kind": "resource",
"type": "gcp.cloud-storage",
"min": 2,
"max": 2,
"basis": {
"kind": "explicit",
"text": "2 gcp.cloud-storage component(s) as requested."
},
"within": "region"
},
{
"id": "count_gcp_pub-sub_in_project",
"kind": "resource",
"type": "gcp.pub-sub",
"min": 3,
"max": 3,
"basis": {
"kind": "explicit",
"text": "3 gcp.pub-sub component(s) as requested."
},
"within": "project"
},
{
"id": "count_gcp_vpc_in_region",
"kind": "group",
"type": "gcp.vpc",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.vpc component(s) as requested."
},
"within": "region"
},
{
"id": "count_gcp_subnet_in_vpc",
"kind": "group",
"type": "gcp.subnet",
"min": 2,
"max": 2,
"basis": {
"kind": "explicit",
"text": "2 gcp.subnet component(s) as requested."
},
"within": "vpc"
},
{
"id": "count_gcp_compute-engine_in_vpc",
"kind": "resource",
"type": "gcp.compute-engine",
"min": 2,
"max": 2,
"basis": {
"kind": "explicit",
"text": "2 gcp.compute-engine component(s) as requested."
},
"within": "vpc"
},
{
"id": "count_gcp_cloud-sql_in_region",
"kind": "resource",
"type": "gcp.cloud-sql",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "1 gcp.cloud-sql component(s) as requested."
},
"within": "region"
}
],
"placement": [
{
"id": "organization_root",
"component": "organization",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Show the Google Cloud organization and project."
}
},
{
"id": "project_parent",
"component": "project",
"relation": "parent",
"group": "organization",
"basis": {
"kind": "explicit",
"text": "Show the Google Cloud organization and project."
}
},
{
"id": "region_parent",
"component": "region",
"relation": "parent",
"group": "project",
"basis": {
"kind": "explicit",
"text": "Use regional placement for regional services."
}
},
{
"id": "producer_root",
"component": "producer",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Keep the media producer outside the organization."
}
},
{
"id": "operations_client_root",
"component": "operations_client",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Keep the operations client outside the organization."
}
},
{
"id": "load_balancer_parent",
"component": "load_balancer",
"relation": "parent",
"group": "project",
"basis": {
"kind": "explicit",
"text": "The Cloud Run ingest is regional; global services are at project scope."
}
},
{
"id": "ingest_parent",
"component": "ingest",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "The ingest service is regional."
}
},
{
"id": "input_bucket_parent",
"component": "input_bucket",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Ingest writes input objects; workers read them."
}
},
{
"id": "jobs_topic_parent",
"component": "jobs_topic",
"relation": "parent",
"group": "project",
"basis": {
"kind": "explicit",
"text": "Keep global Pub/Sub services at project scope."
}
},
{
"id": "vpc_parent",
"component": "vpc",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Both workers are in separate regional subnets of one VPC."
}
},
{
"id": "subnet_b_parent",
"component": "subnet_b",
"relation": "parent",
"group": "vpc",
"basis": {
"kind": "explicit",
"text": "Workers use separate regional subnets of one VPC."
}
},
{
"id": "worker_b_parent",
"component": "worker_b",
"relation": "parent",
"group": "subnet_b",
"basis": {
"kind": "explicit",
"text": "Two Compute Engine workers run in separate regional subnets of one VPC."
}
},
{
"id": "subnet_a_parent",
"component": "subnet_a",
"relation": "parent",
"group": "vpc",
"basis": {
"kind": "explicit",
"text": "Workers use separate regional subnets of one VPC."
}
},
{
"id": "worker_a_parent",
"component": "worker_a",
"relation": "parent",
"group": "subnet_a",
"basis": {
"kind": "explicit",
"text": "Two Compute Engine workers run in separate regional subnets of one VPC."
}
},
{
"id": "output_bucket_parent",
"component": "output_bucket",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Workers write processed objects to object storage."
}
},
{
"id": "status_db_parent",
"component": "status_db",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Workers update Cloud SQL job status."
}
},
{
"id": "completion_topic_parent",
"component": "completion_topic",
"relation": "parent",
"group": "project",
"basis": {
"kind": "explicit",
"text": "Keep global Pub/Sub services at project scope."
}
},
{
"id": "notification_parent",
"component": "notification",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Cloud Run notification service is regional."
}
},
{
"id": "dead_letter_topic_parent",
"component": "dead_letter_topic",
"relation": "parent",
"group": "project",
"basis": {
"kind": "explicit",
"text": "Keep global Pub/Sub services at project scope."
}
}
],
"allowAdditionalResources": false
}
Download Requirements ↓ Review note: Strict validation reports 12 routing findings, mostly plain arrow crossings; accepted in review.
Create a GCP media processing architecture. An external media producer sends uploads through Cloud Load Balancing to a regional Cloud Run ingest service. Ingest writes the input object to Cloud Storage and publishes a job to a global Pub/Sub jobs topic. Two Compute Engine workers in separate regional subnets of one VPC consume jobs. Each worker reads input objects, writes processed objects, updates Cloud SQL job status, and publishes completion to a global Pub/Sub topic. Cloud Run notification service delivers completion to an external operations client. Jobs dead-letter to a second Pub/Sub topic. The operations client can inspect dead letters and deliberately redrive them to the jobs topic. Keep global services at project scope, regional services in their region, and show the organization/project. Do not treat a subnet as an availability zone.Download Prompt ↓
dgm 1
diagram gcp-hard-media-processing {
grammar gcp
flow lr
title "Google Cloud media processing"
cloud-agnostic.client producer "Media producer"
cloud-agnostic.client ops "Operations client"
gcp.organization org "Google Cloud organization" {
gcp.project project "Project" {
gcp.cloud-load-balancing lb "Load balancer"
gcp.pub-sub jobs "Jobs topic"
gcp.pub-sub completion "Completion topic"
gcp.pub-sub dead "Dead-letter topic"
gcp.region region "Region" {
gcp.cloud-run ingest "Ingest service"
gcp.cloud-storage input "Input bucket"
gcp.cloud-storage output "Output bucket"
gcp.vpc vpc "VPC" {
gcp.subnet subnet_a "Subnet A" {
gcp.compute-engine worker1 "Worker 1"
}
gcp.subnet subnet_b "Subnet B" {
gcp.compute-engine worker2 "Worker 2"
}
}
gcp.cloud-sql db "Job status"
gcp.cloud-run notifier "Notification service"
}
}
}
producer -> lb { id upload step 1 label "Upload" kind flow }
lb -> ingest { id route step 2 label "Route" kind flow }
ingest -> input { id write_input step 3 label "Write input" kind flow }
ingest -> jobs { id publish_job step 3 label "Publish job" kind flow }
jobs -> worker1 { id jobs_w1 step 4 label "Jobs" kind flow }
jobs -> worker2 { id jobs_w2 step 4 label "Jobs" kind flow }
input -> worker1 { id read_w1 step 4 label "Read input" kind flow }
input -> worker2 { id read_w2 step 4 label "Read input" kind flow }
worker1 -> output { id out_w1 step 5 label "Processed objects" kind flow }
worker2 -> output { id out_w2 step 5 label "Processed objects" kind flow }
worker1 -> db { id db_w1 step 5 label "Job status" kind flow }
worker2 -> db { id db_w2 step 5 label "Job status" kind flow }
worker1 -> completion { id done_w1 step 5 label "Completion" kind flow }
worker2 -> completion { id done_w2 step 5 label "Completion" kind flow }
completion -> notifier { id notify step 6 label "Completion events" kind flow }
notifier -> ops { id deliver step 7 label "Deliver notice" kind flow }
jobs -> dead { id dead_letter label "Dead-letter" kind fail }
ops -> dead { id inspect label "Inspect" kind peer style dashed }
dead -> jobs { id redrive label "Redrive" kind flow style dashed }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "gcp",
"components": [
{
"id": "producer",
"kind": "resource",
"type": "cloud-agnostic.client",
"basis": {
"kind": "explicit",
"text": "Producer via Cloud Load Balancing to Cloud Run ingest; Cloud Storage and global Pub/Sub jobs; two Compute Engine workers in separate regional subnets of one ..."
}
},
{
"id": "ops",
"kind": "resource",
"type": "cloud-agnostic.client",
"basis": {
"kind": "explicit",
"text": "Producer via Cloud Load Balancing to Cloud Run ingest; Cloud Storage and global Pub/Sub jobs; two Compute Engine workers in separate regional subnets of one ..."
}
},
{
"id": "org",
"kind": "group",
"type": "gcp.organization",
"basis": {
"kind": "explicit",
"text": "Producer via Cloud Load Balancing to Cloud Run ingest; Cloud Storage and global Pub/Sub jobs; two Compute Engine workers in separate regional subnets of one ..."
}
},
{
"id": "project",
"kind": "group",
"type": "gcp.project",
"basis": {
"kind": "explicit",
"text": "Producer via Cloud Load Balancing to Cloud Run ingest; Cloud Storage and global Pub/Sub jobs; two Compute Engine workers in separate regional subnets of one ..."
}
},
{
"id": "lb",
"kind": "resource",
"type": "gcp.cloud-load-balancing",
"basis": {
"kind": "explicit",
"text": "Producer via Cloud Load Balancing to Cloud Run ingest; Cloud Storage and global Pub/Sub jobs; two Compute Engine workers in separate regional subnets of one ..."
}
},
{
"id": "jobs",
"kind": "resource",
"type": "gcp.pub-sub",
"basis": {
"kind": "explicit",
"text": "Producer via Cloud Load Balancing to Cloud Run ingest; Cloud Storage and global Pub/Sub jobs; two Compute Engine workers in separate regional subnets of one ..."
}
},
{
"id": "completion",
"kind": "resource",
"type": "gcp.pub-sub",
"basis": {
"kind": "explicit",
"text": "Producer via Cloud Load Balancing to Cloud Run ingest; Cloud Storage and global Pub/Sub jobs; two Compute Engine workers in separate regional subnets of one ..."
}
},
{
"id": "dead",
"kind": "resource",
"type": "gcp.pub-sub",
"basis": {
"kind": "explicit",
"text": "Producer via Cloud Load Balancing to Cloud Run ingest; Cloud Storage and global Pub/Sub jobs; two Compute Engine workers in separate regional subnets of one ..."
}
},
{
"id": "region",
"kind": "group",
"type": "gcp.region",
"basis": {
"kind": "explicit",
"text": "Producer via Cloud Load Balancing to Cloud Run ingest; Cloud Storage and global Pub/Sub jobs; two Compute Engine workers in separate regional subnets of one ..."
}
},
{
"id": "ingest",
"kind": "resource",
"type": "gcp.cloud-run",
"basis": {
"kind": "explicit",
"text": "Producer via Cloud Load Balancing to Cloud Run ingest; Cloud Storage and global Pub/Sub jobs; two Compute Engine workers in separate regional subnets of one ..."
}
},
{
"id": "input",
"kind": "resource",
"type": "gcp.cloud-storage",
"basis": {
"kind": "explicit",
"text": "Producer via Cloud Load Balancing to Cloud Run ingest; Cloud Storage and global Pub/Sub jobs; two Compute Engine workers in separate regional subnets of one ..."
}
},
{
"id": "output",
"kind": "resource",
"type": "gcp.cloud-storage",
"basis": {
"kind": "inferred",
"text": "Structurally required to place or group the named resources."
}
},
{
"id": "vpc",
"kind": "group",
"type": "gcp.vpc",
"basis": {
"kind": "explicit",
"text": "Producer via Cloud Load Balancing to Cloud Run ingest; Cloud Storage and global Pub/Sub jobs; two Compute Engine workers in separate regional subnets of one ..."
}
},
{
"id": "subnet_a",
"kind": "group",
"type": "gcp.subnet",
"basis": {
"kind": "explicit",
"text": "Producer via Cloud Load Balancing to Cloud Run ingest; Cloud Storage and global Pub/Sub jobs; two Compute Engine workers in separate regional subnets of one ..."
}
},
{
"id": "worker1",
"kind": "resource",
"type": "gcp.compute-engine",
"basis": {
"kind": "explicit",
"text": "Producer via Cloud Load Balancing to Cloud Run ingest; Cloud Storage and global Pub/Sub jobs; two Compute Engine workers in separate regional subnets of one ..."
}
},
{
"id": "subnet_b",
"kind": "group",
"type": "gcp.subnet",
"basis": {
"kind": "explicit",
"text": "Producer via Cloud Load Balancing to Cloud Run ingest; Cloud Storage and global Pub/Sub jobs; two Compute Engine workers in separate regional subnets of one ..."
}
},
{
"id": "worker2",
"kind": "resource",
"type": "gcp.compute-engine",
"basis": {
"kind": "explicit",
"text": "Producer via Cloud Load Balancing to Cloud Run ingest; Cloud Storage and global Pub/Sub jobs; two Compute Engine workers in separate regional subnets of one ..."
}
},
{
"id": "db",
"kind": "resource",
"type": "gcp.cloud-sql",
"basis": {
"kind": "explicit",
"text": "Producer via Cloud Load Balancing to Cloud Run ingest; Cloud Storage and global Pub/Sub jobs; two Compute Engine workers in separate regional subnets of one ..."
}
},
{
"id": "notifier",
"kind": "resource",
"type": "gcp.cloud-run",
"basis": {
"kind": "explicit",
"text": "Producer via Cloud Load Balancing to Cloud Run ingest; Cloud Storage and global Pub/Sub jobs; two Compute Engine workers in separate regional subnets of one ..."
}
}
],
"relationships": [
{
"id": "upload",
"source": "producer",
"target": "lb",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Upload (producer to lb) per the request."
}
},
{
"id": "route",
"source": "lb",
"target": "ingest",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Route (lb to ingest) per the request."
}
},
{
"id": "write_input",
"source": "ingest",
"target": "input",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Write input (ingest to input) per the request."
}
},
{
"id": "publish_job",
"source": "ingest",
"target": "jobs",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Publish job (ingest to jobs) per the request."
}
},
{
"id": "jobs_w1",
"source": "jobs",
"target": "worker1",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Jobs (jobs to worker1) per the request."
}
},
{
"id": "jobs_w2",
"source": "jobs",
"target": "worker2",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Jobs (jobs to worker2) per the request."
}
},
{
"id": "read_w1",
"source": "input",
"target": "worker1",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Read input (input to worker1) per the request."
}
},
{
"id": "read_w2",
"source": "input",
"target": "worker2",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Read input (input to worker2) per the request."
}
},
{
"id": "out_w1",
"source": "worker1",
"target": "output",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Processed objects (worker1 to output) per the request."
}
},
{
"id": "out_w2",
"source": "worker2",
"target": "output",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Processed objects (worker2 to output) per the request."
}
},
{
"id": "db_w1",
"source": "worker1",
"target": "db",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Job status (worker1 to db) per the request."
}
},
{
"id": "db_w2",
"source": "worker2",
"target": "db",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Job status (worker2 to db) per the request."
}
},
{
"id": "done_w1",
"source": "worker1",
"target": "completion",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Completion (worker1 to completion) per the request."
}
},
{
"id": "done_w2",
"source": "worker2",
"target": "completion",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Completion (worker2 to completion) per the request."
}
},
{
"id": "notify",
"source": "completion",
"target": "notifier",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Completion events (completion to notifier) per the request."
}
},
{
"id": "deliver",
"source": "notifier",
"target": "ops",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Deliver notice (notifier to ops) per the request."
}
},
{
"id": "dead_letter",
"source": "jobs",
"target": "dead",
"kind": "fail",
"basis": {
"kind": "explicit",
"text": "Dead-letter (jobs to dead) per the request."
}
},
{
"id": "inspect",
"source": "ops",
"target": "dead",
"kind": "peer",
"basis": {
"kind": "explicit",
"text": "Inspect (ops to dead) per the request."
}
},
{
"id": "redrive",
"source": "dead",
"target": "jobs",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Redrive (dead to jobs) per the request."
}
}
],
"counts": [],
"placement": [
{
"id": "producer_root",
"component": "producer",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "ops_root",
"component": "ops",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "org_root",
"component": "org",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "project_in_org",
"component": "project",
"relation": "parent",
"group": "org",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "lb_in_project",
"component": "lb",
"relation": "parent",
"group": "project",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "jobs_in_project",
"component": "jobs",
"relation": "parent",
"group": "project",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "completion_in_project",
"component": "completion",
"relation": "parent",
"group": "project",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "dead_in_project",
"component": "dead",
"relation": "parent",
"group": "project",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "region_in_project",
"component": "region",
"relation": "parent",
"group": "project",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "ingest_in_region",
"component": "ingest",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "input_in_region",
"component": "input",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "output_in_region",
"component": "output",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "vpc_in_region",
"component": "vpc",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "subnet_a_in_vpc",
"component": "subnet_a",
"relation": "parent",
"group": "vpc",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "worker1_in_subnet_a",
"component": "worker1",
"relation": "parent",
"group": "subnet_a",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "subnet_b_in_vpc",
"component": "subnet_b",
"relation": "parent",
"group": "vpc",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "worker2_in_subnet_b",
"component": "worker2",
"relation": "parent",
"group": "subnet_b",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "db_in_region",
"component": "db",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "notifier_in_region",
"component": "notifier",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "lb_outside_region",
"component": "lb",
"relation": "outside",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
},
{
"id": "jobs_outside_region",
"component": "jobs",
"relation": "outside",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
},
{
"id": "completion_outside_region",
"component": "completion",
"relation": "outside",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
},
{
"id": "dead_outside_region",
"component": "dead",
"relation": "outside",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
}
],
"allowAdditionalResources": true
}
Download Requirements ↓ Cloud-agnostic
Customer Record API
Draw a provider-neutral, left-to-right diagram for a small customer-record API. Show an external web client sending HTTPS requests through an API gateway to a customer API service, which reads and writes a customer database. Nest a production account and primary region inside an application cloud, and place the three services in the region. Keep the client outside the cloud. Do not add provider-specific products or other infrastructure; use automatic routing.Download Prompt ↓
dgm 1
diagram cloud-agnostic-easy-customer-record-api {
grammar cloud-agnostic
flow lr
title "Customer Record API"
cloud-agnostic.cloud application_cloud "Application Cloud" {
cloud-agnostic.account production_account "Production Account" {
cloud-agnostic.region primary_region "Primary Region" {
cloud-agnostic.gateway api_gateway "API Gateway" {}
cloud-agnostic.server customer_api "Customer API" {}
cloud-agnostic.database customer_database "Customer Database" {}
}
}
}
cloud-agnostic.client web_client "Web Client" {}
web_client -> api_gateway { id https_request label "HTTPS request" step 1 kind flow }
api_gateway -> customer_api { id route_to_api label "route" step 2 kind flow }
customer_api -> customer_database { id read_write_records label "read / write" step 3 kind flow }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "cloud-agnostic",
"components": [
{
"id": "application_cloud",
"kind": "group",
"type": "cloud-agnostic.cloud",
"basis": {
"kind": "explicit",
"text": "Nest a production account inside an application cloud."
}
},
{
"id": "production_account",
"kind": "group",
"type": "cloud-agnostic.account",
"basis": {
"kind": "explicit",
"text": "A production account is inside the application cloud."
}
},
{
"id": "primary_region",
"kind": "group",
"type": "cloud-agnostic.region",
"basis": {
"kind": "explicit",
"text": "The primary region is inside the production account."
}
},
{
"id": "web_client",
"kind": "resource",
"type": "cloud-agnostic.client",
"basis": {
"kind": "explicit",
"text": "An external web client sends HTTPS requests."
}
},
{
"id": "api_gateway",
"kind": "resource",
"type": "cloud-agnostic.gateway",
"basis": {
"kind": "explicit",
"text": "Requests pass through an API gateway."
}
},
{
"id": "customer_api",
"kind": "resource",
"type": "cloud-agnostic.server",
"basis": {
"kind": "explicit",
"text": "A customer API service handles requests."
}
},
{
"id": "customer_database",
"kind": "resource",
"type": "cloud-agnostic.database",
"basis": {
"kind": "explicit",
"text": "The API reads and writes customer records in a database."
}
}
],
"relationships": [
{
"id": "https_request",
"source": "web_client",
"target": "api_gateway",
"basis": {
"kind": "explicit",
"text": "The web client sends HTTPS requests through an API gateway."
},
"kind": "flow"
},
{
"id": "route_to_api",
"source": "api_gateway",
"target": "customer_api",
"basis": {
"kind": "explicit",
"text": "The gateway routes requests to the customer API."
},
"kind": "flow"
},
{
"id": "read_write_records",
"source": "customer_api",
"target": "customer_database",
"basis": {
"kind": "explicit",
"text": "The API reads and writes customer records in the database."
},
"kind": "flow"
}
],
"counts": [
{
"id": "exactly_one_application_cloud",
"kind": "group",
"type": "cloud-agnostic.cloud",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "One Application Cloud is specified."
}
},
{
"id": "exactly_one_production_account",
"kind": "group",
"type": "cloud-agnostic.account",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "One Production Account is specified."
},
"within": "application_cloud"
},
{
"id": "exactly_one_primary_region",
"kind": "group",
"type": "cloud-agnostic.region",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "One Primary Region is specified."
},
"within": "production_account"
},
{
"id": "exactly_one_web_client",
"kind": "resource",
"type": "cloud-agnostic.client",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "One Web Client is specified."
}
},
{
"id": "exactly_one_api_gateway",
"kind": "resource",
"type": "cloud-agnostic.gateway",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "One API Gateway is specified."
},
"within": "primary_region"
},
{
"id": "exactly_one_customer_api",
"kind": "resource",
"type": "cloud-agnostic.server",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "One Customer API is specified."
},
"within": "primary_region"
},
{
"id": "exactly_one_customer_database",
"kind": "resource",
"type": "cloud-agnostic.database",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "One Customer Database is specified."
},
"within": "primary_region"
}
],
"placement": [
{
"id": "application_cloud_placement",
"component": "application_cloud",
"relation": "root",
"basis": {
"kind": "inferred",
"text": "Application Cloud is at the diagram root."
}
},
{
"id": "production_account_placement",
"component": "production_account",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Production Account is directly inside Application Cloud."
},
"group": "application_cloud"
},
{
"id": "primary_region_placement",
"component": "primary_region",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Primary Region is directly inside Production Account."
},
"group": "production_account"
},
{
"id": "web_client_placement",
"component": "web_client",
"relation": "outside",
"basis": {
"kind": "explicit",
"text": "Web Client is outside Application Cloud."
},
"group": "application_cloud"
},
{
"id": "api_gateway_placement",
"component": "api_gateway",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "API Gateway is directly inside Primary Region."
},
"group": "primary_region"
},
{
"id": "customer_api_placement",
"component": "customer_api",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Customer API is directly inside Primary Region."
},
"group": "primary_region"
},
{
"id": "customer_database_placement",
"component": "customer_database",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Customer Database is directly inside Primary Region."
},
"group": "primary_region"
}
],
"allowAdditionalResources": false
}
Download Requirements ↓ Draw a provider-neutral, left-to-right diagram for a small customer-record API. Show an external web client sending HTTPS requests through an API gateway to a customer API service, which reads and writes a customer database. Nest a production account and primary region inside an application cloud, and place the three services in the region. Keep the client outside the cloud. Do not add provider-specific products or other infrastructure; use automatic routing.Download Prompt ↓
dgm 1
diagram cloud-agnostic-easy-customer-record-api {
grammar cloud-agnostic
flow lr
title "Customer-record API (cloud-neutral)"
cloud-agnostic.client client "Web client"
cloud-agnostic.cloud cloud "Application cloud" {
cloud-agnostic.account account "Production account" {
cloud-agnostic.region region "Primary region" {
cloud-agnostic.gateway gateway "API gateway"
cloud-agnostic.server api "Customer API"
cloud-agnostic.database db "Customer database"
}
}
}
client -> gateway { id https step 1 label "HTTPS" kind flow }
gateway -> api { id route step 2 label "Route" kind flow }
api -> db { id records step 3 label "Read/write records" kind flow }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "cloud-agnostic",
"components": [
{
"id": "client",
"kind": "resource",
"type": "cloud-agnostic.client",
"basis": {
"kind": "explicit",
"text": "External web client sends HTTPS through an API gateway to a customer API service, which reads and writes a customer database. Production account and primary ..."
}
},
{
"id": "cloud",
"kind": "group",
"type": "cloud-agnostic.cloud",
"basis": {
"kind": "explicit",
"text": "External web client sends HTTPS through an API gateway to a customer API service, which reads and writes a customer database. Production account and primary ..."
}
},
{
"id": "account",
"kind": "group",
"type": "cloud-agnostic.account",
"basis": {
"kind": "explicit",
"text": "External web client sends HTTPS through an API gateway to a customer API service, which reads and writes a customer database. Production account and primary ..."
}
},
{
"id": "region",
"kind": "group",
"type": "cloud-agnostic.region",
"basis": {
"kind": "explicit",
"text": "External web client sends HTTPS through an API gateway to a customer API service, which reads and writes a customer database. Production account and primary ..."
}
},
{
"id": "gateway",
"kind": "resource",
"type": "cloud-agnostic.gateway",
"basis": {
"kind": "explicit",
"text": "External web client sends HTTPS through an API gateway to a customer API service, which reads and writes a customer database. Production account and primary ..."
}
},
{
"id": "api",
"kind": "resource",
"type": "cloud-agnostic.server",
"basis": {
"kind": "explicit",
"text": "External web client sends HTTPS through an API gateway to a customer API service, which reads and writes a customer database. Production account and primary ..."
}
},
{
"id": "db",
"kind": "resource",
"type": "cloud-agnostic.database",
"basis": {
"kind": "explicit",
"text": "External web client sends HTTPS through an API gateway to a customer API service, which reads and writes a customer database. Production account and primary ..."
}
}
],
"relationships": [
{
"id": "https",
"source": "client",
"target": "gateway",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "HTTPS (client to gateway) per the request."
}
},
{
"id": "route",
"source": "gateway",
"target": "api",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Route (gateway to api) per the request."
}
},
{
"id": "records",
"source": "api",
"target": "db",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Read/write records (api to db) per the request."
}
}
],
"counts": [],
"placement": [
{
"id": "client_root",
"component": "client",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "cloud_root",
"component": "cloud",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "account_in_cloud",
"component": "account",
"relation": "parent",
"group": "cloud",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "region_in_account",
"component": "region",
"relation": "parent",
"group": "account",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "gateway_in_region",
"component": "gateway",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "api_in_region",
"component": "api",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "db_in_region",
"component": "db",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
}
],
"allowAdditionalResources": false
}
Download Requirements ↓ Team Project Portal
Create a provider-neutral architecture for a team project portal. Users reach a load balancer that forwards requests to a portal server. The server reads project data from a database, uses a cache for frequent lookups, and retrieves attachments from object storage. Keep the server, database, and cache in a private network; keep the load balancer and object storage outside it. Use a left-to-right automatic layout and add no other services.Download Prompt ↓
dgm 1
diagram cloud-agnostic-medium-team-project-portal {
grammar cloud-agnostic
flow lr
title "Team Project Portal"
cloud-agnostic.cloud application_cloud "Application Cloud" {
cloud-agnostic.network private_network "Private Network" {
cloud-agnostic.server portal_server "Portal Server" {}
cloud-agnostic.database project_database "Project Database" {}
cloud-agnostic.cache lookup_cache "Lookup Cache" {}
}
}
cloud-agnostic.client team_users "Team Users" {}
cloud-agnostic.load-balancer load_balancer "Load Balancer" {}
cloud-agnostic.object-storage attachment_storage "Attachment Storage" {}
team_users -> load_balancer { id users_to_lb label "portal requests" step 1 kind flow }
load_balancer -> portal_server { id lb_to_portal label "forward requests" step 2 kind flow }
portal_server -> project_database { id portal_to_database label "read project data" step 3 kind flow }
portal_server -> lookup_cache { id portal_to_cache label "frequent lookups" step 3 kind flow }
portal_server -> attachment_storage { id portal_to_storage label "retrieve attachments" step 3 kind flow }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "cloud-agnostic",
"components": [
{
"id": "application_cloud",
"kind": "group",
"type": "cloud-agnostic.cloud",
"basis": {
"kind": "inferred",
"text": "The catalog requires a parent for a private network boundary, so a provider-neutral cloud scope supplies the minimal context."
}
},
{
"id": "private_network",
"kind": "group",
"type": "cloud-agnostic.network",
"basis": {
"kind": "explicit",
"text": "The server, database, and cache are kept in a private network."
}
},
{
"id": "team_users",
"kind": "resource",
"type": "cloud-agnostic.client",
"basis": {
"kind": "explicit",
"text": "Users reach the portal."
}
},
{
"id": "load_balancer",
"kind": "resource",
"type": "cloud-agnostic.load-balancer",
"basis": {
"kind": "explicit",
"text": "Users reach a load balancer."
}
},
{
"id": "portal_server",
"kind": "resource",
"type": "cloud-agnostic.server",
"basis": {
"kind": "explicit",
"text": "The load balancer forwards requests to a portal server."
}
},
{
"id": "project_database",
"kind": "resource",
"type": "cloud-agnostic.database",
"basis": {
"kind": "explicit",
"text": "The server reads project data from a database."
}
},
{
"id": "lookup_cache",
"kind": "resource",
"type": "cloud-agnostic.cache",
"basis": {
"kind": "explicit",
"text": "The server uses a cache for frequent lookups."
}
},
{
"id": "attachment_storage",
"kind": "resource",
"type": "cloud-agnostic.object-storage",
"basis": {
"kind": "explicit",
"text": "The server retrieves attachments from object storage."
}
}
],
"relationships": [
{
"id": "users_to_lb",
"source": "team_users",
"target": "load_balancer",
"basis": {
"kind": "explicit",
"text": "Users reach the load balancer."
},
"kind": "flow"
},
{
"id": "lb_to_portal",
"source": "load_balancer",
"target": "portal_server",
"basis": {
"kind": "explicit",
"text": "The load balancer forwards requests to the portal server."
},
"kind": "flow"
},
{
"id": "portal_to_database",
"source": "portal_server",
"target": "project_database",
"basis": {
"kind": "explicit",
"text": "The server reads project data from the database."
},
"kind": "flow"
},
{
"id": "portal_to_cache",
"source": "portal_server",
"target": "lookup_cache",
"basis": {
"kind": "explicit",
"text": "The server uses a cache for frequent lookups."
},
"kind": "flow"
},
{
"id": "portal_to_storage",
"source": "portal_server",
"target": "attachment_storage",
"basis": {
"kind": "explicit",
"text": "The server retrieves attachments from object storage."
},
"kind": "flow"
}
],
"counts": [
{
"id": "exactly_one_application_cloud",
"kind": "group",
"type": "cloud-agnostic.cloud",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "One Application Cloud is specified."
}
},
{
"id": "exactly_one_private_network",
"kind": "group",
"type": "cloud-agnostic.network",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "One Private Network is specified."
},
"within": "application_cloud"
},
{
"id": "exactly_one_team_users",
"kind": "resource",
"type": "cloud-agnostic.client",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "One Team Users is specified."
}
},
{
"id": "exactly_one_load_balancer",
"kind": "resource",
"type": "cloud-agnostic.load-balancer",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "One Load Balancer is specified."
}
},
{
"id": "exactly_one_portal_server",
"kind": "resource",
"type": "cloud-agnostic.server",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "One Portal Server is specified."
},
"within": "private_network"
},
{
"id": "exactly_one_project_database",
"kind": "resource",
"type": "cloud-agnostic.database",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "One Project Database is specified."
},
"within": "private_network"
},
{
"id": "exactly_one_lookup_cache",
"kind": "resource",
"type": "cloud-agnostic.cache",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "One Lookup Cache is specified."
},
"within": "private_network"
},
{
"id": "exactly_one_attachment_storage",
"kind": "resource",
"type": "cloud-agnostic.object-storage",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "One Attachment Storage is specified."
}
}
],
"placement": [
{
"id": "application_cloud_placement",
"component": "application_cloud",
"relation": "root",
"basis": {
"kind": "inferred",
"text": "Application Cloud is at the diagram root."
}
},
{
"id": "private_network_placement",
"component": "private_network",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Private Network is directly inside Application Cloud."
},
"group": "application_cloud"
},
{
"id": "team_users_placement",
"component": "team_users",
"relation": "outside",
"basis": {
"kind": "explicit",
"text": "Team Users is outside Application Cloud."
},
"group": "application_cloud"
},
{
"id": "load_balancer_placement",
"component": "load_balancer",
"relation": "outside",
"basis": {
"kind": "explicit",
"text": "Load Balancer is outside Private Network."
},
"group": "private_network"
},
{
"id": "portal_server_placement",
"component": "portal_server",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Portal Server is directly inside Private Network."
},
"group": "private_network"
},
{
"id": "project_database_placement",
"component": "project_database",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Project Database is directly inside Private Network."
},
"group": "private_network"
},
{
"id": "lookup_cache_placement",
"component": "lookup_cache",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Lookup Cache is directly inside Private Network."
},
"group": "private_network"
},
{
"id": "attachment_storage_placement",
"component": "attachment_storage",
"relation": "outside",
"basis": {
"kind": "explicit",
"text": "Attachment Storage is outside Private Network."
},
"group": "private_network"
}
],
"allowAdditionalResources": false
}
Download Requirements ↓ Create a provider-neutral architecture for a team project portal. Users reach a load balancer that forwards requests to a portal server. The server reads project data from a database, uses a cache for frequent lookups, and retrieves attachments from object storage. Keep the server, database, and cache in a private network; keep the load balancer and object storage outside it. Use a left-to-right automatic layout and add no other services.Download Prompt ↓
dgm 1
diagram cloud-agnostic-medium-team-project-portal {
grammar cloud-agnostic
flow lr
title "Team project portal (cloud-neutral)"
cloud-agnostic.client users "Users"
cloud-agnostic.cloud cloud "Application cloud" {
cloud-agnostic.load-balancer lb "Load balancer"
cloud-agnostic.network network "Private network" {
cloud-agnostic.server portal "Portal server"
cloud-agnostic.cache cache "Cache"
cloud-agnostic.database db "Project database"
}
cloud-agnostic.object-storage attachments "Attachment storage"
}
users -> lb { id visit step 1 label "Requests" kind flow }
lb -> portal { id forward step 2 label "Forward" kind flow }
portal -> db { id projects step 3 label "Project data" kind flow }
portal -> cache { id lookups step 3 label "Frequent lookups" kind flow }
portal -> attachments { id files step 3 label "Fetch attachments" kind flow }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "cloud-agnostic",
"components": [
{
"id": "users",
"kind": "resource",
"type": "cloud-agnostic.client",
"basis": {
"kind": "explicit",
"text": "Users reach a load balancer to a portal server; server reads database, uses cache, retrieves attachments from object storage. Server, database, cache in priv..."
}
},
{
"id": "cloud",
"kind": "group",
"type": "cloud-agnostic.cloud",
"basis": {
"kind": "inferred",
"text": "Structurally required to place or group the named resources."
}
},
{
"id": "lb",
"kind": "resource",
"type": "cloud-agnostic.load-balancer",
"basis": {
"kind": "explicit",
"text": "Users reach a load balancer to a portal server; server reads database, uses cache, retrieves attachments from object storage. Server, database, cache in priv..."
}
},
{
"id": "network",
"kind": "group",
"type": "cloud-agnostic.network",
"basis": {
"kind": "explicit",
"text": "Users reach a load balancer to a portal server; server reads database, uses cache, retrieves attachments from object storage. Server, database, cache in priv..."
}
},
{
"id": "portal",
"kind": "resource",
"type": "cloud-agnostic.server",
"basis": {
"kind": "explicit",
"text": "Users reach a load balancer to a portal server; server reads database, uses cache, retrieves attachments from object storage. Server, database, cache in priv..."
}
},
{
"id": "cache",
"kind": "resource",
"type": "cloud-agnostic.cache",
"basis": {
"kind": "explicit",
"text": "Users reach a load balancer to a portal server; server reads database, uses cache, retrieves attachments from object storage. Server, database, cache in priv..."
}
},
{
"id": "db",
"kind": "resource",
"type": "cloud-agnostic.database",
"basis": {
"kind": "explicit",
"text": "Users reach a load balancer to a portal server; server reads database, uses cache, retrieves attachments from object storage. Server, database, cache in priv..."
}
},
{
"id": "attachments",
"kind": "resource",
"type": "cloud-agnostic.object-storage",
"basis": {
"kind": "explicit",
"text": "Users reach a load balancer to a portal server; server reads database, uses cache, retrieves attachments from object storage. Server, database, cache in priv..."
}
}
],
"relationships": [
{
"id": "visit",
"source": "users",
"target": "lb",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Requests (users to lb) per the request."
}
},
{
"id": "forward",
"source": "lb",
"target": "portal",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Forward (lb to portal) per the request."
}
},
{
"id": "projects",
"source": "portal",
"target": "db",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Project data (portal to db) per the request."
}
},
{
"id": "lookups",
"source": "portal",
"target": "cache",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Frequent lookups (portal to cache) per the request."
}
},
{
"id": "files",
"source": "portal",
"target": "attachments",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Fetch attachments (portal to attachments) per the request."
}
}
],
"counts": [],
"placement": [
{
"id": "users_root",
"component": "users",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "cloud_root",
"component": "cloud",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "lb_in_cloud",
"component": "lb",
"relation": "parent",
"group": "cloud",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "network_in_cloud",
"component": "network",
"relation": "parent",
"group": "cloud",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "portal_in_network",
"component": "portal",
"relation": "parent",
"group": "network",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "cache_in_network",
"component": "cache",
"relation": "parent",
"group": "network",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "db_in_network",
"component": "db",
"relation": "parent",
"group": "network",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "attachments_in_cloud",
"component": "attachments",
"relation": "parent",
"group": "cloud",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "lb_outside_network",
"component": "lb",
"relation": "outside",
"group": "network",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
},
{
"id": "attachments_outside_network",
"component": "attachments",
"relation": "outside",
"group": "network",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
}
],
"allowAdditionalResources": false
}
Download Requirements ↓ Webhook Processing
Draw a provider-neutral, left-to-right webhook-processing diagram. An external partner sends webhook events to an API gateway and webhook ingress function. The ingress function queues events and writes an idempotency key to the event database. An event processor consumes the queue, stores processed status in the same database, and archives the payload in object storage. Nest a production account, primary region, and private network inside an application cloud. Place the gateway and ingress function together in a webhook-edge boundary and place the queue, processor, and database in an event-processing boundary within the network. Keep the payload archive in the region outside the private network. Do not add other services and use automatic routing.Download Prompt ↓
dgm 1
diagram cloud-agnostic-medium-webhook-processing {
grammar cloud-agnostic
flow lr
title "Webhook Processing"
cloud-agnostic.cloud application_cloud "Application Cloud" {
cloud-agnostic.account production_account "Production Account" {
cloud-agnostic.region primary_region "Primary Region" {
cloud-agnostic.network private_network "Private Network" {
cloud-agnostic.boundary event_processing "Event Processing" {
cloud-agnostic.queue event_queue "Event Queue" {}
cloud-agnostic.server event_processor "Event Processor" {}
cloud-agnostic.database event_database "Event Database" {}
}
}
cloud-agnostic.boundary webhook_edge "Webhook Edge" {
cloud-agnostic.gateway api_gateway "API Gateway" {}
cloud-agnostic.function webhook_ingress "Webhook Ingress" {}
}
cloud-agnostic.object-storage payload_archive "Payload Archive" {}
}
}
}
cloud-agnostic.actor partner "External Partner" {}
partner -> api_gateway { id partner_webhook label "webhook events" step 1 kind flow }
api_gateway -> webhook_ingress { id gateway_to_ingress label "deliver events" step 2 kind flow }
webhook_ingress -> event_queue { id ingress_to_queue label "queue events" step 3 kind flow }
webhook_ingress -> event_database { id ingress_idempotency label "write idempotency key" step 3 kind flow }
event_queue -> event_processor { id queue_to_processor label "queued events" step 4 kind flow }
event_processor -> event_database { id processor_status label "store processed status" step 5 kind flow }
event_processor -> payload_archive { id processor_archive label "archive payload" step 5 kind flow }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "cloud-agnostic",
"components": [
{
"id": "application_cloud",
"kind": "group",
"type": "cloud-agnostic.cloud",
"basis": {
"kind": "explicit",
"text": "The production account, primary region, and private network are nested in an application cloud."
}
},
{
"id": "production_account",
"kind": "group",
"type": "cloud-agnostic.account",
"basis": {
"kind": "explicit",
"text": "The production account is inside the application cloud."
}
},
{
"id": "primary_region",
"kind": "group",
"type": "cloud-agnostic.region",
"basis": {
"kind": "explicit",
"text": "The primary region is inside the production account."
}
},
{
"id": "private_network",
"kind": "group",
"type": "cloud-agnostic.network",
"basis": {
"kind": "explicit",
"text": "A private network is nested in the primary region."
}
},
{
"id": "event_processing",
"kind": "group",
"type": "cloud-agnostic.boundary",
"basis": {
"kind": "explicit",
"text": "The queue, processor, and database are in an event-processing boundary within the network."
}
},
{
"id": "webhook_edge",
"kind": "group",
"type": "cloud-agnostic.boundary",
"basis": {
"kind": "explicit",
"text": "The API gateway and ingress function are together in a webhook-edge boundary."
}
},
{
"id": "partner",
"kind": "resource",
"type": "cloud-agnostic.actor",
"basis": {
"kind": "explicit",
"text": "An external partner sends webhook events."
}
},
{
"id": "api_gateway",
"kind": "resource",
"type": "cloud-agnostic.gateway",
"basis": {
"kind": "explicit",
"text": "Webhook events are sent to an API gateway."
}
},
{
"id": "webhook_ingress",
"kind": "resource",
"type": "cloud-agnostic.function",
"basis": {
"kind": "explicit",
"text": "A webhook ingress function receives webhook events."
}
},
{
"id": "event_queue",
"kind": "resource",
"type": "cloud-agnostic.queue",
"basis": {
"kind": "explicit",
"text": "The ingress queues events."
}
},
{
"id": "event_processor",
"kind": "resource",
"type": "cloud-agnostic.server",
"basis": {
"kind": "explicit",
"text": "An event processor consumes the queue."
}
},
{
"id": "event_database",
"kind": "resource",
"type": "cloud-agnostic.database",
"basis": {
"kind": "explicit",
"text": "The ingress writes an idempotency key and processor stores processed status in the same database."
}
},
{
"id": "payload_archive",
"kind": "resource",
"type": "cloud-agnostic.object-storage",
"basis": {
"kind": "explicit",
"text": "The processor archives the payload in object storage, kept in the region outside the private network."
}
}
],
"relationships": [
{
"id": "partner_webhook",
"source": "partner",
"target": "api_gateway",
"basis": {
"kind": "explicit",
"text": "The external partner sends webhook events to the API gateway."
},
"kind": "flow"
},
{
"id": "gateway_to_ingress",
"source": "api_gateway",
"target": "webhook_ingress",
"basis": {
"kind": "explicit",
"text": "The API gateway and ingress function receive webhook events."
},
"kind": "flow"
},
{
"id": "ingress_to_queue",
"source": "webhook_ingress",
"target": "event_queue",
"basis": {
"kind": "explicit",
"text": "The ingress function queues events."
},
"kind": "flow"
},
{
"id": "ingress_idempotency",
"source": "webhook_ingress",
"target": "event_database",
"basis": {
"kind": "explicit",
"text": "The ingress writes an idempotency key to the event database."
},
"kind": "flow"
},
{
"id": "queue_to_processor",
"source": "event_queue",
"target": "event_processor",
"basis": {
"kind": "explicit",
"text": "The event processor consumes the queue."
},
"kind": "flow"
},
{
"id": "processor_status",
"source": "event_processor",
"target": "event_database",
"basis": {
"kind": "explicit",
"text": "The processor stores processed status in the same database."
},
"kind": "flow"
},
{
"id": "processor_archive",
"source": "event_processor",
"target": "payload_archive",
"basis": {
"kind": "explicit",
"text": "The processor archives the payload in object storage."
},
"kind": "flow"
}
],
"counts": [
{
"id": "one_cloud",
"kind": "group",
"type": "cloud-agnostic.cloud",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "One application cloud."
}
},
{
"id": "one_account",
"kind": "group",
"type": "cloud-agnostic.account",
"min": 1,
"max": 1,
"within": "application_cloud",
"basis": {
"kind": "explicit",
"text": "One production account."
}
},
{
"id": "one_region",
"kind": "group",
"type": "cloud-agnostic.region",
"min": 1,
"max": 1,
"within": "production_account",
"basis": {
"kind": "explicit",
"text": "One primary region."
}
},
{
"id": "one_network",
"kind": "group",
"type": "cloud-agnostic.network",
"min": 1,
"max": 1,
"within": "primary_region",
"basis": {
"kind": "explicit",
"text": "One private network."
}
},
{
"id": "two_boundaries",
"kind": "group",
"type": "cloud-agnostic.boundary",
"min": 2,
"max": 2,
"within": "primary_region",
"basis": {
"kind": "explicit",
"text": "One webhook-edge boundary and one event-processing boundary."
}
},
{
"id": "one_gateway",
"kind": "resource",
"type": "cloud-agnostic.gateway",
"min": 1,
"max": 1,
"within": "webhook_edge",
"basis": {
"kind": "explicit",
"text": "An API gateway in the webhook-edge boundary."
}
},
{
"id": "one_function",
"kind": "resource",
"type": "cloud-agnostic.function",
"min": 1,
"max": 1,
"within": "webhook_edge",
"basis": {
"kind": "explicit",
"text": "A webhook ingress function in the webhook-edge boundary."
}
},
{
"id": "one_queue",
"kind": "resource",
"type": "cloud-agnostic.queue",
"min": 1,
"max": 1,
"within": "event_processing",
"basis": {
"kind": "explicit",
"text": "One event queue."
}
},
{
"id": "one_processor",
"kind": "resource",
"type": "cloud-agnostic.server",
"min": 1,
"max": 1,
"within": "event_processing",
"basis": {
"kind": "explicit",
"text": "One event processor."
}
},
{
"id": "one_database",
"kind": "resource",
"type": "cloud-agnostic.database",
"min": 1,
"max": 1,
"within": "event_processing",
"basis": {
"kind": "explicit",
"text": "One event database shared by ingress and processor."
}
},
{
"id": "one_archive",
"kind": "resource",
"type": "cloud-agnostic.object-storage",
"min": 1,
"max": 1,
"within": "primary_region",
"basis": {
"kind": "explicit",
"text": "One regional payload archive."
}
},
{
"id": "one_partner",
"kind": "resource",
"type": "cloud-agnostic.actor",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "One external partner."
}
}
],
"placement": [
{
"id": "application_cloud_placement",
"component": "application_cloud",
"relation": "root",
"basis": {
"kind": "inferred",
"text": "Application Cloud is at the diagram root."
}
},
{
"id": "production_account_placement",
"component": "production_account",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Production Account is directly inside Application Cloud."
},
"group": "application_cloud"
},
{
"id": "primary_region_placement",
"component": "primary_region",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Primary Region is directly inside Production Account."
},
"group": "production_account"
},
{
"id": "private_network_placement",
"component": "private_network",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Private Network is directly inside Primary Region."
},
"group": "primary_region"
},
{
"id": "event_processing_placement",
"component": "event_processing",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Event Processing is directly inside Private Network."
},
"group": "private_network"
},
{
"id": "webhook_edge_placement",
"component": "webhook_edge",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Webhook Edge is directly inside Primary Region."
},
"group": "primary_region"
},
{
"id": "partner_placement",
"component": "partner",
"relation": "outside",
"basis": {
"kind": "explicit",
"text": "External Partner is outside Application Cloud."
},
"group": "application_cloud"
},
{
"id": "api_gateway_placement",
"component": "api_gateway",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "API Gateway is directly inside Webhook Edge."
},
"group": "webhook_edge"
},
{
"id": "webhook_ingress_placement",
"component": "webhook_ingress",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Webhook Ingress is directly inside Webhook Edge."
},
"group": "webhook_edge"
},
{
"id": "event_queue_placement",
"component": "event_queue",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Event Queue is directly inside Event Processing."
},
"group": "event_processing"
},
{
"id": "event_processor_placement",
"component": "event_processor",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Event Processor is directly inside Event Processing."
},
"group": "event_processing"
},
{
"id": "event_database_placement",
"component": "event_database",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Event Database is directly inside Event Processing."
},
"group": "event_processing"
},
{
"id": "payload_archive_placement",
"component": "payload_archive",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Payload Archive is directly inside Primary Region."
},
"group": "primary_region"
}
],
"allowAdditionalResources": false
}
Download Requirements ↓ Draw a provider-neutral, left-to-right webhook-processing diagram. An external partner sends webhook events to an API gateway and webhook ingress function. The ingress function queues events and writes an idempotency key to the event database. An event processor consumes the queue, stores processed status in the same database, and archives the payload in object storage. Nest a production account, primary region, and private network inside an application cloud. Place the gateway and ingress function together in a webhook-edge boundary and place the queue, processor, and database in an event-processing boundary within the network. Keep the payload archive in the region outside the private network. Do not add other services and use automatic routing.Download Prompt ↓
dgm 1
diagram cloud-agnostic-medium-webhook-processing {
grammar cloud-agnostic
flow lr
title "Webhook processing (cloud-neutral)"
cloud-agnostic.client partner "External partner"
cloud-agnostic.cloud cloud "Application cloud" {
cloud-agnostic.account account "Production account" {
cloud-agnostic.region region "Primary region" {
cloud-agnostic.boundary edge "Webhook edge" {
style dashed
fill none
cloud-agnostic.gateway gateway "API gateway"
cloud-agnostic.function ingress "Ingress function"
}
cloud-agnostic.network network "Private network" {
cloud-agnostic.boundary processing "Event processing" {
style dashed
fill none
cloud-agnostic.queue queue "Event queue"
cloud-agnostic.server processor "Event processor"
cloud-agnostic.database db "Event database"
}
}
cloud-agnostic.object-storage archive "Payload archive"
}
}
}
partner -> gateway { id webhook step 1 label "Webhook events" kind flow }
gateway -> ingress { id invoke step 2 label "Invoke" kind flow }
ingress -> queue { id enqueue step 3 label "Queue events" kind flow }
ingress -> db { id idempotency step 3 label "Idempotency key" kind flow }
queue -> processor { id consume step 4 label "Consume" kind flow }
processor -> db { id status step 5 label "Processed status" kind flow }
processor -> archive { id archive_payload step 5 label "Archive payload" kind flow }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "cloud-agnostic",
"components": [
{
"id": "partner",
"kind": "resource",
"type": "cloud-agnostic.client",
"basis": {
"kind": "explicit",
"text": "Partner sends webhooks to API gateway and ingress function, which queues events and writes idempotency key to event database; processor consumes queue, store..."
}
},
{
"id": "cloud",
"kind": "group",
"type": "cloud-agnostic.cloud",
"basis": {
"kind": "explicit",
"text": "Partner sends webhooks to API gateway and ingress function, which queues events and writes idempotency key to event database; processor consumes queue, store..."
}
},
{
"id": "account",
"kind": "group",
"type": "cloud-agnostic.account",
"basis": {
"kind": "explicit",
"text": "Partner sends webhooks to API gateway and ingress function, which queues events and writes idempotency key to event database; processor consumes queue, store..."
}
},
{
"id": "region",
"kind": "group",
"type": "cloud-agnostic.region",
"basis": {
"kind": "explicit",
"text": "Partner sends webhooks to API gateway and ingress function, which queues events and writes idempotency key to event database; processor consumes queue, store..."
}
},
{
"id": "edge",
"kind": "group",
"type": "cloud-agnostic.boundary",
"basis": {
"kind": "explicit",
"text": "Partner sends webhooks to API gateway and ingress function, which queues events and writes idempotency key to event database; processor consumes queue, store..."
}
},
{
"id": "gateway",
"kind": "resource",
"type": "cloud-agnostic.gateway",
"basis": {
"kind": "explicit",
"text": "Partner sends webhooks to API gateway and ingress function, which queues events and writes idempotency key to event database; processor consumes queue, store..."
}
},
{
"id": "ingress",
"kind": "resource",
"type": "cloud-agnostic.function",
"basis": {
"kind": "explicit",
"text": "Partner sends webhooks to API gateway and ingress function, which queues events and writes idempotency key to event database; processor consumes queue, store..."
}
},
{
"id": "network",
"kind": "group",
"type": "cloud-agnostic.network",
"basis": {
"kind": "explicit",
"text": "Partner sends webhooks to API gateway and ingress function, which queues events and writes idempotency key to event database; processor consumes queue, store..."
}
},
{
"id": "processing",
"kind": "group",
"type": "cloud-agnostic.boundary",
"basis": {
"kind": "explicit",
"text": "Partner sends webhooks to API gateway and ingress function, which queues events and writes idempotency key to event database; processor consumes queue, store..."
}
},
{
"id": "queue",
"kind": "resource",
"type": "cloud-agnostic.queue",
"basis": {
"kind": "explicit",
"text": "Partner sends webhooks to API gateway and ingress function, which queues events and writes idempotency key to event database; processor consumes queue, store..."
}
},
{
"id": "processor",
"kind": "resource",
"type": "cloud-agnostic.server",
"basis": {
"kind": "explicit",
"text": "Partner sends webhooks to API gateway and ingress function, which queues events and writes idempotency key to event database; processor consumes queue, store..."
}
},
{
"id": "db",
"kind": "resource",
"type": "cloud-agnostic.database",
"basis": {
"kind": "explicit",
"text": "Partner sends webhooks to API gateway and ingress function, which queues events and writes idempotency key to event database; processor consumes queue, store..."
}
},
{
"id": "archive",
"kind": "resource",
"type": "cloud-agnostic.object-storage",
"basis": {
"kind": "explicit",
"text": "Partner sends webhooks to API gateway and ingress function, which queues events and writes idempotency key to event database; processor consumes queue, store..."
}
}
],
"relationships": [
{
"id": "webhook",
"source": "partner",
"target": "gateway",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Webhook events (partner to gateway) per the request."
}
},
{
"id": "invoke",
"source": "gateway",
"target": "ingress",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Invoke (gateway to ingress) per the request."
}
},
{
"id": "enqueue",
"source": "ingress",
"target": "queue",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Queue events (ingress to queue) per the request."
}
},
{
"id": "idempotency",
"source": "ingress",
"target": "db",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Idempotency key (ingress to db) per the request."
}
},
{
"id": "consume",
"source": "queue",
"target": "processor",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Consume (queue to processor) per the request."
}
},
{
"id": "status",
"source": "processor",
"target": "db",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Processed status (processor to db) per the request."
}
},
{
"id": "archive_payload",
"source": "processor",
"target": "archive",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Archive payload (processor to archive) per the request."
}
}
],
"counts": [],
"placement": [
{
"id": "partner_root",
"component": "partner",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "cloud_root",
"component": "cloud",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "account_in_cloud",
"component": "account",
"relation": "parent",
"group": "cloud",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "region_in_account",
"component": "region",
"relation": "parent",
"group": "account",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "edge_in_region",
"component": "edge",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "gateway_in_edge",
"component": "gateway",
"relation": "parent",
"group": "edge",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "ingress_in_edge",
"component": "ingress",
"relation": "parent",
"group": "edge",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "network_in_region",
"component": "network",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "processing_in_network",
"component": "processing",
"relation": "parent",
"group": "network",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "queue_in_processing",
"component": "queue",
"relation": "parent",
"group": "processing",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "processor_in_processing",
"component": "processor",
"relation": "parent",
"group": "processing",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "db_in_processing",
"component": "db",
"relation": "parent",
"group": "processing",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "archive_in_region",
"component": "archive",
"relation": "parent",
"group": "region",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
}
],
"allowAdditionalResources": false
}
Download Requirements ↓ Order Processing with Recovery Region
Review note: Strict validation reports 16 routing findings, mostly plain arrow crossings; accepted in review.
Create a cloud-neutral order processing architecture in one cloud account with primary and recovery regions. A public buyer reaches a regional load balancer, which forwards requests to an API server inside the primary private application network and cluster. The database and cache are in the same private network. The API uses them, calls an external payment service, and enqueues work in a regional queue outside the network. Show separate database, cache, and payment response arrows back to the API. The queue feeds a worker server in the application cluster. The worker sends fulfillment to an external warehouse and receives its acknowledgment back; it retries by sending work back to the queue. It also writes order status to the primary database and receipts to object storage outside the network. The primary database replicates to a recovery database inside a recovery network. A recovery application server reads that replica and can serve the buyer through a recovery load balancer. Keep payment and warehouse external, and preserve all directions and containment.Download Prompt ↓
dgm 1
diagram cloud-agnostic-hard-order-processing {
grammar cloud-agnostic
flow lr
title "Order Processing with Recovery Region"
cloud-agnostic.boundary external_parties "External Parties" {
cloud-agnostic.client buyer "Public Buyer" {}
cloud-agnostic.actor payment_service "Payment Service" {}
cloud-agnostic.actor warehouse "External Warehouse" {}
}
cloud-agnostic.cloud application_cloud "Application Cloud" {
cloud-agnostic.account cloud_account "Cloud Account" {
cloud-agnostic.region primary_region "Primary Region" {
cloud-agnostic.network primary_network "Primary Private Network" {
cloud-agnostic.cluster primary_cluster "Application Cluster" {
cloud-agnostic.server api_server "API Server" {}
cloud-agnostic.server worker_server "Worker Server" {}
}
cloud-agnostic.database primary_database "Primary Database" {}
cloud-agnostic.cache primary_cache "Primary Cache" {}
}
cloud-agnostic.load-balancer primary_lb "Primary Load Balancer" {}
cloud-agnostic.queue work_queue "Regional Work Queue" {}
cloud-agnostic.object-storage receipt_storage "Receipt Storage" {}
}
cloud-agnostic.region recovery_region "Recovery Region" {
cloud-agnostic.network recovery_network "Recovery Network" {
cloud-agnostic.database recovery_database "Recovery Database" {}
cloud-agnostic.server recovery_app "Recovery Application Server" {}
}
cloud-agnostic.load-balancer recovery_lb "Recovery Load Balancer" {}
}
}
}
buyer -> primary_lb { id buyer_primary label "order request" step 1 kind flow from e to w }
primary_lb -> api_server { id primary_lb_api label "forward request" step 2 kind flow from e to w }
api_server -> primary_database { id api_db_request label "database request" step 3 kind flow from e to w }
primary_database -> api_server { id db_api_response label "database response" style dashed kind flow from w to e }
api_server -> primary_cache { id api_cache_request label "cache lookup" step 4 kind flow from s to n }
primary_cache -> api_server { id cache_api_response label "cache response" step 5 kind flow from n to s }
api_server -> payment_service { id api_payment_request label "payment request" step 6 kind flow from w to e }
payment_service -> api_server { id payment_api_response label "payment response" step 7 kind flow from e to w }
api_server -> work_queue { id api_to_queue label "enqueue work" step 8 kind flow from e to w }
work_queue -> worker_server { id queue_to_worker label "queued order" step 9 kind flow from w to e }
worker_server -> warehouse { id worker_to_warehouse label "fulfillment" step 10 kind flow from w to e }
warehouse -> worker_server { id warehouse_ack label "fulfillment acknowledgment" step 11 kind flow from e to w }
worker_server -> primary_database { id worker_status label "write order status" step 12 kind flow from e to w }
worker_server -> receipt_storage { id worker_receipt label "write receipt" step 12 kind flow from e to w }
worker_server -> work_queue { id worker_retry label "retry work" kind fail style dashed from e to w }
primary_database -> recovery_database { id database_replication label "replicate data" step 13 kind flow from e to w }
recovery_database -> recovery_app { id recovery_read label "replica read" step 14 kind flow from e to w }
buyer -> recovery_lb { id buyer_recovery label "recovery request" step 1 kind flow from e to w }
recovery_lb -> recovery_app { id recovery_lb_app label "forward recovery request" step 2 kind flow from e to w }
recovery_app -> recovery_lb { id recovery_app_lb label "recovery response" step 15 kind flow from w to e }
recovery_lb -> buyer { id recovery_to_buyer label "serve buyer" step 16 kind flow from w to e }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "cloud-agnostic",
"components": [
{
"id": "external_parties",
"kind": "group",
"type": "cloud-agnostic.boundary",
"basis": {
"kind": "inferred",
"text": "The buyer, payment service, and warehouse are grouped outside the application cloud to separate actors from infrastructure."
}
},
{
"id": "application_cloud",
"kind": "group",
"type": "cloud-agnostic.cloud",
"basis": {
"kind": "explicit",
"text": "One cloud account contains the primary and recovery regions."
}
},
{
"id": "cloud_account",
"kind": "group",
"type": "cloud-agnostic.account",
"basis": {
"kind": "explicit",
"text": "One cloud account contains both regions."
}
},
{
"id": "primary_region",
"kind": "group",
"type": "cloud-agnostic.region",
"basis": {
"kind": "explicit",
"text": "The primary region is in the account."
}
},
{
"id": "primary_network",
"kind": "group",
"type": "cloud-agnostic.network",
"basis": {
"kind": "explicit",
"text": "The API server, database, and cache are in the primary private application network."
}
},
{
"id": "primary_cluster",
"kind": "group",
"type": "cloud-agnostic.cluster",
"basis": {
"kind": "explicit",
"text": "The API server and worker are in the application cluster inside the primary network."
}
},
{
"id": "recovery_region",
"kind": "group",
"type": "cloud-agnostic.region",
"basis": {
"kind": "explicit",
"text": "The recovery region is in the same account."
}
},
{
"id": "recovery_network",
"kind": "group",
"type": "cloud-agnostic.network",
"basis": {
"kind": "explicit",
"text": "The recovery database is inside a recovery network."
}
},
{
"id": "buyer",
"kind": "resource",
"type": "cloud-agnostic.client",
"basis": {
"kind": "explicit",
"text": "A public buyer reaches the regional load balancer and can be served through the recovery load balancer."
}
},
{
"id": "payment_service",
"kind": "resource",
"type": "cloud-agnostic.actor",
"basis": {
"kind": "explicit",
"text": "The API calls an external payment service."
}
},
{
"id": "warehouse",
"kind": "resource",
"type": "cloud-agnostic.actor",
"basis": {
"kind": "explicit",
"text": "The worker sends fulfillment to an external warehouse and receives its acknowledgment."
}
},
{
"id": "primary_lb",
"kind": "resource",
"type": "cloud-agnostic.load-balancer",
"basis": {
"kind": "explicit",
"text": "A buyer reaches a regional load balancer in the primary region."
}
},
{
"id": "api_server",
"kind": "resource",
"type": "cloud-agnostic.server",
"basis": {
"kind": "explicit",
"text": "The load balancer forwards requests to an API server in the private application network and cluster."
}
},
{
"id": "primary_database",
"kind": "resource",
"type": "cloud-agnostic.database",
"basis": {
"kind": "explicit",
"text": "The database is in the primary private network and receives order status and replicates to recovery."
}
},
{
"id": "primary_cache",
"kind": "resource",
"type": "cloud-agnostic.cache",
"basis": {
"kind": "explicit",
"text": "The cache is in the same primary private network."
}
},
{
"id": "work_queue",
"kind": "resource",
"type": "cloud-agnostic.queue",
"basis": {
"kind": "explicit",
"text": "The API enqueues work in a regional queue outside the network."
}
},
{
"id": "worker_server",
"kind": "resource",
"type": "cloud-agnostic.server",
"basis": {
"kind": "explicit",
"text": "A worker server in the application cluster consumes queued work."
}
},
{
"id": "receipt_storage",
"kind": "resource",
"type": "cloud-agnostic.object-storage",
"basis": {
"kind": "explicit",
"text": "The worker writes receipts to object storage outside the network."
}
},
{
"id": "recovery_database",
"kind": "resource",
"type": "cloud-agnostic.database",
"basis": {
"kind": "explicit",
"text": "The primary database replicates to a recovery database inside a recovery network."
}
},
{
"id": "recovery_app",
"kind": "resource",
"type": "cloud-agnostic.server",
"basis": {
"kind": "explicit",
"text": "A recovery application server reads that replica."
}
},
{
"id": "recovery_lb",
"kind": "resource",
"type": "cloud-agnostic.load-balancer",
"basis": {
"kind": "explicit",
"text": "The recovery application server can serve the buyer through a recovery load balancer."
}
}
],
"relationships": [
{
"id": "buyer_primary",
"source": "buyer",
"target": "primary_lb",
"basis": {
"kind": "explicit",
"text": "The public buyer reaches the primary regional load balancer."
},
"kind": "flow"
},
{
"id": "primary_lb_api",
"source": "primary_lb",
"target": "api_server",
"basis": {
"kind": "explicit",
"text": "The primary load balancer forwards requests to the API server."
},
"kind": "flow"
},
{
"id": "api_db_request",
"source": "api_server",
"target": "primary_database",
"basis": {
"kind": "explicit",
"text": "The API uses the primary database."
},
"kind": "flow"
},
{
"id": "db_api_response",
"source": "primary_database",
"target": "api_server",
"basis": {
"kind": "explicit",
"text": "Show a separate database response arrow back to the API."
},
"kind": "flow"
},
{
"id": "api_cache_request",
"source": "api_server",
"target": "primary_cache",
"basis": {
"kind": "explicit",
"text": "The API uses the cache."
},
"kind": "flow"
},
{
"id": "cache_api_response",
"source": "primary_cache",
"target": "api_server",
"basis": {
"kind": "explicit",
"text": "Show a separate cache response arrow back to the API."
},
"kind": "flow"
},
{
"id": "api_payment_request",
"source": "api_server",
"target": "payment_service",
"basis": {
"kind": "explicit",
"text": "The API calls the external payment service."
},
"kind": "flow"
},
{
"id": "payment_api_response",
"source": "payment_service",
"target": "api_server",
"basis": {
"kind": "explicit",
"text": "Show a separate payment response arrow back to the API."
},
"kind": "flow"
},
{
"id": "api_to_queue",
"source": "api_server",
"target": "work_queue",
"basis": {
"kind": "explicit",
"text": "The API enqueues work in a regional queue outside the network."
},
"kind": "flow"
},
{
"id": "queue_to_worker",
"source": "work_queue",
"target": "worker_server",
"basis": {
"kind": "explicit",
"text": "The queue feeds a worker server in the application cluster."
},
"kind": "flow"
},
{
"id": "worker_to_warehouse",
"source": "worker_server",
"target": "warehouse",
"basis": {
"kind": "explicit",
"text": "The worker sends fulfillment to an external warehouse."
},
"kind": "flow"
},
{
"id": "warehouse_ack",
"source": "warehouse",
"target": "worker_server",
"basis": {
"kind": "explicit",
"text": "The worker receives the warehouse acknowledgment."
},
"kind": "flow"
},
{
"id": "worker_status",
"source": "worker_server",
"target": "primary_database",
"basis": {
"kind": "explicit",
"text": "The worker writes order status to the primary database."
},
"kind": "flow"
},
{
"id": "worker_receipt",
"source": "worker_server",
"target": "receipt_storage",
"basis": {
"kind": "explicit",
"text": "The worker writes receipts to object storage outside the network."
},
"kind": "flow"
},
{
"id": "worker_retry",
"source": "worker_server",
"target": "work_queue",
"basis": {
"kind": "explicit",
"text": "The worker retries by sending work back to the queue."
},
"kind": "fail"
},
{
"id": "database_replication",
"source": "primary_database",
"target": "recovery_database",
"basis": {
"kind": "explicit",
"text": "The primary database replicates to the recovery database."
},
"kind": "flow"
},
{
"id": "recovery_read",
"source": "recovery_database",
"target": "recovery_app",
"basis": {
"kind": "explicit",
"text": "The recovery application server reads the recovery database replica."
},
"kind": "flow"
},
{
"id": "buyer_recovery",
"source": "buyer",
"target": "recovery_lb",
"basis": {
"kind": "explicit",
"text": "The recovery application can serve the buyer through a recovery load balancer."
},
"kind": "flow"
},
{
"id": "recovery_lb_app",
"source": "recovery_lb",
"target": "recovery_app",
"basis": {
"kind": "explicit",
"text": "The recovery load balancer forwards the buyer request to recovery application."
},
"kind": "flow"
},
{
"id": "recovery_app_lb",
"source": "recovery_app",
"target": "recovery_lb",
"basis": {
"kind": "inferred",
"text": "A serving path returns the recovery application response through its load balancer."
},
"kind": "flow"
},
{
"id": "recovery_to_buyer",
"source": "recovery_lb",
"target": "buyer",
"basis": {
"kind": "inferred",
"text": "The recovery load balancer returns the served response to the buyer."
},
"kind": "flow"
}
],
"counts": [
{
"id": "one_external_parties",
"kind": "group",
"type": "cloud-agnostic.boundary",
"min": 1,
"max": 1,
"basis": {
"kind": "inferred",
"text": "One logical group for external actors."
}
},
{
"id": "one_cloud",
"kind": "group",
"type": "cloud-agnostic.cloud",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "One cloud account with primary and recovery regions."
}
},
{
"id": "one_account",
"kind": "group",
"type": "cloud-agnostic.account",
"min": 1,
"max": 1,
"within": "application_cloud",
"basis": {
"kind": "explicit",
"text": "One cloud account."
}
},
{
"id": "two_regions",
"kind": "group",
"type": "cloud-agnostic.region",
"min": 2,
"max": 2,
"within": "cloud_account",
"basis": {
"kind": "explicit",
"text": "Primary and recovery regions."
}
},
{
"id": "two_networks",
"kind": "group",
"type": "cloud-agnostic.network",
"min": 2,
"max": 2,
"within": "cloud_account",
"basis": {
"kind": "explicit",
"text": "A primary private application network and a recovery network."
}
},
{
"id": "one_cluster",
"kind": "group",
"type": "cloud-agnostic.cluster",
"min": 1,
"max": 1,
"within": "primary_network",
"basis": {
"kind": "explicit",
"text": "One application cluster in the primary private network."
}
},
{
"id": "one_buyer",
"kind": "resource",
"type": "cloud-agnostic.client",
"min": 1,
"max": 1,
"basis": {
"kind": "explicit",
"text": "A public buyer."
}
},
{
"id": "one_primary_lb",
"kind": "resource",
"type": "cloud-agnostic.load-balancer",
"min": 1,
"max": 1,
"within": "primary_region",
"basis": {
"kind": "explicit",
"text": "A regional primary load balancer."
}
},
{
"id": "one_recovery_lb",
"kind": "resource",
"type": "cloud-agnostic.load-balancer",
"min": 1,
"max": 1,
"within": "recovery_region",
"basis": {
"kind": "explicit",
"text": "A recovery load balancer."
}
},
{
"id": "two_primary_servers",
"kind": "resource",
"type": "cloud-agnostic.server",
"min": 2,
"max": 2,
"within": "primary_cluster",
"basis": {
"kind": "explicit",
"text": "An API server and worker server in the primary application cluster."
}
},
{
"id": "one_recovery_app",
"kind": "resource",
"type": "cloud-agnostic.server",
"min": 1,
"max": 1,
"within": "recovery_network",
"basis": {
"kind": "explicit",
"text": "A recovery application server."
}
},
{
"id": "two_databases",
"kind": "resource",
"type": "cloud-agnostic.database",
"min": 2,
"max": 2,
"within": "cloud_account",
"basis": {
"kind": "explicit",
"text": "Primary and recovery databases."
}
},
{
"id": "one_cache",
"kind": "resource",
"type": "cloud-agnostic.cache",
"min": 1,
"max": 1,
"within": "primary_network",
"basis": {
"kind": "explicit",
"text": "A primary cache."
}
},
{
"id": "one_queue",
"kind": "resource",
"type": "cloud-agnostic.queue",
"min": 1,
"max": 1,
"within": "primary_region",
"basis": {
"kind": "explicit",
"text": "A regional work queue."
}
},
{
"id": "one_storage",
"kind": "resource",
"type": "cloud-agnostic.object-storage",
"min": 1,
"max": 1,
"within": "primary_region",
"basis": {
"kind": "explicit",
"text": "Receipt object storage."
}
},
{
"id": "two_external_actors",
"kind": "resource",
"type": "cloud-agnostic.actor",
"min": 2,
"max": 2,
"basis": {
"kind": "explicit",
"text": "One external payment service and one external warehouse."
}
}
],
"placement": [
{
"id": "external_parties_placement",
"component": "external_parties",
"relation": "root",
"basis": {
"kind": "inferred",
"text": "External Parties is at the diagram root."
}
},
{
"id": "application_cloud_placement",
"component": "application_cloud",
"relation": "root",
"basis": {
"kind": "inferred",
"text": "Application Cloud is at the diagram root."
}
},
{
"id": "cloud_account_placement",
"component": "cloud_account",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Cloud Account is directly inside Application Cloud."
},
"group": "application_cloud"
},
{
"id": "primary_region_placement",
"component": "primary_region",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Primary Region is directly inside Cloud Account."
},
"group": "cloud_account"
},
{
"id": "primary_network_placement",
"component": "primary_network",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Primary Private Network is directly inside Primary Region."
},
"group": "primary_region"
},
{
"id": "primary_cluster_placement",
"component": "primary_cluster",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Application Cluster is directly inside Primary Private Network."
},
"group": "primary_network"
},
{
"id": "recovery_region_placement",
"component": "recovery_region",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Recovery Region is directly inside Cloud Account."
},
"group": "cloud_account"
},
{
"id": "recovery_network_placement",
"component": "recovery_network",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Recovery Network is directly inside Recovery Region."
},
"group": "recovery_region"
},
{
"id": "buyer_placement",
"component": "buyer",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Public Buyer is directly inside External Parties."
},
"group": "external_parties"
},
{
"id": "payment_service_placement",
"component": "payment_service",
"relation": "outside",
"basis": {
"kind": "explicit",
"text": "Payment Service is outside Application Cloud."
},
"group": "application_cloud"
},
{
"id": "warehouse_placement",
"component": "warehouse",
"relation": "outside",
"basis": {
"kind": "explicit",
"text": "External Warehouse is outside Application Cloud."
},
"group": "application_cloud"
},
{
"id": "primary_lb_placement",
"component": "primary_lb",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Primary Load Balancer is directly inside Primary Region."
},
"group": "primary_region"
},
{
"id": "api_server_placement",
"component": "api_server",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "API Server is directly inside Application Cluster."
},
"group": "primary_cluster"
},
{
"id": "primary_database_placement",
"component": "primary_database",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Primary Database is directly inside Primary Private Network."
},
"group": "primary_network"
},
{
"id": "primary_cache_placement",
"component": "primary_cache",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Primary Cache is directly inside Primary Private Network."
},
"group": "primary_network"
},
{
"id": "work_queue_placement",
"component": "work_queue",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Regional Work Queue is directly inside Primary Region."
},
"group": "primary_region"
},
{
"id": "worker_server_placement",
"component": "worker_server",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Worker Server is directly inside Application Cluster."
},
"group": "primary_cluster"
},
{
"id": "receipt_storage_placement",
"component": "receipt_storage",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Receipt Storage is directly inside Primary Region."
},
"group": "primary_region"
},
{
"id": "recovery_database_placement",
"component": "recovery_database",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Recovery Database is directly inside Recovery Network."
},
"group": "recovery_network"
},
{
"id": "recovery_app_placement",
"component": "recovery_app",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Recovery Application Server is directly inside Recovery Network."
},
"group": "recovery_network"
},
{
"id": "recovery_lb_placement",
"component": "recovery_lb",
"relation": "parent",
"basis": {
"kind": "explicit",
"text": "Recovery Load Balancer is directly inside Recovery Region."
},
"group": "recovery_region"
}
],
"allowAdditionalResources": false
}
Download Requirements ↓ Review note: Strict validation reports 19 routing findings, mostly plain arrow crossings; accepted in review.
Create a cloud-neutral order processing architecture in one cloud account with primary and recovery regions. A public buyer reaches a regional load balancer, which forwards requests to an API server inside the primary private application network and cluster. The database and cache are in the same private network. The API uses them, calls an external payment service, and enqueues work in a regional queue outside the network. Show separate database, cache, and payment response arrows back to the API. The queue feeds a worker server in the application cluster. The worker sends fulfillment to an external warehouse and receives its acknowledgment back; it retries by sending work back to the queue. It also writes order status to the primary database and receipts to object storage outside the network. The primary database replicates to a recovery database inside a recovery network. A recovery application server reads that replica and can serve the buyer through a recovery load balancer. Keep payment and warehouse external, and preserve all directions and containment.Download Prompt ↓
dgm 1
diagram cloud-agnostic-hard-order-processing {
grammar cloud-agnostic
flow lr
title "Order processing (cloud-neutral)"
cloud-agnostic.client buyer "Buyer"
cloud-agnostic.actor payment "External payment service"
cloud-agnostic.actor warehouse "External warehouse"
cloud-agnostic.account account "Cloud account" {
cloud-agnostic.region primary "Primary region" {
cloud-agnostic.load-balancer lb "Load balancer"
cloud-agnostic.network network "Primary application network" {
cloud-agnostic.cluster cluster "Application cluster" {
cloud-agnostic.server api "API server"
cloud-agnostic.server worker "Worker server"
}
cloud-agnostic.database db "Primary database"
cloud-agnostic.cache cache "Cache"
}
cloud-agnostic.queue queue "Work queue"
cloud-agnostic.object-storage receipts "Receipt storage"
}
cloud-agnostic.region recovery "Recovery region" {
cloud-agnostic.load-balancer rlb "Recovery load balancer"
cloud-agnostic.network rnetwork "Recovery network" {
cloud-agnostic.server rapp "Recovery app server"
cloud-agnostic.database rdb "Recovery database"
}
}
}
buyer -> lb { id order step 1 label "Orders" kind flow }
lb -> api { id forward step 2 label "Forward" kind flow }
api -> db { id db_query step 3 label "Query" kind flow }
api -> cache { id cache_lookup step 3 label "Lookup" kind flow }
api -> payment { id charge step 3 label "Charge" kind flow }
db -> api { id db_resp label "Database response" kind flow style dashed }
cache -> api { id cache_resp label "Cache response" kind flow style dashed }
payment -> api { id payment_resp label "Payment response" kind flow style dashed }
api -> queue { id enqueue step 4 label "Enqueue work" kind flow }
queue -> worker { id dispatch step 5 label "Work" kind flow }
worker -> warehouse { id fulfill step 6 label "Fulfillment" kind flow }
warehouse -> worker { id ack label "Acknowledgment" kind flow style dashed }
worker -> queue { id retry label "Retry" kind fail }
worker -> db { id order_status step 6 label "Order status" kind flow }
worker -> receipts { id write_receipts step 6 label "Receipts" kind flow }
db -> rdb { id replicate step 7 label "Replication" kind flow }
rdb -> rapp { id read_replica step 8 label "Read replica" kind flow }
buyer -> rlb { id failover label "Failover requests" kind flow style dashed }
rlb -> rapp { id failover_fwd label "Forward" kind flow style dashed }
}
Download .dgm source ↓ {
"$schema": "../../.dumbdiagrams/requirements.schema.json",
"version": 1,
"grammar": "cloud-agnostic",
"components": [
{
"id": "buyer",
"kind": "resource",
"type": "cloud-agnostic.client",
"basis": {
"kind": "explicit",
"text": "Buyer reaches regional load balancer to API server in primary private network and cluster; database and cache in network; API calls external payment and enqu..."
}
},
{
"id": "payment",
"kind": "resource",
"type": "cloud-agnostic.actor",
"basis": {
"kind": "explicit",
"text": "Buyer reaches regional load balancer to API server in primary private network and cluster; database and cache in network; API calls external payment and enqu..."
}
},
{
"id": "warehouse",
"kind": "resource",
"type": "cloud-agnostic.actor",
"basis": {
"kind": "explicit",
"text": "Buyer reaches regional load balancer to API server in primary private network and cluster; database and cache in network; API calls external payment and enqu..."
}
},
{
"id": "account",
"kind": "group",
"type": "cloud-agnostic.account",
"basis": {
"kind": "explicit",
"text": "Buyer reaches regional load balancer to API server in primary private network and cluster; database and cache in network; API calls external payment and enqu..."
}
},
{
"id": "primary",
"kind": "group",
"type": "cloud-agnostic.region",
"basis": {
"kind": "explicit",
"text": "Buyer reaches regional load balancer to API server in primary private network and cluster; database and cache in network; API calls external payment and enqu..."
}
},
{
"id": "lb",
"kind": "resource",
"type": "cloud-agnostic.load-balancer",
"basis": {
"kind": "explicit",
"text": "Buyer reaches regional load balancer to API server in primary private network and cluster; database and cache in network; API calls external payment and enqu..."
}
},
{
"id": "network",
"kind": "group",
"type": "cloud-agnostic.network",
"basis": {
"kind": "explicit",
"text": "Buyer reaches regional load balancer to API server in primary private network and cluster; database and cache in network; API calls external payment and enqu..."
}
},
{
"id": "cluster",
"kind": "group",
"type": "cloud-agnostic.cluster",
"basis": {
"kind": "explicit",
"text": "Buyer reaches regional load balancer to API server in primary private network and cluster; database and cache in network; API calls external payment and enqu..."
}
},
{
"id": "api",
"kind": "resource",
"type": "cloud-agnostic.server",
"basis": {
"kind": "explicit",
"text": "Buyer reaches regional load balancer to API server in primary private network and cluster; database and cache in network; API calls external payment and enqu..."
}
},
{
"id": "worker",
"kind": "resource",
"type": "cloud-agnostic.server",
"basis": {
"kind": "explicit",
"text": "Buyer reaches regional load balancer to API server in primary private network and cluster; database and cache in network; API calls external payment and enqu..."
}
},
{
"id": "db",
"kind": "resource",
"type": "cloud-agnostic.database",
"basis": {
"kind": "explicit",
"text": "Buyer reaches regional load balancer to API server in primary private network and cluster; database and cache in network; API calls external payment and enqu..."
}
},
{
"id": "cache",
"kind": "resource",
"type": "cloud-agnostic.cache",
"basis": {
"kind": "explicit",
"text": "Buyer reaches regional load balancer to API server in primary private network and cluster; database and cache in network; API calls external payment and enqu..."
}
},
{
"id": "queue",
"kind": "resource",
"type": "cloud-agnostic.queue",
"basis": {
"kind": "explicit",
"text": "Buyer reaches regional load balancer to API server in primary private network and cluster; database and cache in network; API calls external payment and enqu..."
}
},
{
"id": "receipts",
"kind": "resource",
"type": "cloud-agnostic.object-storage",
"basis": {
"kind": "explicit",
"text": "Buyer reaches regional load balancer to API server in primary private network and cluster; database and cache in network; API calls external payment and enqu..."
}
},
{
"id": "recovery",
"kind": "group",
"type": "cloud-agnostic.region",
"basis": {
"kind": "explicit",
"text": "Buyer reaches regional load balancer to API server in primary private network and cluster; database and cache in network; API calls external payment and enqu..."
}
},
{
"id": "rlb",
"kind": "resource",
"type": "cloud-agnostic.load-balancer",
"basis": {
"kind": "explicit",
"text": "Buyer reaches regional load balancer to API server in primary private network and cluster; database and cache in network; API calls external payment and enqu..."
}
},
{
"id": "rnetwork",
"kind": "group",
"type": "cloud-agnostic.network",
"basis": {
"kind": "explicit",
"text": "Buyer reaches regional load balancer to API server in primary private network and cluster; database and cache in network; API calls external payment and enqu..."
}
},
{
"id": "rapp",
"kind": "resource",
"type": "cloud-agnostic.server",
"basis": {
"kind": "explicit",
"text": "Buyer reaches regional load balancer to API server in primary private network and cluster; database and cache in network; API calls external payment and enqu..."
}
},
{
"id": "rdb",
"kind": "resource",
"type": "cloud-agnostic.database",
"basis": {
"kind": "explicit",
"text": "Buyer reaches regional load balancer to API server in primary private network and cluster; database and cache in network; API calls external payment and enqu..."
}
}
],
"relationships": [
{
"id": "order",
"source": "buyer",
"target": "lb",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Orders (buyer to lb) per the request."
}
},
{
"id": "forward",
"source": "lb",
"target": "api",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Forward (lb to api) per the request."
}
},
{
"id": "db_query",
"source": "api",
"target": "db",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Query (api to db) per the request."
}
},
{
"id": "cache_lookup",
"source": "api",
"target": "cache",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Lookup (api to cache) per the request."
}
},
{
"id": "charge",
"source": "api",
"target": "payment",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Charge (api to payment) per the request."
}
},
{
"id": "db_resp",
"source": "db",
"target": "api",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Database response (db to api) per the request."
}
},
{
"id": "cache_resp",
"source": "cache",
"target": "api",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Cache response (cache to api) per the request."
}
},
{
"id": "payment_resp",
"source": "payment",
"target": "api",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Payment response (payment to api) per the request."
}
},
{
"id": "enqueue",
"source": "api",
"target": "queue",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Enqueue work (api to queue) per the request."
}
},
{
"id": "dispatch",
"source": "queue",
"target": "worker",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Work (queue to worker) per the request."
}
},
{
"id": "fulfill",
"source": "worker",
"target": "warehouse",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Fulfillment (worker to warehouse) per the request."
}
},
{
"id": "ack",
"source": "warehouse",
"target": "worker",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Acknowledgment (warehouse to worker) per the request."
}
},
{
"id": "retry",
"source": "worker",
"target": "queue",
"kind": "fail",
"basis": {
"kind": "explicit",
"text": "Retry (worker to queue) per the request."
}
},
{
"id": "order_status",
"source": "worker",
"target": "db",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Order status (worker to db) per the request."
}
},
{
"id": "write_receipts",
"source": "worker",
"target": "receipts",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Receipts (worker to receipts) per the request."
}
},
{
"id": "replicate",
"source": "db",
"target": "rdb",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Replication (db to rdb) per the request."
}
},
{
"id": "read_replica",
"source": "rdb",
"target": "rapp",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Read replica (rdb to rapp) per the request."
}
},
{
"id": "failover",
"source": "buyer",
"target": "rlb",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Failover requests (buyer to rlb) per the request."
}
},
{
"id": "failover_fwd",
"source": "rlb",
"target": "rapp",
"kind": "flow",
"basis": {
"kind": "explicit",
"text": "Forward (rlb to rapp) per the request."
}
}
],
"counts": [],
"placement": [
{
"id": "buyer_root",
"component": "buyer",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "payment_root",
"component": "payment",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "warehouse_root",
"component": "warehouse",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "account_root",
"component": "account",
"relation": "root",
"basis": {
"kind": "explicit",
"text": "Placed outside any cloud boundary."
}
},
{
"id": "primary_in_account",
"component": "primary",
"relation": "parent",
"group": "account",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "lb_in_primary",
"component": "lb",
"relation": "parent",
"group": "primary",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "network_in_primary",
"component": "network",
"relation": "parent",
"group": "primary",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "cluster_in_network",
"component": "cluster",
"relation": "parent",
"group": "network",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "api_in_cluster",
"component": "api",
"relation": "parent",
"group": "cluster",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "worker_in_cluster",
"component": "worker",
"relation": "parent",
"group": "cluster",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "db_in_network",
"component": "db",
"relation": "parent",
"group": "network",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "cache_in_network",
"component": "cache",
"relation": "parent",
"group": "network",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "queue_in_primary",
"component": "queue",
"relation": "parent",
"group": "primary",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "receipts_in_primary",
"component": "receipts",
"relation": "parent",
"group": "primary",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "recovery_in_account",
"component": "recovery",
"relation": "parent",
"group": "account",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "rlb_in_recovery",
"component": "rlb",
"relation": "parent",
"group": "recovery",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "rnetwork_in_recovery",
"component": "rnetwork",
"relation": "parent",
"group": "recovery",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "rapp_in_rnetwork",
"component": "rapp",
"relation": "parent",
"group": "rnetwork",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "rdb_in_rnetwork",
"component": "rdb",
"relation": "parent",
"group": "rnetwork",
"basis": {
"kind": "explicit",
"text": "Containment described in the request."
}
},
{
"id": "lb_outside_network",
"component": "lb",
"relation": "outside",
"group": "network",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
},
{
"id": "queue_outside_network",
"component": "queue",
"relation": "outside",
"group": "network",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
},
{
"id": "receipts_outside_network",
"component": "receipts",
"relation": "outside",
"group": "network",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
},
{
"id": "payment_outside_account",
"component": "payment",
"relation": "outside",
"group": "account",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
},
{
"id": "warehouse_outside_account",
"component": "warehouse",
"relation": "outside",
"group": "account",
"basis": {
"kind": "explicit",
"text": "Kept outside the network boundary per the request."
}
}
],
"allowAdditionalResources": false
}
Download Requirements ↓