DEV Community

Cover image for Nobody keeps the AWS network diagram current. I built a tool for it
Karina Pérez
Karina Pérez

Posted on Originally published at vpcatlas.com

Nobody keeps the AWS network diagram current. I built a tool for it

VPC Atlas reads an AWS account with read-only calls and draws its network in draw.io and Lucidchart. Alpha, MIT licensed.

Every team I joined asked for the same thing first: the network diagram. The one that shows every VPC, how the VPCs connect through Transit Gateways, peerings, VPNs and Direct Connect, and what sits at the edge in front of them. And every time, the diagram that existed was out of date.

Drawn by hand, or rebuilt from the console

A network diagram drawn by hand is wrong a week later. Someone adds an attachment, someone shares a Transit Gateway through AWS RAM, a peering with another account appears, and the picture stays as it was.

The alternative is to rebuild it from the console: open each VPC, read the route tables, follow the attachments, check the endpoints, then draw it. On a real account that takes days. I wanted to point a tool at the account, get the diagram in minutes, and do it again next week to compare.

What VPC Atlas does

vpcatlas connects to an AWS account with auditor permissions and maps its network: VPCs, subnets, routing, gateways, endpoints, load balancers, firewalls, the DNS resolver and whatever is shared through RAM, plus what sits in front of them: Route 53, CloudFront, WAF, ACM and Shield. It also reads compute and data stores such as RDS, S3 and DynamoDB, so a subnet shows what runs in it, and account services such as CloudTrail, GuardDuty and KMS for the inventory.

It is read-only by design. It calls Describe*, Get*, List* and Search* APIs and never creates, changes or deletes anything. It ships the minimal policy it needs, so you can read what it asks for before you grant it.

One run gives you three things. The diagrams: a Global page, one page per Region and one page per VPC, as .drawio and .lucid files, drawn with the AWS Architecture Icons and laid out like the AWS Managed Services multi-account landing zone network reference. An inventory in JSON, Markdown and HTML, with every resource account by account and a section for every external account linked to yours. And a dashboard: vpcatlas serve shows the same diagrams in the browser, keeps a history of scans and draws the difference between two of them, what was added in green and what changed in orange. The raw result is saved too, as vpcatlas-graph.json, so you can redraw later without calling AWS again.

Recording of vpcatlas discover running against a simulated AWS account, then listing the generated diagram files

The recordings and diagrams here come from a simulated AWS account, so the ids are examples. This is the dashboard on that account:

The vpcatlas dashboard showing the live diagrams, run history and downloads

And a Region page:

The eu-west-1 region diagram in draw.io: VPCs, Transit Gateway, endpoints and gateways

How it works

A read-only pipeline with four stages: collect, graph, layout, export. Each stage takes one input and gives one output, which is what makes it easy to test.

Collectors read the account, one per service, all paginated. Regions run in parallel, but inside a Region the collectors run one after another to keep API throttling low, and a call that fails with AccessDenied is logged and skipped, without ever stopping the run. The results become a networkx directed graph wrapped by Pydantic models, with typed edges (contains, routes_to, attached_to, peered_with, shared_from) and external accounts as nodes of their own. Positions are computed once, as a deterministic grid: cloud, Region, VPC, availability zone, subnet. Both diagram exporters draw from that one layout, so the same input gives the same drawing, nothing moves between two runs unless the network moved, and a diff means something. The exporters write mxGraph XML with the mxgraph.aws4 shapes for draw.io, a Lucid Standard Import package for Lucid, and the inventory in JSON, Markdown and HTML.

The decisions that took time

Numbered flows. Every arrow is the same grey, and numbered circles tell the kinds of traffic apart. A kind of traffic keeps its number on every page: 1 Internet ingress, 2 NAT egress, 3 Transit Gateway attachment, 4 Direct Connect or VPN, 5 VPC peering, 6 shared prefix list or RAM. A legend lists the ones a page uses. The numbers come from the kind of each edge, not from observed traffic, and the documentation says so.

The Global page. The whole network on one page: accounts, the Transit Gateway hub, peerings, Direct Connect gateways. Anything referenced but not owned by an audited account goes in a dashed box of its own, one per external account.

Gaps, not zeros. A denied call becomes a recorded gap. Where a count would have been, the page says not read. It never writes 0, because a zero looks like an answer.

Crowded pages. The layout is where most of my time went. A Region page with 77 API Gateways took 97 seconds in --detail full; drawing the fans of edges as a bus, one trunk with a branch per icon, brought it to under a second. --detail simple folds more than three resources of one kind into one card, such as API Gateway ×77, and on the same page it went from 37 seconds to under a second, and from 17,700 to 2,660 pixels wide.

The diagram of the prod VPC in draw.io, with subnets, route tables and numbered flows

One VPC page: subnets, routing and numbered flows.

Try it in a sandbox account

You need Python 3.12 or newer and an AWS account you may read.

pipx install vpcatlas
vpcatlas iam-policy > auditor-policy.json   # attach this to the role or user you will use
vpcatlas discover --profile audit --output-dir ./out
vpcatlas serve --cache ./out/vpcatlas-graph.json
Enter fullscreen mode Exit fullscreen mode

For a quick run in a sandbox, the AWS managed ReadOnlyAccess also works, but it reads far more than the tool needs; don't leave it on a role you keep. Credentials work the way the AWS CLI's do: a profile, environment variables, SSO, or an assumed role with an external ID and MFA.

You get the graph, the inventory and a diagrams/ folder. Open any .drawio file in diagrams.net, or import a .lucid file with Lucid Standard Import. Start with vpcatlas-global.drawio. The dashboard opens on http://127.0.0.1:8080 over the scan you just made, without calling AWS again.

There is a binary installer with no Python needed (curl -fsSL https://vpcatlas.com/install.sh | sh, or a PowerShell one-liner on Windows) and a Docker image, which serves the dashboard by default:

docker run --rm -p 127.0.0.1:8080:8080 -v "$HOME/.aws:/home/atlas/.aws:ro" \
  vpcatlas/vpcatlas serve --host 0.0.0.0 --profile audit
Enter fullscreen mode Exit fullscreen mode

The dashboard shows your network topology, so keep it on a private network, or set VPCATLAS_AUTH_PASSWORD and serve it over HTTPS.

What it does not do yet

This is an alpha, and the limits are in the documentation.

  • Accounts are listed by hand. Repeat --profile or --role-arn to merge several accounts into one graph. There is no discovery of the accounts of an AWS Organization yet: you list them.
  • A snapshot. The files describe the network at the moment of the scan.
  • No traffic analysis. No flow logs, reachability analysis or route simulation.
  • No contents. No S3 objects, secrets or log events, and no rule or policy bodies.
  • Services without a collector. Global Accelerator, VPC Lattice, IPAM, Network Manager and Cloud WAN, Client VPN and a few more.
  • AWS only, and a regenerated file replaces your edits, so keep edited copies under another name.

Planned for v2: Network Manager and Cloud WAN topologies, Direct Connect and VPN path tracing, drift between two snapshots, diagram diffs in pull requests, and multi-account runs from an AWS Organizations list.

How it is built and released

I wanted to be able to ask of this tool what I ask of any other: where did the binary come from?

Every change goes through lint, type checks, tests on Linux, macOS and Windows, both Docker images with smoke tests and a scan, and the installers on three systems. CodeQL, OpenSSF Scorecard and Dependabot run weekly, pip-audit nightly. The full list, and the reason for each check, is in the CI/CD post.

A release produces binaries for up to five platforms, SHA256SUMS, an SBOM, and signed and attested images, and a last job installs the published release with the live installers. The package is on PyPI and the image on Docker Hub, for linux/amd64 and linux/arm64. To check a download:

gh attestation verify vpcatlas-X.Y.Z-linux-x86_64.tar.gz --owner karina-pp
Enter fullscreen mode Exit fullscreen mode

Image signatures and SBOMs start with 0.4.1, and verifying an image signature needs cosign 3 or newer.

Built with AI, runs without it

AI helped me write this tool, and I'd rather say so than pretend otherwise. The tool itself needs none of it: no model, no API key, no account with anyone, no bill per token, and nothing leaves your network except the AWS API calls you authorised. Some teams can't use AI tools at work, or won't pay for them. They still need the diagram, so the tool doesn't depend on one.

Where to get it

It's MIT licensed. The most useful thing you can do is run it on a sandbox account and tell me where the drawing is wrong or the reading comes up short.

Top comments (0)