🏗️ Terraform Lektion 8/15 ~8 Min. Fortgeschritten

Workspaces und Umgebungen

dev/staging/prod mit Workspaces oder Directory-Struktur.

📝 Meine Notizen

Lernziele

Nach dieser Lektion kannst du erklären, wofür Terraform Workspaces da sind — und wann du stattdessen separate Verzeichnisse oder Stacks nutzt. Du wechselst Workspaces, verstehst die Auswirkung auf den State und kennst die gängige Empfehlung für dev/staging/prod in Platform-Teams.

Das Problem: dieselbe Config, drei Umgebungen

Dein VPC-Modul ist fertig. Jetzt brauchst du es in dev, staging und prod — mit unterschiedlichen CIDRs, Instance-Größen und Tags. Drei Optionen stehen zur Debatte:

  1. Drei Kopien des Codes (dev/, staging/, prod/) — funktioniert, driftet aber
  2. Ein Code, drei State-Dateien über Workspaces oder separate Backend-Keys
  3. Ein Code, Variables pro Umgebung (dev.tfvars, prod.tfvars)

Option 1 ist verbreitet und oft die richtige Wahl. Option 2 und 3 werden häufig verwechselt — genau das klären wir hier.

Terraform Workspaces: was sie wirklich tun

Ein Workspace ist ein benannter State innerhalb desselben Backends. Der Code bleibt identisch; nur der State unterscheidet sich:

terraform workspace list
terraform workspace new dev
terraform workspace select prod
terraform workspace show

Im S3-Backend landet der State unter einem Key wie env:/prod/platform/network/terraform.tfstate statt direkt unter platform/network/terraform.tfstate. Default-Workspace heißt default.

Im Code kannst du den Workspace auslesen:

locals {
  environment = terraform.workspace
}

resource "aws_s3_bucket" "logs" {
  bucket = "logs-${local.environment}-${var.suffix}"
}

Das klingt elegant — ein Verzeichnis, ein terraform apply, Workspace wechseln, nochmal apply. In der Praxis stellt sich schnell die Frage: Wie verhinderst du, dass jemand aus Versehen apply im prod-Workspace ausführt, während er denkt, er ist in dev?

Workspaces vs. Verzeichnisstruktur: die ehrliche Empfehlung

KriteriumWorkspacesSeparate Verzeichnisse/Stacks
Code-DuplikationMinimalMehr (oder geteilt via Module)
State-IsolationGut (eigener Key)Sehr gut (eigener Key + oft eigenes Backend)
CI/CD-TrennungSchwerer — ein Job, Workspace-ParameterEinfacher — ein Pipeline pro Verzeichnis
Blast RadiusEin Fehler im falschen WorkspaceFehler bleibt im Stack
Unterschiedliche Provider-ConfigUmständlichNatürlich (eigene tfvars, eigene Backends)

HashiCorp empfiehlt Workspaces primär für ephemeral Environments desselben Typs — z. B. Preview-Umgebungen pro Pull Request, nicht für lang lebende prod/staging/dev mit unterschiedlichen IAM-Policies.

Die meisten Platform-Teams in Produktion nutzen separate Verzeichnisse oder Stacks:

infra/
├── env/
│   ├── dev/
│   │   ├── main.tf
│   │   ├── backend.tf
│   │   └── terraform.tfvars
│   ├── staging/
│   └── prod/
└── modules/
    └── vpc/

Jede Umgebung hat eigenes Backend (oder mindestens eigenen State-Key), eigene tfvars, eigene CI-Pipeline mit unterschiedlichen Approval-Gates. Verwechslungsgefahr sinkt dramatisch.

Workspaces sind legitim für: gleichartige Kurzlebig-Umgebungen, lokale Experimente, oder wenn du bewusst minimale Struktur willst und die CI-Disziplin hast, den Workspace als Pflichtparameter zu enforcen.

Variables + tfvars: die Ergänzung

Unabhängig von Workspaces oder Verzeichnissen parametrisierst du Unterschiede über Variables:

# variables.tf
variable "environment" {
  type = string
}

variable "instance_count" {
  type = number
}
# env/prod/terraform.tfvars
environment    = "prod"
instance_count = 3
cd env/prod
terraform plan -var-file=terraform.tfvars

Workspaces und tfvars sind orthogonal: Du kannst Workspaces und tfvars kombinieren — aber die Verwirrung steigt. Wähle ein Modell und halte es durch.

Praxis: Workspaces mit dem random-Provider

mkdir ws-lab && cd ws-lab
cat > main.tf <<'EOF'
terraform {
  required_providers {
    random = {
      source  = "hashicorp/random"
      version = "~> 3.6"
    }
  }
}

resource "random_pet" "server" {
  prefix = terraform.workspace
  length = 2
}

output "name" {
  value = random_pet.server.id
}
EOF

terraform init
terraform workspace new dev
terraform apply -auto-approve    # z.B. dev-faithful-moth
terraform workspace new prod
terraform apply -auto-approve    # z.B. prod-correct-horse
terraform workspace select dev
terraform output name            # dev-...
terraform workspace select prod
terraform output name            # prod-...
terraform workspace select default
terraform destroy                # nur default-Workspace!

Der letzte Schritt ist die Lektion: destroy im default-Workspace löscht nur dessen Ressourcen — dev und prod bleiben stehen, unsichtbar, bis du in deren Workspaces ebenfalls destroy ausführst. Genau diese „vergessenen” Ressourcen erzeugen Kosten.

Typische Stolperfallen

Prod-Apply im dev-Workspace: Kein technisches Hindernis — nur Disziplin. Separate Verzeichnisse mit unterschiedlichen CI-Approval-Flows sind sicherer.

Workspace vergessen vor destroy: Du destroyest nur den aktiven Workspace. Andere Workspaces laufen weiter und verursachen Kosten.

Workspaces für grundverschiedene Umgebungen: Prod braucht Multi-AZ, dev Single-AZ; prod braucht andere IAM-Rollen. Das in if workspace == "prod" zu packen, macht den Code unleserlich — separate Stacks sind klarer.

Backend-Key-Kollision: Ohne Workspace-Präfix im Backend-Key überschreiben Umgebungen sich gegenseitig. Workspaces fügen das Präfix automatisch hinzu; bei manuellen Keys musst du key = "env/prod/..." selbst setzen.

Interview-Vorbereitung

„Wie trennst du dev/staging/prod in Terraform?” — Drei Modelle nennen: Workspaces (geteilter Code, getrennter State), separate Verzeichnisse/Stacks (empfohlen für Prod), tfvars für Parameter. Trade-offs erklären.

Follow-ups:

  • „Wofür sind Workspaces gedacht?” — Mehrere States für denselben Code; ideal für ephemeral/previews, weniger für lang lebende Prod-Umgebungen.
  • „Was passiert bei terraform workspace select prod?” — Nur der State-Kontext wechselt; Code bleibt gleich.
  • „Workspaces vs. -var-file?” — Workspaces trennen State; tfvars trennen Parameter. Orthogonal, aber kombinierbar.
  • „Wie verhinderst du Accidental Prod Apply?” — Separate Pipelines, Backend-Keys, IAM — nicht nur Workspace-Namen.

Zusammenfassung

Workspaces bieten mehrere State-Instanzen für denselben Code — nützlich für Previews und Experimente. Für dev/staging/prod mit unterschiedlichen Policies empfehlen die meisten Teams separate Verzeichnisse oder Stacks mit eigenen Backends und CI-Pipelines. Variables und tfvars parametrisieren Unterschiede in beiden Modellen. Die Wahl ist weniger technisch als organisatorisch: Wie sehr willst du Verwechslungsgefahr eliminieren?

In der nächsten Lektion verbinden wir Terraform mit Kubernetes — Cluster-Ressourcen und Helm-Releases aus HCL.