Terraform-Architekturdiagramm: von .tf-Dateien zu einem Bild, das Menschen lesen können

Terraform beschreibt deine Infrastruktur bereits, aber weder der Code noch terraform graph ist ein Architekturdiagramm. Was ein lesbares braucht und was wegkann.

· Gründer & Entwickler

Veröffentlicht am

Terraform-Architekturdiagramm: von .tf-Dateien zu einem Bild, das Menschen lesen können

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

Nutzer erreichen per HTTPS einen Load Balancer in den öffentlichen Subnetzen einer VPC. Er leitet an einen ECS-Service in privaten Subnetzen weiter, der PostgreSQL und einen S3-Bucket nutzt. Ein DNS-Alias zeigt auf den Load Balancer; eine Notiz nennt die Terraform-Ressourcen der Karten.

10 Komponenten · 5 Verbindungen

In Archboard öffnen
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
Eine in Terraform definierte Web-App, für Menschen gezeichnet: Nutzer erreichen einen Application Load Balancer in öffentlichen Subnetzen, ein ECS-Service und eine Multi-AZ-PostgreSQL-Datenbank liegen in privaten Subnetzen, eine Notiz ordnet jede Karte ihren Ressourcenadressen zu.

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

  1. Melde dich mit Google oder GitHub an und leg ein Diagramm an.
  2. 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.
  3. 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.
  4. 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.
  5. 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.

Kostenlos starten — ein Seat, keine Kreditkarte.

Ähnliche Beiträge

← Zurück zum Blog

In einer Minute ein Canvas öffnen

Melden Sie sich mit Google oder GitHub an. Kostenlos für einen Sitzplatz. Upgraden Sie, wenn das Team dazukommt.