← All posts

How do you turn Terraform into an AWS architecture diagram with Mermaid?

Terraform provisions AWS but gives you no readable architecture diagram — terraform graph only emits a low-level dependency graph. Here is how to turn your Terraform, or its plan JSON, into a validated Mermaid architecture-beta diagram: the diagramming options compared, an LLM grounding workflow, and a worked multi-tier example checked at zero rule violations in LatixEngine.

Quick answer

Terraform provisions AWS infrastructure but produces no readable architecture diagram — terraform graph only emits a low-level dependency graph. To get a clean picture, feed your Terraform, or its plan JSON, to an LLM, generate Mermaid architecture-beta source, then validate it in LatixEngine to fix hallucinated icons and placement before it ships.

Terraform is the source of truth for what your AWS infrastructure is, but it is a poor source of truth for what your infrastructure looks like. HCL describes resources one block at a time — a aws_lb here, three aws_subnet blocks there, a security group two files away — and nowhere in that does a human get to see the shape of the system. The moment someone asks "can you show me how this fits together?", you are stuck: the answer lives in your head, scattered across .tf files, or in a diagram that went stale three sprints ago.

The obvious first move is terraform graph, and it disappoints almost everyone who tries it. This post covers why the built-in option and its ecosystem fall short for communication, the full menu of ways to diagram a Terraform project, and a concrete workflow that turns your Terraform into a Mermaid architecture-beta diagram you can validate, version, and trust. If you have used Terraform's cousin CloudFormation, the same approach applies — see Mermaid vs AWS Application Composer for the CloudFormation-specific path.

The short version.

Terraform tells the cloud what to build; it does not draw you an architecture. terraform graph gives a low-level dependency graph, not a picture. The dependable route to a clean, current diagram is to convert your Terraform (ideally the terraform show -json plan output) into Mermaid architecture-beta, then validate it in LatixEngine so hallucinated icons and misplaced resources are caught before the diagram ships.

Why doesn't terraform graph give you a usable architecture diagram?

terraform graph does exactly what its documentation promises: it emits the dependency graph Terraform builds internally, in Graphviz DOT format, which you render by piping it to dot. That graph is genuinely useful for what it is designed for — debugging the order of operations, spotting dependency cycles, and understanding why Terraform plans to replace a resource. It is not designed to explain a system to a person.

Three problems make it the wrong tool for communication. First, it is resource-level: every aws_route_table_association, aws_iam_role_policy_attachment, and provider node shows up as its own box, so a modest stack becomes a wall of nodes long before it becomes a diagram anyone wants to read. Second, it has no cloud vocabulary — there are no service icons, no notion of a VPC containing subnets, no visual grouping by account or region; it is a plumbing diagram, not an architecture. Third, it reflects dependencies, not topology: the edges mean "Terraform must create A before B", which is often unrelated to how traffic actually flows between components.

The ecosystem tries to fill the gap. Tools like Inframap, Rover, and Blast Radius consume your state or plan and produce cleaner, sometimes interactive graphs. They are a real improvement, but they inherit the same fundamental framing: the output is a graph derived from resources, not a hand-composable architecture picture that lives in your repository as reviewable text.

What are your options for diagramming a Terraform project?

There is no shortage of ways to draw AWS infrastructure; they differ in how much manual effort they need, whether the result stays truthful over time, and whether it lives in your codebase. Here is the honest comparison.

ApproachWhat you getWhere it shinesThe catch
terraform graphA Graphviz DOT dependency graphDebugging apply order and cyclesResource-level, no icons, unreadable past a few dozen resources
Inframap / Rover / Blast RadiusAuto-generated graphs from state or planA quick visual with no redrawingStill graph-shaped; extra tooling to run and keep working
Cloudcraft / BrainboardPolished cloud diagrams, optional live scanStakeholder-ready visualsPaid tiers; live scans need account credentials; drifts from the repo
draw.io / LucidchartAny picture you can drawFull manual controlManual, drifts from reality, no validation
Mermaid + LatixEngineText architecture-beta diagram, validatedDocs-as-code that versions in git and gets reviewedLLM-assisted, not auto-derived from state; a documentation layer

The right choice depends on the deliverable. If you need a one-off isometric picture for a slide, a scanning tool like Cloudcraft is hard to beat. If you need a diagram that ships with the code, survives refactors, covers more than one cloud, and can be checked for correctness, a text format wins — and that is the case the rest of this post walks through.

How do you turn Terraform into a Mermaid AWS diagram?

The workflow has four steps, and the fourth is the one that turns a plausible-looking diagram into a correct one.

  • Start by collecting a grounding input. You can paste key .tf files, but the far better input is the plan JSON: run terraform plan -out plan.tfplan, then terraform show -json plan.tfplan. That JSON enumerates every resource and its resolved attributes, which stops the model from guessing at what you actually deploy.
  • Next, prompt an LLM to produce Mermaid architecture-beta source, and ground it with the real icon slugs. ChatGPT, Claude, and Gemini all write this syntax on request, and all three hallucinate AWS icon names — so give them the correct ones up front. The exact pattern, including the slugs models get wrong most often, is in how to prompt LLMs for Mermaid AWS diagrams.
  • Then validate the output in the LatixEngine editor. Paste the generated Mermaid and it checks every slug against the icon catalog and runs the diagram through AWS placement rules — public databases, single-AZ deployments, an API Gateway wired straight to a relational database, and more. This is where hallucinated icons and quietly wrong topology get caught. The full catalogue of what it flags is in common AWS architecture mistakes.
  • Finally, commit the .mmd text next to the Terraform module it describes and render it wherever you publish. Because it is plain text, it diffs in the same pull request as the infrastructure change; for platform-by-platform rendering see rendering and embedding Mermaid AWS diagrams.

The reason this beats asking an LLM to "draw my Terraform" in one shot is the validation gate. A model will happily emit aws:ec2 or aws:rds-instance — slugs that do not exist — and place a database in a public subnet without comment. Grounding reduces those errors; validation removes them.

What does a Terraform stack look like as a Mermaid diagram?

Take a common Terraform module: a VPC with public and private subnets, an internet gateway, a NAT gateway for private egress, an Application Load Balancer in front of an ECS service, an RDS PostgreSQL instance the service talks to, and an S3 bucket for static assets. In HCL that is dozens of resource blocks across several files. As a Mermaid architecture-beta diagram, validated at zero rule violations, it is this:

architecture-beta
service users(aws:res-users-light)[Users]
group aws_account(aws:aws-account)[AWS Account]
group region(aws:region)[us-east-1] in aws_account
service s3(aws:arch-amazon-simple-storage-service)[Static Assets S3] in region
group vpc(aws:virtual-private-cloud-vpc)[VPC 10.0.0.0/16] in region
service igw(aws:res-amazon-vpc-internet-gateway)[Internet Gateway] in vpc
group pub(aws:public-subnet)[Public Subnet] in vpc
service alb(aws:res-elastic-load-balancing-application-load-balancer)[Application Load Balancer] in pub
service nat(aws:res-amazon-vpc-nat-gateway)[NAT Gateway] in pub
group priv(aws:private-subnet)[Private Subnet] in vpc
service ecs(aws:arch-amazon-elastic-container-service)[ECS Service] in priv
service rds(aws:arch-amazon-rds)[RDS PostgreSQL] in priv
users:R --> L:igw
igw:B --> T:alb
alb:B --> T:ecs
ecs:R --> L:rds
ecs:L --> R:nat
ecs:B --> T:s3
nat:T --> R:igw

Two things are worth noticing. The grouping carries meaning that terraform graph throws away: the region contains the VPC, the VPC contains the subnets, and the RDS instance sits inside the private subnet where it belongs. And the validation is doing real work — if the LLM had placed rds in the public subnet, or emitted a slug like aws:rds that is not in the catalog, LatixEngine would have flagged it rather than rendering a confident, wrong picture. For a library of ready-made starting points in this same style, see the AWS architecture patterns gallery, and for the grammar behind the ports and in keyword, the architecture-beta syntax reference.

How do you keep the diagram in sync with your Terraform?

A diagram is only worth trusting if it tracks reality, and the failure mode of every hand-drawn diagram is drift. The trick is to treat the Mermaid file as documentation-as-code with the same discipline you apply to the Terraform itself.

  • Store the .mmd beside the module — in the same directory as the .tf files it describes — so the diagram and the infrastructure move together.
  • Regenerate from the plan JSON when the topology changes materially. You do not redraw for a tag change; you do redraw when a subnet, a managed service, or a traffic path appears or disappears.
  • Re-validate every time in LatixEngine, so a change that introduces an anti-pattern — say, exposing the database or collapsing to a single AZ — is caught in the same review as the Terraform change that caused it.
  • Review the diagram diff in the pull request. Because the source is text, a reviewer sees exactly which nodes and edges changed, right next to the infrastructure change, instead of squinting at two exported images.

This does not make the diagram auto-update from state, and that is a deliberate boundary. A diagram that silently mutates is a diagram no one has reviewed. Regenerate-and-validate keeps a human in the loop while keeping the effort to minutes.

Does this replace terraform graph, Terragrunt, or your state file?

No — and it is worth being precise about the boundary, because these tools answer different questions. Your Terraform state remains the single source of truth for what exists; Terraform and Terragrunt remain how you plan and apply changes; terraform graph remains the right tool when you need to debug dependency ordering. None of that is what a documentation diagram is for.

The Mermaid diagram is the communication layer that sits on top. Its job is to let a new engineer, a security reviewer, or a stakeholder understand the system in thirty seconds, and to make a change to the system visible in review. It complements the state file the way a README complements the code: neither replaces the other, and a project is healthier with both. LatixEngine is free, runs entirely in the browser with no login or install, and validates against AWS, Azure, and GCP rules — so the picture you commit next to your Terraform is one you can actually rely on.

Frequently asked questions

Can you generate an AWS architecture diagram from Terraform automatically?

Not into a clean, presentation-ready architecture diagram. Terraform's built-in terraform graph emits a Graphviz dependency graph of resources and providers, and third-party tools like Inframap, Rover, and Blast Radius auto-derive graphs from your state or plan. All of them are resource-level and graph-shaped. For an architecture picture with real cloud icons that lives in your repo, the reliable path is to convert the Terraform into Mermaid architecture-beta and validate it.

What does terraform graph actually produce?

terraform graph outputs a description of the dependency graph between your resources, data sources, and providers in the Graphviz DOT format, which you pipe to dot to render an image. It is built for debugging apply ordering and dependency cycles, not for communicating architecture — it shows every resource node and edge, has no cloud service icons, and becomes unreadable past a few dozen resources.

How do you visualize a Terraform plan as a diagram?

Run terraform plan -out plan.tfplan, then terraform show -json plan.tfplan to get machine-readable JSON of every resource and its attributes. That JSON is the best grounding input for an LLM: hand it over with the real Mermaid icon slugs, ask for architecture-beta source, and validate the result in LatixEngine before committing it.

Is Mermaid better than Cloudcraft or diagrams.net for Terraform diagrams?

It depends on the goal. Cloudcraft produces polished isometric visuals and can live-scan an account, and diagrams.net gives you full manual control. Mermaid's advantage is that the diagram is plain text that versions in git, diffs in a pull request, renders with no login or install, and can be validated against AWS rules — so it stays truthful next to the Terraform it describes.

Can an LLM read my Terraform and produce a correct diagram?

An LLM can read HCL or plan JSON and produce Mermaid architecture-beta source that is structurally close, but it reliably hallucinates AWS icon slugs and sometimes misplaces resources. That is exactly what the validation step catches: LatixEngine flags invalid slugs against the icon catalog and checks placement against AWS rules, so the errors surface before the diagram reaches your docs.

Does the Mermaid diagram stay in sync with my Terraform automatically?

No — it is a documentation layer, not a live view of state. When the Terraform changes materially, regenerate the diagram from the new plan JSON and re-validate it. Because the diagram is text committed beside the module, the change shows up in the same pull request as the infrastructure change, which is where reviewers can see it.

Try it in the editor

Paste any example in this post into the LatixEngine editor to render it with native cloud icons and validate it against AWS, Azure, and GCP best practices. No login, no install.

Open the editor →