Terraform beschreibt deine Infrastruktur bereits, präzise und versioniert. Warum versteht dann niemand das System aus dem Code? Weil eine .tf-Datei beantwortet, „was es gibt und wie es konfiguriert ist“, während Leute, die ein Architekturdiagramm lesen, etwas anderes fragen: Wo kommt der Traffic herein, was spricht mit was, wo liegen die Daten und was ist von außen erreichbar?
Dieser Guide zeigt, wie du von Terraform zu einem Diagramm kommst, das Menschen lesen können: warum terraform graph nicht dieses Diagramm ist, wie du Ressourcen auf Rahmen und Karten abbildest, wann sich Plan-JSON lohnt, was du weglässt und wie du das Ergebnis in Pull-Request-Reviews nutzt.
Warum weder der Code noch terraform graph das Diagramm ist
Ein kleiner Produktions-Stack kommt leicht auf hundert Ressourcen, verteilt auf mehrere Dateien und Module, und viele davon sind Klebstoff: IAM-Policy-Attachments, Routing-Tabellen-Zuordnungen, Regeln von Sicherheitsgruppen, Target-Group-Attachments. Die Antwort auf „Kann das Internet die Datenbank erreichen?“ steckt darin, verteilt auf ein Dutzend Referenzen.
terraform graph ändert das nicht. Es gibt einen Graphen in der Sprache DOT aus, und seit Terraform 1.7 ist die Standardausgabe ein vereinfachter Graph, der laut Befehlsreferenz nur die Abhängigkeitsreihenfolge der Ressourcen beschreibt. Optionen wie -type=plan zeigen eine Annäherung an den vollständigeren Graphen, mit dem Terraform einen Plan erstellt, und seit Terraform 1.16 gibt -format=mermaid Mermaid statt DOT aus.
Ein Abhängigkeitsgraph beantwortet, „was vor was existieren muss“. Der ECS-Service hängt von einer IAM-Rolle, einer Target Group und einer Task-Definition ab, also zeigen die Pfeile vom Service zu seinen Voraussetzungen. Das ist oft die Gegenrichtung des Traffics, und die Klebstoff-Ressourcen nehmen so viel Platz ein wie die Datenbank. Zum Debuggen eines Plans ist das nützlich. Ein Architekturdiagramm ist es nicht.
Der Beispiel-Stack
Eine typische Web-App auf AWS: eine VPC mit öffentlichen und privaten Subnetzen in zwei Availability Zones, ein Application Load Balancer, ein ECS-Service auf Fargate, eine PostgreSQL-Datenbank auf RDS und ein S3-Bucket für Uploads. Ein Auszug aus der Konfiguration:
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "private_a" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.11.0/24"
availability_zone = "eu-west-1a"
}
resource "aws_lb" "web" {
name = "web"
load_balancer_type = "application"
subnets = [aws_subnet.public_a.id, aws_subnet.public_b.id]
security_groups = [aws_security_group.alb.id]
}
resource "aws_ecs_service" "app" {
name = "app"
cluster = aws_ecs_cluster.main.id
task_definition = aws_ecs_task_definition.app.arn
launch_type = "FARGATE"
desired_count = 2
network_configuration {
subnets = [aws_subnet.private_a.id, aws_subnet.private_b.id]
security_groups = [aws_security_group.app.id]
}
load_balancer {
target_group_arn = aws_lb_target_group.app.arn
container_name = "app"
container_port = 8080
}
}
resource "aws_db_instance" "main" {
identifier = "app-db"
engine = "postgres"
instance_class = "db.t4g.medium"
allocated_storage = 50
username = "app"
manage_master_user_password = true
multi_az = true
db_subnet_group_name = aws_db_subnet_group.main.name
vpc_security_group_ids = [aws_security_group.db.id]
}
Terraform auf ein Diagramm abbilden
Die meiste Arbeit besteht darin zu entscheiden, welche Ressourcen zu Elementen im Diagramm werden und welche zu Details anderer Elemente:
| In Terraform | Im Diagramm |
|---|---|
aws_vpc, aws_subnet und Referenzen über vpc_id / subnet_id |
Rahmen: die VPC um öffentliche und private Subnetze |
aws_lb mit Listener und Target Group |
Eine Load-Balancer-Karte; der Listener-Port steht an der Kante |
aws_ecs_service mit Cluster und Task-Definition |
Eine Compute-Karte mit der gewünschten Anzahl |
aws_db_instance mit seiner Subnetzgruppe |
Eine Datenbank-Karte in den privaten Subnetzen, mit Vermerk Multi-AZ |
aws_s3_bucket mit Versionierung und Zugriffssperre |
Eine Objektspeicher-Karte |
| Regeln von Sicherheitsgruppen | Ports und Protokolle an den Kanten |
| Referenzen zwischen Ressourcen | Verbindungen, gezeichnet in Richtung des Traffics |
depends_on |
Eine gestrichelte Linie, wenn sie etwas sagt, das Leser brauchen |
IAM-Rollen, -Policies, -Attachments; random_*, time_*, null_resource |
Weggelassen oder eine kurze Notiz auf der Karte |
.tf-Dateien oder Plan-JSON
Du kannst direkt mit der Konfiguration arbeiten oder mit einem Plan:
terraform plan -out plan.out
terraform show -json plan.out > plan.json
Die .tf-Dateien sind schnell und brauchen keinen Lauf, aber count und for_each sind nicht aufgelöst, Variablen sind unbekannt und Remote-Module bleiben geschlossen. In Plan-JSON ist all das aufgelöst, und die Liste resource_changes sagt, was der Plan mit jeder Ressource tut: ["create"], ["update"], ["delete"] oder ["delete", "create"] für ein Ersetzen. Damit ist Plan-JSON die bessere Eingabe, um eine Änderung zu prüfen. Geh sorgfältig mit der Datei um: Die Dokumentation zu terraform show warnt, dass sensible Werte aus dem State in der JSON-Ausgabe im Klartext erscheinen.
Das Diagramm
Diagramminhalt
- Users
- app.example.com
- VPC
- Public subnets · 2 AZs
- Application LB
- Private subnets · 2 AZs
- ECS service ×2
- PostgreSQL, Multi-AZ
- Uploads bucket
- HTTPS 443
- alias record
- HTTP 8080
- PostgreSQL 5432
- HTTPS 443, uploads
So liest du es:
- Eingang. Nutzer erreichen den Application Load Balancer per HTTPS auf Port 443. Der DNS-Alias-Eintrag zeigt auf ihn.
- Netzwerkgrenzen. Die VPC enthält zwei Rahmen: öffentliche Subnetze für den Load Balancer und private Subnetze für alles andere. Nichts in den privaten Subnetzen ist aus dem Internet erreichbar.
- Der Pfad. Der Load Balancer leitet auf Port 8080 an den ECS-Service weiter. Der Service spricht auf Port 5432 mit PostgreSQL und schreibt Uploads per HTTPS nach S3.
- Die Notiz. Sie ordnet jede Karte den Ressourcenadressen dahinter zu und listet auf, was bewusst weggelassen wurde, damit Leser den Code finden.
Erst kürzen, dann ergänzen, was Terraform nicht weiß
Kürze konsequent. IAM-Klebstoff, Routing-Tabellen-Zuordnungen, Log-Gruppen und einzelne Ressourcen pro Sicherheitsgruppen-Regel gehören in den Code. Eine Karte pro deploybarer Einheit oder Datenablage ist für die meisten Leser die richtige Ebene.
Dann ergänze, was Terraform dir nicht sagen kann:
- Wer das System nutzt und wo der Traffic hereinkommt.
- Die Flussrichtung. Referenzen zeigen von einer Ressource zu dem, was sie braucht; der Traffic läuft oft andersherum.
- Ports und Protokolle aus den Regeln der Sicherheitsgruppen, an die Kanten geschrieben.
- Externe Dienste, die die App aufruft und die nicht in dieser Konfiguration verwaltet werden.
- Fakten, die im Incident zählen: Multi-AZ, Backups, die gewünschte Anzahl.
In Pull-Request-Reviews nutzen
Ein Diagramm, das aus dem Plan eines Pull Requests erzeugt wird, zeigt Reviewern die Form einer Änderung statt eines langen Diffs. Achte besonders auf ein paar Dinge:
- Ein neuer öffentlicher Einstiegspunkt, etwa ein Load Balancer, ein öffentliches Subnetz oder eine Sicherheitsgruppe, die für 0.0.0.0/0 offen ist.
- Das Ersetzen einer zustandsbehafteten Ressource.
["delete", "create"]an einer Datenbank oder einem Bucket verdient einen zweiten Reviewer. - Ressourcen, die zwischen Subnetzen wandern oder das private Netz verlassen.
- Neue Datenablagen, die einen Owner, Backups und einen Eintrag in deiner Datenlandkarte brauchen.
Halte das erzeugte Diagramm und das kuratierte Architekturdiagramm getrennt. Das erzeugte ist eine Review-Hilfe für eine Änderung; das kuratierte ist Dokumentation, die das System erklärt.
Aktuell halten
Behandle das kuratierte Diagramm wie Code: ein Owner, ein Link aus der README des Moduls und ein Update, sobald eine Änderung einen Einstiegspunkt, eine Datenablage oder eine Netzwerkgrenze hinzufügt. Architekturdiagramme, die nicht veralten beschreibt genau dafür einen Workflow. Für die Netzwerkseite desselben Stacks siehe den Guide zum AWS-VPC-Diagramm, und für den Betrieb in zwei Regionen das AWS-Multi-Region-Architekturdiagramm.
In Archboard nachbauen
- Melde dich mit Google oder GitHub an und leg ein Diagramm an.
- Für einen ersten Entwurf füge deine
.tf-Dateien oder dein Plan-JSON in das kostenlose Tool Terraform als Diagramm ein. Es macht aus VPCs und Subnetzen Rahmen, aus Ressourcen Karten und aus Referenzen Verbindungen, markiert geplante Änderungen aus Plan-JSON und faltet Klebstoff wie Target-Group-Attachments in Verbindungen. Wähle In Archboard öffnen, um weiterzuarbeiten. - Um von Hand zu zeichnen, füge einen VPC-Rahmen aus dem Netzwerk-Pack mit zwei Subnetz-Rahmen hinzu, einen Cloud-Lastverteiler aus dem Cloud-Pack in die öffentlichen Subnetze und eine Recheninstanz sowie eine Verwaltete Datenbank in die privaten Subnetze.
- Füge einen Objektspeicher-Node aus dem Cloud-Pack für den Bucket hinzu, einen Internet-Node aus dem Netzwerk-Pack für die Nutzer und einen DNS-Node für den Alias-Eintrag.
- Beschrifte die Kanten mit Ports und Protokollen und füge einen Markdown-Block aus dem Basis-Pack hinzu, der Karten den Ressourcenadressen zuordnet.
Das Beispiel nutzt 10 Diagramm-Nodes und bleibt damit im Free-Plan. Wenn dein Stack in CloudFormation definiert ist, erledigt das Tool CloudFormation als Diagramm dasselbe für Templates.
FAQ
Kann terraform graph ein Architekturdiagramm erzeugen? Es erzeugt einen Abhängigkeitsgraphen in DOT oder, seit Terraform 1.16, in Mermaid. Das hilft beim Debuggen von Plänen, zeigt aber die Aufbaureihenfolge statt des Traffics und enthält Klebstoff-Ressourcen. Bevor Menschen ihn als Architektur lesen können, muss er kuratiert werden.
Sollte ich aus .tf-Dateien oder aus Plan-JSON zeichnen?
Nimm .tf-Dateien für einen schnellen Blick auf ein Modul und Plan-JSON, um eine Änderung zu prüfen, weil im Plan Anzahlen, Module und geplante Aktionen aufgelöst sind.
Wie stelle ich Sicherheitsgruppen dar? Als Ports und Protokolle an den Kanten zwischen den Ressourcen, die sie schützen, nicht als eigene Boxen.
Was sollte ich weglassen?
IAM-Attachments, Routing-Tabellen-Zuordnungen, Hilfsressourcen wie random_id und alles, was nicht verändert, wie Leser Traffic, Daten oder Erreichbarkeit verstehen.
Wie halte ich das Diagramm mit dem Code synchron? Erzeuge einen Entwurf neu, wenn eine Änderung einen Einstiegspunkt, eine Datenablage oder eine Netzwerkgrenze hinzufügt, und aktualisiere das kuratierte Diagramm im selben Pull Request.