Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"plugins": [
{
"category": "deployment",
"description": "Deploy applications to AWS with architecture recommendations, cost estimates, and IaC deployment.",
"description": "Deploy applications to AWS with architecture recommendations, cost estimates, IaC deployment, and architecture diagram generation.",
"keywords": [
"aws",
"aws agent skills",
Expand All @@ -20,12 +20,14 @@
"cdk",
"cloudformation",
"infrastructure",
"pricing"
"pricing",
"diagram",
"architecture"
],
"name": "deploy-on-aws",
"source": "./plugins/deploy-on-aws",
"tags": ["aws", "deploy", "infrastructure", "cdk"],
"version": "1.1.0"
"tags": ["aws", "deploy", "infrastructure", "cdk", "diagram"],
"version": "1.2.0"
},
{
"category": "location",
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ Equips agents with the skills to accelerate AWS deployment - recommending AWS ar
| Agent Skill | Triggers |
| ----------- | --------------------------------------------------------------------------------------------------------------------- |
| **deploy** | "deploy to AWS", "host on AWS", "run this on AWS", "AWS architecture", "estimate AWS cost", "generate infrastructure" |
| **diagram** | "architecture diagram", "draw architecture", "generate diagram", "infrastructure diagram", "AWS diagram" |

### MCP Servers

Expand Down
8 changes: 5 additions & 3 deletions plugins/deploy-on-aws/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@
"author": {
"name": "Amazon Web Services"
},
"description": "Deploy applications to AWS with architecture recommendations, cost estimates, and IaC deployment.",
"description": "Deploy applications to AWS with architecture recommendations, cost estimates, IaC deployment, and architecture diagram generation.",
"homepage": "https://github.com/awslabs/agent-plugins",
"keywords": [
"aws",
"deploy",
"infrastructure",
"cdk",
"cloudformation",
"pricing"
"pricing",
"diagram",
"architecture"
],
"license": "Apache-2.0",
"name": "deploy-on-aws",
"repository": "https://github.com/awslabs/agent-plugins",
"version": "1.1.0"
"version": "1.2.0"
}
80 changes: 80 additions & 0 deletions plugins/deploy-on-aws/skills/diagram/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
name: diagram
description: "Generate architecture diagrams as code using the Python diagrams DSL. Triggers on phrases like: architecture diagram, system design diagram, draw architecture, generate diagram, infrastructure diagram, AWS diagram, Kubernetes diagram, network diagram, visualize architecture."
---

# Architecture Diagram Generation

Generate architecture diagrams using the Python [diagrams](https://diagrams.mingrammer.com/) package. Write a Python script, run it, and produce a PNG.

Supports AWS (29 service categories), Kubernetes, on-premises, GCP, SaaS, and custom icons via the `diagrams` DSL.

## When to Load Reference Files

Load the appropriate reference file based on what the user is building:

- **Any diagram** -> ALWAYS load [references/dsl-syntax.md](references/dsl-syntax.md) first for DSL syntax, constructor options, connections, clusters, and edge styles
- **AWS architecture**, **cloud infrastructure**, or **AWS services** -> load [references/aws-services.md](references/aws-services.md) for AWS import paths, common icons, and 5 AWS examples
- **Kubernetes**, **on-premises**, **SaaS**, **flowcharts**, **sequence diagrams**, **custom icons**, or **non-AWS diagrams** -> load [references/non-aws-providers.md](references/non-aws-providers.md) for K8s, on-prem, flowchart, and custom icon examples
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The skill claims support for "sequence diagrams", but the Python diagrams DSL (GraphViz-based) doesn't produce UML sequence diagrams. Please remove this trigger/category or clarify what diagram types are actually supported.

Suggested change
- **Kubernetes**, **on-premises**, **SaaS**, **flowcharts**, **sequence diagrams**, **custom icons**, or **non-AWS diagrams** -> load [references/non-aws-providers.md](references/non-aws-providers.md) for K8s, on-prem, flowchart, and custom icon examples
- **Kubernetes**, **on-premises**, **SaaS**, **flowcharts**, **custom icons**, or **non-AWS diagrams** -> load [references/non-aws-providers.md](references/non-aws-providers.md) for K8s, on-prem, flowchart, and custom icon examples

Copilot uses AI. Check for mistakes.

## Workflow

1. Load [references/dsl-syntax.md](references/dsl-syntax.md)
2. Load the relevant provider reference (AWS or non-AWS)
3. Write a Python script using the `diagrams` DSL
4. Run: `mkdir -p generated-diagrams && python diagram.py`
5. Verify the PNG was created in `generated-diagrams/`
Comment on lines +24 to +26
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workflow uses python diagram.py but the prerequisites/verification use python3. Using python can invoke Python 2 or a different environment. Also, step 5 says to verify a PNG even though outformat can be overridden (e.g., SVG). Consider standardizing on python3 and verifying the generated file based on the chosen outformat.

Copilot uses AI. Check for mistakes.

## Critical Rules

- ALWAYS set `show=False` in `Diagram()` constructor
- ALWAYS set `filename="generated-diagrams/<name>"` (no `.png` extension)
- ALWAYS use explicit imports: `from diagrams.aws.compute import EC2`
- ALWAYS run `mkdir -p generated-diagrams` before executing
- Use `Cluster()` to group related resources (VPCs, subnets, namespaces)
- Use `Edge(label=, color=, style=)` for labeled or styled connections

## Defaults

Default output format: PNG
Default layout direction: TB (top-to-bottom)

Override syntax:

- "left to right" -> Use `direction="LR"`
- "SVG format" -> Use `outformat="svg"`

When not specified, ALWAYS use `direction="TB"` and `outformat="png"`.

## Prerequisites

Requires two dependencies installed locally:

1. **GraphViz** (system package providing `dot`):
- macOS: `brew install graphviz`
- Ubuntu/Debian: `sudo apt-get install graphviz`
- Amazon Linux/RHEL: `sudo yum install graphviz`
2. **Python diagrams package**: `pip install diagrams`

**Verify:** `dot -V && python3 -c "import diagrams; print('OK')"`

### Missing Dependencies

If `dot` command not found:

- Inform user: "GraphViz is not installed. Required for diagram rendering."
- Show install command for detected OS
- DO NOT attempt to generate diagrams without GraphViz

If `import diagrams` fails:

- Inform user: "Python diagrams package not installed."
- Show: `pip install diagrams`
- DO NOT proceed without the package

## References

- [DSL syntax and patterns](references/dsl-syntax.md)
- [AWS services and examples](references/aws-services.md)
- [Non-AWS providers and examples](references/non-aws-providers.md)
- [diagrams documentation](https://diagrams.mingrammer.com/)
111 changes: 111 additions & 0 deletions plugins/deploy-on-aws/skills/diagram/references/aws-services.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# AWS Services and Examples

## AWS Service Categories

| Category | Import Path | Common Icons |
|----------|------------|--------------|
| `analytics` | `diagrams.aws.analytics` | Athena, EMR, Glue, Kinesis, Redshift, Quicksight |
| `compute` | `diagrams.aws.compute` | EC2, Lambda, ECS, EKS, Fargate, Batch |
| `database` | `diagrams.aws.database` | RDS, Aurora, DynamoDB, ElastiCache, Redshift, Neptune |
| `integration` | `diagrams.aws.integration` | SQS, SNS, StepFunctions, EventBridge, MQ |
| `management` | `diagrams.aws.management` | CloudWatch, CloudFormation, SystemsManager |
| `ml` | `diagrams.aws.ml` | Sagemaker, Rekognition, Comprehend, Bedrock |
| `network` | `diagrams.aws.network` | VPC, ELB, ALB, NLB, CloudFront, Route53, APIGateway |
| `security` | `diagrams.aws.security` | IAM, Cognito, WAF, KMS, Shield, SecretsManager |
| `storage` | `diagrams.aws.storage` | S3, EBS, EFS, FSx, Backup |
| `general` | `diagrams.aws.general` | User, Users, Client, InternetGateway |

Other categories: `ar`, `blockchain`, `business`, `cost`, `devtools`, `enablement`, `enduser`, `engagement`, `game`, `iot`, `media`, `migration`, `mobile`, `quantum`, `robotics`, `satellite`.

## Example: Basic Web Service

```python
from diagrams import Diagram
from diagrams.aws.compute import EC2
from diagrams.aws.database import RDS
from diagrams.aws.network import ELB

with Diagram("Web Service", show=False, filename="generated-diagrams/aws-basic"):
ELB("lb") >> EC2("web") >> RDS("userdb")
```

## Example: Grouped Workers

```python
from diagrams import Diagram
from diagrams.aws.compute import EC2
from diagrams.aws.database import RDS
from diagrams.aws.network import ELB

with Diagram("Grouped Workers", show=False, direction="TB", filename="generated-diagrams/aws-workers"):
ELB("lb") >> [EC2("w1"), EC2("w2"), EC2("w3"), EC2("w4"), EC2("w5")] >> RDS("events")
```

## Example: Clustered Web Services

```python
from diagrams import Diagram, Cluster
from diagrams.aws.compute import ECS
from diagrams.aws.database import RDS, ElastiCache
from diagrams.aws.network import ELB, Route53

with Diagram("Clustered Web Services", show=False, filename="generated-diagrams/aws-clustered"):
dns = Route53("dns")
lb = ELB("lb")
with Cluster("Services"):
svc_group = [ECS("web1"), ECS("web2"), ECS("web3")]
with Cluster("DB Cluster"):
db_primary = RDS("userdb")
db_primary - [RDS("userdb ro")]
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example uses db_primary - [RDS("userdb ro")]. The - operator in the diagrams DSL is typically used between nodes, not a list, so this is likely to fail at runtime. Use a single replica node (or assign the replica to a variable) instead of wrapping it in a list.

Suggested change
db_primary - [RDS("userdb ro")]
db_replica = RDS("userdb ro")
db_primary - db_replica

Copilot uses AI. Check for mistakes.
memcached = ElastiCache("memcached")
dns >> lb >> svc_group
svc_group >> db_primary
svc_group >> memcached
```

## Example: Event Processing

```python
from diagrams import Diagram, Cluster
from diagrams.aws.compute import ECS, EKS, Lambda
from diagrams.aws.analytics import Redshift
from diagrams.aws.integration import SQS
from diagrams.aws.storage import S3

with Diagram("Event Processing", show=False, filename="generated-diagrams/aws-events"):
source = EKS("k8s source")
with Cluster("Event Flows"):
with Cluster("Event Workers"):
workers = [ECS("w1"), ECS("w2"), ECS("w3")]
queue = SQS("event queue")
with Cluster("Processing"):
handlers = [Lambda("p1"), Lambda("p2"), Lambda("p3")]
store = S3("events store")
dw = Redshift("analytics")
source >> workers >> queue >> handlers
handlers >> store
handlers >> dw
```

## Example: S3 Image Processing with Bedrock

```python
from diagrams import Diagram, Cluster, Edge
from diagrams.aws.compute import Lambda
from diagrams.aws.general import User
from diagrams.aws.ml import Bedrock
from diagrams.aws.storage import S3

with Diagram("S3 Image Processing", show=False, direction="LR", filename="generated-diagrams/aws-bedrock"):
user = User("User")
with Cluster("S3 Bucket"):
input_folder = S3("Input")
output_folder = S3("Output")
fn = Lambda("Processor")
bedrock = Bedrock("Claude Sonnet")
user >> Edge(label="Upload") >> input_folder
input_folder >> Edge(label="Trigger") >> fn
fn >> Edge(label="Process") >> bedrock
bedrock >> Edge(label="Result") >> fn
fn >> Edge(label="Save") >> output_folder
```
110 changes: 110 additions & 0 deletions plugins/deploy-on-aws/skills/diagram/references/dsl-syntax.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Diagrams DSL Syntax Reference

## Basic Structure

```python
from diagrams import Diagram, Cluster, Edge
from diagrams.aws.compute import EC2, Lambda
from diagrams.aws.database import RDS
from diagrams.aws.network import ELB

with Diagram("Title", show=False, filename="generated-diagrams/name"):
with Cluster("VPC"):
lb = ELB("ALB")
Comment on lines +9 to +13
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the basic structure example, ELB("ALB") mixes the ELB icon with an "ALB" label. If the intent is an Application Load Balancer, use the ALB node/icon; otherwise rename the label to avoid confusion.

Suggested change
from diagrams.aws.network import ELB
with Diagram("Title", show=False, filename="generated-diagrams/name"):
with Cluster("VPC"):
lb = ELB("ALB")
from diagrams.aws.network import ALB
with Diagram("Title", show=False, filename="generated-diagrams/name"):
with Cluster("VPC"):
lb = ALB("ALB")

Copilot uses AI. Check for mistakes.
with Cluster("Private Subnet"):
servers = [EC2("web1"), EC2("web2")]
db = RDS("PostgreSQL")
lb >> servers >> db
```

## Diagram Constructor

```python
Diagram(
name="Diagram Title", # Title shown on the diagram
show=False, # ALWAYS False -- don't open viewer
filename="path/name", # Output path (no .png extension)
direction="TB", # TB (top-bottom), LR (left-right), BT, RL
outformat="png", # png (default), jpg, svg, pdf
)
```

## Connections

```python
node1 >> node2 >> node3 # Left to right flow
node1 << node2 # Right to left flow
node1 - node2 # Bidirectional
node1 >> [node2, node3, node4] # Fan out to multiple
node1 >> Edge(label="HTTPS", color="darkgreen", style="dashed") >> node2
```

## Clusters

```python
with Cluster("VPC"):
with Cluster("Public Subnet"):
lb = ELB("ALB")
with Cluster("Private Subnet"):
app = [EC2("app1"), EC2("app2")]
with Cluster("Data"):
db = RDS("db")
lb >> app >> db
```

## Edge Styles

| Parameter | Values |
|-----------|--------|
| `color` | `"darkgreen"`, `"firebrick"`, `"brown"`, `"darkorange"`, `"black"`, any CSS color |
| `style` | `"solid"`, `"dashed"`, `"dotted"`, `"bold"` |
| `label` | Any string |

## Provider Import Paths

| Provider | Import Pattern | Example |
|----------|---------------|---------|
| AWS | `diagrams.aws.<category>` | `from diagrams.aws.compute import EC2` |
| GCP | `diagrams.gcp.<category>` | `from diagrams.gcp.storage import GCS` |
| Kubernetes | `diagrams.k8s.<category>` | `from diagrams.k8s.compute import Pod` |
| On-premises | `diagrams.onprem.<category>` | `from diagrams.onprem.database import PostgreSQL` |
| SaaS | `diagrams.saas.<category>` | `from diagrams.saas.chat import Slack` |
| Programming | `diagrams.programming.<category>` | `from diagrams.programming.flowchart import Action` |
| Generic | `diagrams.generic.<category>` | `from diagrams.generic.compute import Rack` |
| Custom | `diagrams.custom` | `Custom("name", "icon.png")` |

## Common Patterns

### Fan-out / Fan-in

```python
source >> [worker1, worker2, worker3] >> sink
```

### Bidirectional with Replica

```python
primary = RDS("primary")
primary - RDS("replica")
```

### Nested Clusters

```python
with Cluster("VPC"):
with Cluster("Public"):
lb = ELB("ALB")
with Cluster("Private"):
app = [EC2("app1"), EC2("app2")]
lb >> app
```

### Custom Nodes

```python
from diagrams.custom import Custom
from urllib.request import urlretrieve

icon_path, _ = urlretrieve("https://example.com/icon.png", "icon.png")
Comment on lines +106 to +108
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The custom node example downloads an icon at runtime via urlretrieve, which adds an external network dependency and can pull untrusted content. Prefer referencing a local icon file path (or document a separate, manual download step with integrity verification) so diagram generation is deterministic and safer.

Suggested change
from urllib.request import urlretrieve
icon_path, _ = urlretrieve("https://example.com/icon.png", "icon.png")
# Use a local icon file. Download or place the icon in your project beforehand.
icon_path = "icons/my-service.png"

Copilot uses AI. Check for mistakes.
custom_node = Custom("My Service", icon_path)
```
Loading
Loading