Workspaces und Umgebungen
dev/staging/prod mit Workspaces oder Directory-Struktur.
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:
- Drei Kopien des Codes (
dev/,staging/,prod/) — funktioniert, driftet aber - Ein Code, drei State-Dateien über Workspaces oder separate Backend-Keys
- 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
| Kriterium | Workspaces | Separate Verzeichnisse/Stacks |
|---|---|---|
| Code-Duplikation | Minimal | Mehr (oder geteilt via Module) |
| State-Isolation | Gut (eigener Key) | Sehr gut (eigener Key + oft eigenes Backend) |
| CI/CD-Trennung | Schwerer — ein Job, Workspace-Parameter | Einfacher — ein Pipeline pro Verzeichnis |
| Blast Radius | Ein Fehler im falschen Workspace | Fehler bleibt im Stack |
| Unterschiedliche Provider-Config | Umständlich | Natü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.