Generate an editable OCI architecture diagram in draw.io from Terraform or a plain-text description. Run /drawio-architect in Claude Code to turn your input into a validated .drawio file with Oracle Cloud Infrastructure icons.
Author: Sergio Farfan · sergio.farfan@gmail.com Version: 1.5.0 · Install the plugin · Download archive · Changelog
Single-VCN topology with the on-premises panel, region-level DRG and its VCN attachment, subnets with NSG shields on the protected resources, gateways on the VCN border and the Oracle Services Network panel — rendered by draw.io from the reference layout example (oci-drawio-architect/examples/generate_reference_layout.py); every connector is routed automatically.
Detail view: data subnet, Service Gateway on the bottom border facing the Oracle Services Network band — uniform icon sizes, captions under every icon, connectors kept in the gutters.
If you've ever had to document an OCI architecture, you know the drill. You open draw.io, hunt for the right Oracle icon set, drag shapes onto the canvas, manually wire up VCNs and subnets, nudge elements into alignment, then spend another 30 minutes making sure the colors match Oracle's official template — only to realize the Terraform config changed last week and the diagram is already out of date.
For cloud architects working with OCI, this is a recurring tax on every project:
- Diagrams drift from reality. Terraform is the source of truth, but draw.io doesn't know that. Every infrastructure change means a manual diagram update that usually doesn't happen until someone asks for it in a review.
- The OCI icon set is not built into draw.io. You have to find it, import it, and figure out which icon maps to which service — across a dozen categories and more than 150 icons.
- Layout is time-consuming. Getting the Region > VCN > Subnet > Service hierarchy right, with proper spacing, no overlapping containers, and Oracle's color scheme, takes significant effort even for experienced users.
- Hub-and-spoke topologies are especially painful. When you have 10–15 spoke VCNs connected through a DRG, laying that out cleanly by hand is an hour-long exercise in pixel arithmetic.
- Diagrams are created once and abandoned. Because updating them is expensive, teams stop maintaining them. By the time a new engineer joins or an audit happens, the diagram shows an architecture from two sprints ago.
The root cause: architecture diagrams are treated as a design artifact — something you create manually — rather than something you generate from the actual infrastructure definition.
The plugin accepts three input types: a Terraform directory (HCL or terraform show -json output) — parsed to extract VCNs, subnets, gateways, and DRG attachments — a VCN name resolved against existing .tfvars files, or a plain-text description of the target architecture. Whatever the input, it is first normalized into a small model (subject, region, hub, VCNs with subnets and their icons, an OCI Services panel, gateways, edges). A deterministic layout recipe (scripts/oci_layout.py) turns that model into a diagram with the same structure as the reference sample: subnets in traffic order, a services panel, a gateway row, a hub panel vertically centred on the VCN. Under the hood, a DrawioBuilder class backed by 159 bundled OCI SVG icons sizes every container from its children, routes every connector through the gutters so it doesn't cross unrelated icons or captions, styles everything with Oracle's Redwood palette, and validates the result (overlaps, containment, dangling ids, label overflow, edge crossings) before the file is written. If draw.io desktop is installed, the plugin also exports a PNG so the result can be inspected visually. The entire workflow runs inside Claude Code via a single /drawio-architect command.
- Settings — on first run, auto-detects tenancy, region, VCNs, compartments and logos from Terraform configs,
~/.oci/configand the OCI CLI, and saves them to.claude/oci-drawio-architect.local.md - Input — asks what to diagram: Terraform directory path, VCN name, or free-form description
- Model — normalizes the input into the diagram model (VCNs, subnets, services with their regional / VCN-resident class, gateways, DRGs with attachments, on-premises side, edges)
- Generate — writes a
generate_<name>_drawio.pyscript that imports the plugin'sDrawioBuilder/oci_layoutdirectly from the plugin (sys.path.insert(0, "<plugin>/scripts")) — nothing is copied into your project - Run — executes the script to produce the
.drawiofile - Validate + render — gates on
scripts/check_overlaps.py(exit 0 required) and, when draw.io desktop is available, exports a PNG withscripts/render_drawio.pyfor a visual check - Report — file path, size, what's in the diagram, settings used, and viewing instructions
All four types share the same model and layout recipe; the page is sized from the content (fit_page()), so there is no fixed canvas size to pick.
| Type | Best For | Layout |
|---|---|---|
| Single-VCN Topology | Application stacks | Region > optional on-premises panel + DRG column + one VCN column: subnet rows in traffic order, data tier, gateways on the VCN border, Oracle Services Network panel |
| Hub-and-Spoke Network | Network overview with DRG | On-premises panel (CPE), region-level DRG with one attachment box per spoke, spoke VCN columns, OSN panel; attachment connectors without arrowheads |
| Service Inventory | Compartment-level resource view | Compartment and services panels built with place_icons() / fit_to_children(); NSG or route rules as add_table() pages |
| Multi-VCN Overview | VCN interconnections via DRG | Several VCN columns, LPG pairs on facing borders, OSN panel, cross-VCN edges |
draw.io offers a connector for AI hosts — its hosted MCP server at mcp.draw.io, which can be added as a remote connector. This plugin deliberately does not use it:
- No Oracle Cloud shapes. draw.io's built-in shape libraries cover AWS, Azure, GCP and IBM but not OCI (adding Oracle's library to the standard product is still an open request on the draw.io issue tracker), so the plugin bundles Oracle's official OCI Architecture Diagram Toolkit icons and embeds them in the file.
- Generation stays local. The
.drawiofile is built on your machine by the bundled Python scripts, so diagram content — VCN names, CIDRs, hostnames, OCIDs — never leaves it. Using the connector means sending the diagram to a server outside your machine for rendering. - The preview does not work here. The connector's inline preview needs a host that implements the MCP Apps protocol; Claude Code does not, so the diagram never appears. draw.io desktop covers viewing, and
scripts/render_drawio.pyexports PNG, SVG and PDF from the command line.
View and detail controls: one discovered topology, several readable views (design: the v1.5.0 spec, full list in the changelog):
- Label modes. Captions become a rendered field list -
minimal,network(the new default) anddetailed- over a documented vocabulary (name, type, private/public IP, CIDR, FQDN, port/protocol, compartment, AD/FD, lifecycle, tags). An OCID is never rendered in a caption, in any mode; a hand-written model's caption is unaffected. - View layers. The diagram can be emitted onto real draw.io layers -
routes,security,iam,dataflow,management,associations- over a base layer namedNetwork, toggled withCmd/Ctrl+Shift+Lwithout regenerating the file. - Detail levels.
executive,application,network(default, today's output) andengineering, each a composition of the label mode, the layer set and a small table of content gates. - Filtering. One shared predicate over tags, compartment, region, VCN, subnet, resource type, environment and application, applied identically by the Terraform parser, the live-tenancy reader and the layout CLI.
- Participating mode.
all(every discovered resource, the Terraform default) orparticipating(only what takes part in the architecture, the live-tenancy default). - Relationship provenance.
edges[].discoveryreplaces the oldinferredboolean with seven named methods and becomes a filter axis;--annotate-discoveryputs it in the connector tooltip. - Global-services bucket. IAM, Policies, Audit and public DNS can move into a tenancy-scoped box below the region, distinct from the regional Oracle Services Network.
- Purpose presets.
network,dataflow,security,inventory,dependency,ha- the six purposes the team's diagram guidelines name, each a one-flag composition of everything above. - The demo (
examples/generate_demo_diagram.py) grows to six pages: Architecture (the outside canvas with the badge legend), DRG as a box (the nested 1.3.0 canvas), Compartments and OKE, Executive overview, Engineering detail, and Security (the custom-API NSG table).
Placement enrichments: where things go now follows Oracle's Location Canvas and the toolkit's grouping specs (design: the v1.4.0 spec, full list in the changelog):
- Location boxes leave the region. On-Premises sits left of the OCI Region, Internet and 3rd Party Cloud stack in a narrow column to its right, and the
Site-to-Site VPN/FastConnect/Remote Peeringlabel sits in the gap between the on-premises box and the region - the arrangement the toolkit's Location Canvas defines.locations: "nested"restores the 1.3.x canvas exactly. - Gateways face what they connect to. The Internet Gateway and the NAT Gateway take the VCN border facing the Internet box: the right border, IGW above NAT, for the rightmost VCN column, and the top border, IGW rightmost and the captions above the glyphs, for every other column - a left-hand column's right border faces the next VCN, not the Internet box. The Service Gateway moves to the bottom border and the Oracle Services Network becomes a full-width band under the VCN stack. Within a border the order is always
igw, nat, sgw, lpg, never model order.gateway_edgeand a per-gatewaysideoverride it. - Subnet labels are two lines: name with a
(Public)/(Private)token, then the CIDR.subnet_label: "inline"restores the single-line form. - Compartments can become containers around the VCNs they hold, with an optional tenancy wrapper - opt-in via
show_compartments, because a view with every compartment drawn is unreadable. The DRG stays at region level. - Grouping boxes: an OKE cluster box inside a subnet (the parser emits one when a cluster and its node pools share a subnet), plus Oracle's
tieranduser_groupboxes for hand-written models. A box is a real container and an edge may terminate on it. - Badges get a legend, the DRG gets its route-table badges (up to two, the pair Oracle creates by default), and the attachment connector style is selectable (
attachment_style: "solid" | "dotted").
Patch release: correctness fixes and coverage, no new features and no intentional layout change.
- Two DRGs without a
nameno longer abort the build; an unnamed DRG takes its name from the second line of its label, its address or its position. - The Terraform parser no longer invents a DRG attachment for an IPSec connection, a private virtual circuit or a remote peering connection that names no DRG, and says so when it falls back to a single unambiguous DRG.
- Validator: a DRG caption inside a VCN whose border the glyph only straddles is now an error, a leaf inside nested foreign containers is reported once, and a badged container's title is measured against the width its badges leave.
- Layout: badges and captions get the room they need (NSG badge on a custom slot, subnet title beside its corner badges, DRG caption on a bare cluster side, the gap between two VCN columns with facing gateways).
- The hub panel accepts an optional
kind(onprem|remote_region) that selects its title.
Topology-aware placement: the layout recipe now follows how the team's diagram guidelines and Oracle's own reference architectures draw connectivity infrastructure (see the changelog for the complete list):
- The DRG is a region-level element. It sits between the on-premises panel and the VCN columns with one rounded attachment box per attachment beside it (VCN, IPSec, FastConnect, remote peering);
drg_styleicon(default) orboxgroups the boxes under a dashedDRG: <name>frame. - Gateways sit on the VCN border, not in a bottom row: IGW and NAT straddle the bottom, the Service Gateway the right border facing the services panel, LPGs the border facing their peer VCN.
- Regional services get their own Oracle Services Network panel, right of the VCN columns, fed by the Service Gateway; VCN-resident services without a subnet stay in the VCN.
- Four connector kinds and a legend:
data(solid, open arrow),control(dashed, open arrow),association(dotted, no arrowhead) andattachment(thin solid, no arrowhead), plusadd_legend()rows for all four. - New validator rules catch a DRG box parented inside a VCN and any leaf sitting inside a VCN/subnet it does not belong to, with tolerances so border-straddling gateways still pass.
- Model schema 2 (
drgs[]with typed attachments,services[].regional,gateways[].peer) with automatic migration and a warning for schema-1 models. - Route tables, security lists and NSGs are badges, not icons.
subnet.route_table/subnet.security_listsdraw half-size badges on the subnet's top-right corner anditem.nsgsa shield on the protected resource's icon (names in the tooltip);parse_terraform.pyandquery_tenancy.pyfill the fields from the Terraform and topology attributes. The reference sample (OCI_Architecture.drawio) and the screenshots above show the four NSGs as shields on the load balancer, the two VMs and the database; hand-placednsgicons stay valid in existing scripts.
Driven by a full code review and output-quality audit of 1.1.0 (see the changelog for the complete list):
- The workflow works out of the box. Generated scripts import the builder from the plugin directory instead of copying
drawio_builder.pyinto your project; icons resolve through$OCI_SVG_DIR, the plugin'sicons/,$CLAUDE_PLUGIN_ROOT/iconsand the standard~/.claude/pluginsinstall locations. - The reference look is back. Region / on-premises / compartment labels top-left at 12px, charcoal 1px dashed services panel, dashed edges with
dashPattern=6 3, and a font stack (Oracle Sans,Arial,Helvetica,sans-serif) so labels never fall back to a serif face. Three style profiles:default,official(strict OCI toolkit v24.2) andv1.0. New container typesother,metro_or_realm,third_party_cloud,internet. - Icons render at one size, without ghost boxes. 16 icons (VM, Functions, Block Volume, Buckets, Object Storage and others) carried a leftover caption-placeholder rectangle; it is gone, every viewBox is cropped to the glyph, and every glyph is fitted into a uniform 70×70 area of a 75×95 slot. 55 empty stencil shells were removed and 4 scrape-artifact filenames fixed (159 icons in 12 categories remain, every one addressable by file stem plus 206 short aliases).
- Edges route themselves.
add_edge()picks the common-ancestor parent and routes through container margins and gutters, avoiding icons, captions and container titles; labels dodge collisions.route="direct"androute="pinned"keep the 1.1.0 and 1.0.0 behaviours. - Validation catches what used to slip through. Any-two-container overlaps, child containers spilling out of their parent, icon/caption collisions, unknown
parent/source/targetids (which made draw.io silently drop the whole diagram), long captions and estimated edge crossings — with compressed pages andUserObjectwrappers handled. - Layout helpers so nobody hand-computes coordinates:
place_icons,fit_to_children,resize,fit_page,add_title,add_legend,add_table,add_page/use_page/add_layer, deterministic ids viakey=,metadata/tooltip/link,render(). - New tools:
oci_layout.py(model → diagram CLI),render_drawio.py(PNG/SVG/PDF export),build_icon_catalog.py,smoke_test.sh,parse_terraform.py(Terraform HCL directory,--plan-jsonor--state-json→ model, with--vcnfiltering) and the experimentalquery_tenancy.py(live tenancy → model via the OCI CLI);examples/generate_reference_layout.pyrebuilds the reference sample from a model dict; atests/suite covering the builder, settings detection and the icon set. - Settings detection rewritten:
region = var.regionresolved through tfvars and variable defaults, comment stripping, provider-block scoping, complete region table (eu-london-1was never a region —uk-london-1is),[DEFAULT]inheritance in~/.oci/config, CLI timeouts and session-token auth, logo classification fixed, relative logo paths, new keysvcns,compartments,terraform_dirs,auth_tenancy_ocid,oci_auth,subscribed_regions,home_region. - Installer and packager hardened:
python3 -m pip --user, Pillow optional (warns, never blocks),rsyncwithcpfallback, JSON-based upsert ofmarketplace.jsonthat preserves other plugins, 8 verification checks including a post-install smoke test, cleaner uninstall;pack.shis reproducible, excludeslogos/and tarballs, always includesLICENSEandicons/NOTICE, and prints the SHA256.
- Claude Code (CLI) installed and working
- Python 3.9+ — the builder uses only the standard library
- draw.io desktop for viewing generated
.drawiofiles (and for the optional PNG export) - Pillow (optional) — needed only to embed PNG/JPEG logos with
add_image(); SVG logos and all bundled icons work without it - OCI CLI (optional) — for tenancy name and region subscriptions during settings auto-detection
The plugin bundles 159 OCI SVG icons (12 categories, about 1.4 MB); no external icon dependency is needed.
curl -fsSL https://github.com/sergio-farfan/OCI-draw.io-Architect/releases/download/v1.5.0/oci-drawio-architect-v1.5.0.tar.gz | tar -xz && ./oci-drawio-architect/install.shThis will:
- Download and extract the archive
- Check prerequisites (Claude Code directory, Python 3.9+,
rsyncorcp) - Try
python3 -m pip install --user Pillowif Pillow is missing — and continue without it if that fails - Create or update the local marketplace at
~/.claude/plugins/marketplaces/local/(only theoci-drawio-architectentry inmarketplace.jsonis touched) - Copy the plugin files into the marketplace (staged, then swapped in atomically)
- Verify all components (8 checks, including a post-install smoke test that generates the demo diagram and runs the overlap checker on it)
Open Claude Code and run these two commands:
/plugin marketplace add ~/.claude/plugins/marketplaces/local
/plugin install oci-drawio-architect@local
Exit and reopen Claude Code for the plugin to load.
/drawio-architect
The command will prompt you for what to diagram.
On first run, the plugin probes your Terraform files, ~/.oci/config and the OCI CLI (each CLI call is bounded by an 8 s timeout) and saves what it finds:
| Setting | Source | Description |
|---|---|---|
tenancy_name |
OCI CLI (oci iam tenancy get) |
Tenancy display name (for the diagram title) |
tenancy_ocid |
Terraform provider block / tfvars, ~/.oci/config |
Tenancy OCID (must match ocid1.tenancy.) |
auth_tenancy_ocid |
~/.oci/config |
Reported when the CLI identity's tenancy differs from the Terraform one |
region |
Terraform provider "oci" block (var.region resolved via tfvars / variable defaults), then ~/.oci/config |
OCI region identifier |
region_label |
Auto-derived | Human-readable region name (55-entry table; a label is derived for unknown regions) |
home_region, subscribed_regions |
OCI CLI (oci iam region-subscription list) |
Tenancy's home region and subscriptions |
oci_profile, oci_auth |
Terraform provider block, ~/.oci/config |
CLI profile; security_token when session auth is configured |
compartment, compartment_ocid, compartments |
Terraform (oci_identity_compartment resources, compartment_ocid / compartment_id variables) |
Diagram scope — edit compartment by hand if needed |
vcns |
Terraform (oci_core_vcn resources or vcns = {...} tfvars maps) |
VCN names and CIDRs |
logo_light, logo_dark |
File scan (logos/, assets/logos/, assets/images/, docs/logos/, then the plugin-local logos/) |
*dark* / *black* files become logo_light (dark artwork for light backgrounds); *white* / *light* become logo_dark. Project paths are stored relative |
terraform_dir, terraform_dirs |
Directory walk (shallowest dir with a provider "oci" block, else with tfvars; .terraform, .git, node_modules pruned) |
Chosen directory plus any tied candidates |
Settings are stored in .claude/oci-drawio-architect.local.md (per-project; ignored via .claude/*.local.md in .gitignore). Edit the file directly to change values. Delete the file and re-run /drawio-architect to re-detect, or run the probe yourself:
python3 ~/.claude/plugins/marketplaces/local/plugins/oci-drawio-architect/scripts/detect_settings.py [--no-cli] [terraform_dir]The plugin also activates automatically when you mention in conversation:
- "draw.io OCI"
- "diagram this architecture"
- "drawio with OCI icons"
~/.claude/plugins/marketplaces/local/plugins/oci-drawio-architect/install.sh --uninstallThis removes the plugin files, its cache, its installed_plugins.json entry and its marketplace.json entry (other plugins are preserved); the local marketplace itself is removed only when nothing else lives in it.
Then inside Claude Code:
/plugin uninstall oci-drawio-architect@local
(and /plugin marketplace remove local if the installer reported the marketplace is now empty). Restart Claude Code.
Everything runs from the source tree; no install is needed.
# Unit tests (builder, settings-detection fixtures, icon-set integrity and alias map)
python3 -m unittest discover -s oci-drawio-architect/tests
# End-to-end smoke test: demo diagram -> overlap checker -> PNG (if draw.io desktop is present)
oci-drawio-architect/scripts/smoke_test.sh # SMOKE_SKIP_PNG=1 to skip the export
# Rebuild the reference sample from its model dict, then validate and render it
python3 oci-drawio-architect/examples/generate_reference_layout.py out.drawio --render
python3 oci-drawio-architect/scripts/check_overlaps.py --strict out.drawio # exit 0 clean, 1 errors, 2 unusable input
python3 oci-drawio-architect/scripts/render_drawio.py out.drawio -f png # exit 3 when draw.io desktop is missing (DRAWIO_BIN overrides)
# Terraform -> model JSON -> diagram with the shared recipe
python3 oci-drawio-architect/scripts/parse_terraform.py terraform/envs/prod --vcn app-vcn --out model.json # or --plan-json / --state-json
python3 oci-drawio-architect/scripts/oci_layout.py model.json -o out.drawio --profile default --legend --render png
# Regenerate / verify the icon catalog after touching icons/
python3 oci-drawio-architect/scripts/build_icon_catalog.py --check
# Regenerate the README screenshots from the reference example (needs draw.io desktop)
python3 oci-drawio-architect/examples/make_screenshots.py
# Package a release (version is read from .claude-plugin/plugin.json; prints size, entry count and SHA256)
oci-drawio-architect/pack.sh /path/to/outputExpect generated .drawio files to weigh roughly 7–13 KB per embedded icon (the six-page demo with 95 icons is about 910 KB; the reference sample with 27 icons and 4 badges about 280 KB). The reference sample itself is OCI_Architecture.drawio at the repository root.
The plugin code is MIT-licensed (see LICENSE). The SVG files under oci-drawio-architect/icons/ are Oracle Cloud Infrastructure architecture icons — Copyright (c) Oracle and/or its affiliates — sourced from the OCI Architecture Diagram Toolkit. They are not covered by the MIT license; they are bundled solely so the plugin can embed them when documenting OCI architectures. See oci-drawio-architect/icons/NOTICE for the attribution and refer to Oracle's page for the applicable terms before using the icons for any other purpose.
| Problem | Fix |
|---|---|
/drawio-architect not found |
Restart Claude Code after plugin install |
Pillow is required for PNG/JPEG logos |
python3 -m pip install --user Pillow (add --break-system-packages on PEP 668 Pythons, or use a venv). Only PNG/JPEG logos need it; use an SVG logo to avoid the dependency |
OCI icon directory not found / Icon SVG not found |
The builder searches $OCI_SVG_DIR, the plugin's icons/, $CLAUDE_PLUGIN_ROOT/icons and ~/.claude/plugins/.... Export OCI_SVG_DIR=/path/to/oci-drawio-architect/icons or call set_icon_dir() |
| Unknown icon key | The error lists close matches; every SVG is usable by its file stem (compute_virtual_machine_vm) or alias (vm) — see references/icon-catalog.md |
check_overlaps.py exits 1 |
Read the ERROR: / OVERLAP: lines: fix the container sizes (fit_to_children()), the parent ids, or the layout math, regenerate and re-run |
render_drawio.py exits 3 |
draw.io desktop not found on PATH, /Applications, /opt or snap — install it or set DRAWIO_BIN=/path/to/drawio |
| Settings not detected | Ensure a provider "oci" {} block exists in your Terraform directory (or pass the directory to detect_settings.py) |
| Want to re-detect settings | Delete .claude/oci-drawio-architect.local.md and re-run |
| Tenancy name missing | Install and configure OCI CLI (brew install oci-cli); --no-cli skips the queries entirely |
| Fonts look wrong in draw.io | Close and reopen the file (draw.io caches renders); labels use the Oracle Sans,Arial,Helvetica,sans-serif stack |

