Diagrams
Your architecture diagram belongs in the repository
TALA went open source last week, so we are using the occasion to explain why every diagram we hand a client is a text file under version control, and why the ones that are not are always out of date.
On 7 September the Terrastruct team open-sourced TALA,
the layout engine for D2. It was the one paid piece of an
otherwise free tool; it is now MPL-2.0, the same licence as D2 itself, bundled
in D2 v0.9.0 and selected with --layout=tala. The discussion on Hacker
News ran to a few hundred
points, mostly people who had wanted exactly this.
We have used D2 internally for about two years. Our reasons have less to do with diagrams than with the argument we already make about firewalls and servers.
Diagrams drift
Every estate we inherit has an architecture diagram. It is a PNG in a wiki, or
a .drawio file somebody exported once, or a Visio document that only opens on
one person’s laptop. It is always wrong, and it is wrong in a specific way: it
describes the system as it was on the day somebody had time to draw it.
Nobody updates it, because updating it means opening a drawing program, finding the right box, moving the arrows so they do not overlap, exporting, and uploading: fifteen minutes of fiddling for a change that took one line of configuration, so nobody does it.
A diagram that is a text file fails differently. It goes stale in the same
commit that changes the system, where a reviewer can see it, so either
nixos-rebuild and the diagram move together or the difference shows up in the
pull request.
What it looks like
Here is a typical example of what we draw: a client’s laptop reaching a host over WireGuard, and that host shipping backups to a second country:
direction: right
goteborg: Göteborg {
laptop: ThinkPad
}
sto: you.sto — Stockholm {
nginx
redmine: Redmine
pg: PostgreSQL {shape: cylinder}
nginx -> redmine -> pg
}
cra: craiova.cra — Romania {
backup: Backup target {shape: cylinder}
}
goteborg.laptop -> sto.nginx: wg0
sto.pg -> cra.backup: nightly, encrypted
That is the entire source. It produces this:
Nineteen lines, and D2 handles the layout. Add a second host and the arrows rearrange themselves.
Two more examples
A migration, before and beside after. This is the diagram that does the most work in a proposal, because the left side is what the client is paying for now:
before: Before — eu-west-1 {
alb: Application Load Balancer
ecs: ECS tasks
rds: RDS Postgres {shape: cylinder}
s3: S3 {shape: cylinder}
alb -> ecs -> rds
ecs -> s3
}
after: After — Falkenstein + Stockholm {
pf: pf
nixos: NixOS host
pg: PostgreSQL {shape: cylinder}
minio: MinIO {shape: cylinder}
pf -> nixos -> pg
nixos -> minio
}
before -> after: one service a week, rehearsed rollback
An estate, with the evidence attached. NIS2 Article 21(2)(a) wants risk analysis and security policies written down. An assessor does not want a picture; they want to know the picture is generated from the same repository as the thing it describes:
net: Perimeter {
pf: pf ruleset
wg: WireGuard mesh
}
hosts: Hosts declared in one repository {
a: you.sto
b: kalmar.sto
c: craiova.cra
}
net.pf -> hosts.a
net.pf -> hosts.b
net.wg -> hosts.c: site-to-site
hosts -> audit: nixos-rebuild --target-host
audit: "Every change is a commit" {shape: document}
All three compile. We checked them against d2 before publishing, as we would
with any example we put on the internet.
Where it is weaker
The announcement is unusually open about TALA’s limits, and we would rather repeat them than bury them. It uses randomness, so a small change to the source can produce a noticeably different layout. It handles directed acyclic graphs worse than Dagre or ELK, and most infrastructure diagrams are exactly that. It also scales nonlinearly, so a large diagram gets slow.
That matches our experience. We reach for --layout=elk for anything that is
mostly a flow, and TALA for the messier network pictures where its freedom to
move things around helps. Switching is one flag.
The broader caution is that automatic layout does not rescue a diagram that is trying to show too much. If your picture has sixty nodes, the problem is the picture: D2 will lay out sixty nodes tidily, and nobody will read them.
When we would not use it
If a diagram is drawn once for a pitch and thrown away, use whatever is fastest; version control does not help something that will never have a second version. If your team collaborates on diagrams visually, in real time, a canvas tool is a better fit and we would say so.
If the diagram is not generated from, or reviewed alongside, the thing it describes, it does not matter which tool drew it: it will be wrong within a quarter. That was true before last week’s licence change too.