Keeping the architecture diagram true to what is deployed
A C4 container diagram generated from Terraform state and a live cluster.
Generates a C4-style container diagram from two sources of truth that already exist, Terraform state and live Kubernetes resources, resolving ingress edges through each Service's label selector and datastore edges from environment variables. One file, standard library only, safe to drop into any CI job, and regenerated on every merge the diagram's diff becomes the architecture-change review.
The problem
Most organisations have an architecture diagram; few have a current one.
The lifecycle is consistent enough to be a genre. Someone draws the system during a design phase, in a tool with a licence. It is accurate on the day it is exported. Then a service is added, a queue is introduced, a database is split, an ingress is renamed — and each of those changes is made by someone who has never opened the diagram file and would not have edit access if they tried.
Six months later the diagram shows a system that does not exist, and the time it costs most is during an incident. The on-call engineer opens it to find what sits behind the failing ingress, and it points at a service that was merged in the spring and leaves out the queue that is backing up. A whiteboard photo would be treated with suspicion; a diagram in the wiki is trusted, because it looks finished.
The second, subtler problem is that architectural change is invisible in code review. A pull request that adds an SQS queue and a consumer is, in the diff, a few dozen lines of HCL among several hundred. The reviewer sees resource blocks. Nobody sees "we now have an asynchronous path into the payment service", which is the change a senior reviewer would have an opinion about, and the kind a diagram shows at a glance.
The method
Two inputs, both already authoritative. Terraform state describes the infrastructure that was provisioned; live Kubernetes resources describe what is running. Neither requires anyone to maintain a separate model, because both are maintained already for other reasons. Either can be used alone — --tfstate infra.tfstate produces the infrastructure half without a cluster, which is the right mode for a repository that provisions but does not run workloads.
Read both shapes of Terraform state. The tool reads terraform show -json output and a classic flat state file, and works out which it was given. A TF_KINDS table maps resource types to a node kind and a label prefix, so classification is a lookup. The cost is coverage: a resource type the table does not list is left out of the diagram, not guessed at.
Wire the edges you can prove from selectors. Ingress-to-service edges come from the Ingress backend's Service name and that Service's label selector, the mechanism Kubernetes routes on, so they hold even where a service's name follows no convention.
Name the heuristic, and run it in two passes. Service-to-datastore edges are guessed from a workload's environment values in two passes: one for DSN-style values (a datastore host inside a URL), then one for whole-token name matches. Each pass is its own function, so a wrong edge can be traced to one rule and the rule argued with.
Render three formats from one model, sharing the grouping code. --format mermaid|plantuml|d2 picks the renderer (Mermaid by default), and all three group nodes with the same helper, so the formats cannot drift into different orderings. Only Mermaid draws Terraform module subgraphs, because only Mermaid is read in a pull request.
No dependencies at all. dependencies = [] keeps installation to one file. Where every package added to a CI image goes through review, the review is of that file; in an air-gapped pipeline with no cluster to reach, the Terraform half still runs.
Commit the output and regenerate in CI. The design assumes the file is checked in and regenerated on every merge, which makes the tool a drift detector; the CI recipe is in use case 2.
The headline results
- Freshness is a property of the pipeline.
The full results, with the tables and the reasoning behind each figure, are in the PDF.
What is in the PDF
- The problem — what goes unanswered without it, and who notices first.
- Why the obvious alternative falls short — stated plainly, including where it is the better choice.
- How it works — the method, not a feature list.
- Concrete use cases — with console output quoted from the repository, never reconstructed.
- The methodology behind any number it emits — every term shown, so the figure survives a question.
- What it deliberately does not do — the section most papers leave out.
Part of the Platform & SRE theme.
Get the PDF
This paper already selected; the download starts when you send the form. No follow-up sequence.