🏗️ Terraform Lektion 6/15 ~7 Min. Fortgeschritten

Remote State und Backends

S3, GCS, Terraform Cloud für Team-Arbeit.

📝 Meine Notizen

Lernziele

Nach dieser Lektion kannst du ein Remote-Backend einrichten und erklären, warum Teams keinen lokalen State nutzen. Du kennst S3 + DynamoDB als AWS-Standard, GCS-Locking und Terraform Cloud als Managed-Alternative. Du liest fremden State über terraform_remote_state und planst State-Verschlüsselung sowie Zugriffskontrolle.

Das Problem: State auf dem Laptop skaliert nicht

Lokaler State funktioniert für Solo-Experimente. Sobald zwei Platform Engineers am selben Stack arbeiten, bricht das Modell zusammen: Wer hat die aktuelle terraform.tfstate? Per Slack geschickt? Was passiert, wenn beide gleichzeitig apply ausführen? Und wo liegt das Backup, wenn der Laptop gestohlen wird?

Remote State löst drei Probleme auf einmal: zentraler Speicherort, echtes Locking und Zugriffskontrolle über Cloud-IAM statt Dateirechte auf einem MacBook.

Backends: wo der State lebt

Das Backend konfigurierst du im terraform-Block:

terraform {
  backend "s3" {
    bucket         = "company-tf-state"
    key            = "platform/network/terraform.tfstate"
    region         = "eu-central-1"
    dynamodb_table = "terraform-locks"
    encrypt        = true
  }
}

Wichtig: Backend-Konfiguration kann keine Variablen nutzen — Werte sind fest oder kommen über -backend-config-Dateien bei init. Das ist eine bewusste Einschränkung: Das Backend muss existieren, bevor Terraform läuft.

Erstes Setup: Du legst Bucket und DynamoDB-Tabelle manuell oder in einem separaten „bootstrap”-Stack an. Dieser Bootstrap-Stack hat selbst lokalen State oder einen minimalen Backend — das Henne-Ei-Problem kennst du einmal, danach referenzieren alle anderen Stacks darauf.

AWS: S3 + DynamoDB

KomponenteAufgabe
S3 BucketState-Datei speichern, Versionierung aktivieren
DynamoDB TableLock-Einträge (LockID, Conditional Writes)
encrypt = trueSSE-S3 oder SSE-KMS
IAM PolicyWer darf State lesen/schreiben?

Versionierung auf dem Bucket ist Pflicht: Bei korruptem State rollst du auf eine frühere S3-Version zurück — besser als neu importieren.

GCP: GCS Backend

terraform {
  backend "gcs" {
    bucket = "company-tf-state"
    prefix = "platform/network"
  }
}

GCS unterstützt natives Locking über Object-Metadaten — keine separate Lock-Tabelle nötig.

Terraform Cloud / HCP Terraform

Managed Backend mit UI, Run-Historie, Policy-as-Code (Sentinel) und Team-Permissions. Du tauschst Betriebsaufwand gegen Vendor-Lock-in und Kosten. Für Teams ohne eigene State-Infrastruktur oft der schnellste Weg in Produktion.

State zwischen Stacks teilen

Große Plattformen splitten Infrastruktur in Stacks — z. B. network, eks, apps — jeder mit eigenem State. Der EKS-Stack braucht VPC-ID und Subnet-IDs aus dem Network-Stack:

data "terraform_remote_state" "network" {
  backend = "s3"
  config = {
    bucket = "company-tf-state"
    key    = "platform/network/terraform.tfstate"
    region = "eu-central-1"
  }
}

resource "aws_eks_cluster" "platform" {
  name     = "platform-prod"
  role_arn = aws_iam_role.cluster.arn

  vpc_config {
    subnet_ids = data.terraform_remote_state.network.outputs.private_subnet_ids
  }
}

Der Network-Stack exportiert die Werte als Outputs; der EKS-Stack liest sie read-only. So bleiben Blast Radius und Apply-Frequenz getrennt — du musst nicht bei jeder App-Änderung den ganzen VPC-Stack mitplanen.

Alternative: Terragrunt wrappt Remote State und DRY-Backend-Konfiguration; manche Teams nutzen es, andere bleiben bei plain Terraform mit Copy-Paste-Backend-Blöcken. Beides ist legitim — entscheidend ist die Stack-Grenze, nicht das Wrapper-Tool.

Migration: lokal → remote

# Backend-Block in main.tf einfügen, dann:
terraform init -migrate-state
# Terraform fragt: "Copy existing state to the new backend?" → yes

Terraform kopiert den lokalen State ins Remote Backend. Die lokale Datei bleibt als Backup — lösche sie erst, wenn du verifiziert hast, dass der Remote State vollständig ist (terraform state list).

Praxis: MinIO als S3-kompatibles Backend (lokal)

Für ein Lab ohne AWS-Account kannst du MinIO nutzen — die Konfiguration ist identisch zu S3:

# MinIO läuft auf localhost:9000, Bucket "tfstate" angelegt
cat > backend.hcl <<'EOF'
bucket = "tfstate"
key    = "lab/demo.tfstate"
region = "us-east-1"
endpoint = "http://localhost:9000"
access_key = "minioadmin"
secret_key = "minioadmin"
skip_credentials_validation = true
skip_metadata_api_check     = true
force_path_style            = true
EOF

terraform init -backend-config=backend.hcl
terraform apply

In Produktion entfallen die skip_*-Flags — sie existieren nur für S3-kompatible Endpoints außerhalb AWS.

Typische Stolperfallen

Bucket ohne Versionierung: Ein korruptes State-Overwrite ist dann nicht recoverbar. Versionierung ist keine Option, sondern Pflicht.

Backend-Config mit Variablen: bucket = var.state_bucket funktioniert nicht im Backend-Block. Nutze -backend-config oder hardcoded Werte im Bootstrap-Stack.

Zu große Remote-State-Abhängigkeiten: Wenn zehn Stacks alle den Network-State lesen und der Network-Stack bei jedem Plan alle Reader triggert, wird die Kopplung eng. Outputs stabil halten, Breaking Changes versionieren.

IAM zu breit: s3:* auf den State-Bucket für alle Entwickler bedeutet: jeder kann State manipulieren. Trenne Plan-Rechte (read) von Apply-Rechten (write).

Lock-Tabelle vergessen: S3 allein ohne DynamoDB (bei AWS) — kein Locking. Zwei parallele Applies sind dann möglich.

Interview-Vorbereitung

„Warum Remote State?” — Team-Zusammenarbeit, Locking, zentraler Speicher, IAM-gesteuerte Zugriffe, Backup über S3-Versionierung.

Follow-ups:

  • „Wie teilst du State zwischen Stacks?” — Separate State-Dateien pro Stack; terraform_remote_state oder Terragrunt für Outputs.
  • „Was ist das Henne-Ei-Problem?” — Backend-Infrastruktur muss existieren, bevor andere Stacks sie nutzen; Bootstrap-Stack löst das.
  • „S3 vs. Terraform Cloud?” — Self-managed vs. Managed: Kontrolle und Kosten vs. weniger Ops und eingebaute Governance.
  • „Wie migrierst du lokal zu remote?” — terraform init -migrate-state.

Zusammenfassung

Remote State macht Terraform teamfähig: S3 + DynamoDB (AWS), GCS (GCP) oder Terraform Cloud speichern die State-Datei zentral, erzwingen Locking und ermöglichen IAM-basierte Zugriffskontrolle. Stacks teilen Daten über Outputs und terraform_remote_state, nicht über einen Monolith-State. Versionierung und Verschlüsselung sind Pflicht — der State ist so sensibel wie die Infrastruktur selbst.

In der nächsten Lektion strukturieren wir wiederholbare Bausteine mit Modulen.