Ein lokales terraform.tfstate auf dem Laptop skaliert nicht: Sobald zwei Kolleginnen dieselbe Infrastruktur anfassen, driftet der State auseinander, ein paralleles terraform apply zerschießt die Datei, und niemand hat die aktuelle Quelle der Wahrheit. Remote State löst das — eine geteilte, zentrale Statedatei plus Locking, das einen zweiten Lauf blockiert, statt den State zu korrumpieren. Das Problem: In den meisten Anleitungen landet genau dieser sensible State in einem AWS-S3-Bucket in den USA. intercolo i3 ist das S3-kompatible Backend in Deutschland: strong read-after-write, angesprochen über den Endpoint https://de-fra.i3storage.com in der Region de-fra, mit nativem Locking über use_lockfile (Terraform 1.10+ / OpenTofu 1.8+) — ohne DynamoDB, DSGVO/AVV, 99,999999% Durability und Daten, die das RZ Frankfurt nie verlassen.
endpoints = { s3 = ... } richtet das Backend auf de-fra.i3storage.com statt AWS. Die drei skip_-Flags sind bei einem Nicht-AWS-Endpoint Pflicht: skip_credentials_validation überspringt den AWS-STS-Check, skip_requesting_account_id die IAM-Account-Abfrage, skip_region_validation die Prüfung gegen die AWS-Regionsliste (de-fra ist keine AWS-Region). use_lockfile = true aktiviert das native Locking. Zugangsdaten kommen aus den Umgebungsvariablen AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY (Ihr SigV4-Schlüsselpaar).
Klassisch brauchte das AWS-S3-Backend eine separate DynamoDB-Tabelle (dynamodb_table) als Lock — ohne sie konnten zwei gleichzeitige Läufe den State zerstören. Seit Terraform 1.10 und OpenTofu 1.8 gibt es use_lockfile = true: Das Backend legt vor jedem schreibenden Lauf ein .tflock-Objekt direkt neben der Statedatei an — über bedingte S3-Schreibvorgänge (If-None-Match), die genau einen Schreiber gewinnen lassen. Kein zweiter Dienst, keine zusätzliche Rechnung, keine extra IAM-Policy für DynamoDB. intercolo i3 unterstützt diese Conditional Writes, also greift das Lock sauber für Ihr ganzes Team. Ein Backend-Block, fertig — der zweite apply wartet oder bricht mit Lock-Fehler ab, statt den State zu überschreiben.
Legen Sie einen Bucket an (z. B. tf-state) — per Web-Konsole, aws-cli oder rclone gegen https://de-fra.i3storage.com. Erzeugen Sie ein SigV4-API-Schlüsselpaar (Access/Secret). Für saubere Trennung nehmen Sie pro Umgebung (dev/stage/prod) ein eigenes Schlüsselpaar und idealerweise einen eigenen Bucket.
Fügen Sie den terraform { backend "s3" { ... } }-Block aus dem Beispiel ein: bucket, key, region = de-fra, endpoints = { s3 = "https://de-fra.i3storage.com" }, use_lockfile = true und die drei skip_-Flags. Exportieren Sie AWS_ACCESS_KEY_ID und AWS_SECRET_ACCESS_KEY mit Ihren SigV4-Schlüsseln (nicht in den Code committen).
Führen Sie terraform init -migrate-state aus (bei neuen Projekten genügt terraform init). Terraform kopiert Ihr vorhandenes lokales terraform.tfstate in den Bucket und bestätigt die Migration. Danach die lokale Statedatei löschen oder sicher archivieren — sie ist ab jetzt nur noch remote maßgeblich.
Ab jetzt zieht jeder terraform plan / apply vor dem Schreiben das .tflock-Lock und gibt es danach wieder frei. Ein zweiter, gleichzeitig laufender apply blockiert mit einem Lock-Fehler, statt den State zu beschädigen. Prüfen Sie mit terraform plan, dass keine Änderungen anstehen — dann liegt Ihr State sauber in Frankfurt.
Ehrlich und wichtig: Ein terraform.tfstate kann Klartext-Werte enthalten — DB-Passwörter, API-Tokens, generierte Schlüssel. Es gibt KEINE storage-seitige Verschlüsselung at-Rest, nur TLS auf dem Transport. Halten Sie Secrets deshalb möglichst aus dem State heraus: Referenzieren Sie sie über einen Secret-Manager oder HashiCorp Vault (data-Sources statt Klartext-Ressourcen), statt sie in Ressourcen zu schreiben, die im State landen. Wo ein Provider Werte zwingend persistiert, verschlüsseln Sie den State clientseitig, bevor er das Backend erreicht — OpenTofu 1.7+ kann State und Plan nativ clientseitig verschlüsseln, mit Terraform bietet sich ein SOPS/age-Workflow in der Pipeline an. Der Zugriff läuft ausschließlich über SigV4-API-Keys per TLS — kein öffentlicher Bucket. Nutzen Sie getrennte Schlüssel und Buckets pro Umgebung, damit ein geleakter Schlüssel einen kleinen Wirkungsradius hat.
| AWS S3 + DynamoDB | Wasabi | intercolo i3 | |
|---|---|---|---|
| Standort / Datenhoheit | US-Cloud, CLOUD Act | EU-Region wählbar, US-Konzern | RZ Frankfurt, 100% DE, DSGVO/AVV |
| Endpoint | s3.<region>.amazonaws.com | s3.<region>.wasabisys.com | https://de-fra.i3storage.com (de-fra) |
| State-Locking | DynamoDB (klassisch) oder use_lockfile | abhängig vom Conditional-Write-Support | natives use_lockfile (Conditional Writes) |
| Zusätzlicher Dienst nötig | DynamoDB-Tabelle (klassisch) | keiner | keiner |
| Egress-Modell | pro GB, plus Anfragekosten | 'kostenlos' bis Speichermenge, dann gedrosselt | 1 TB inkl./TB, dann +3,99 €/TB |
| Verschlüsselung at-Rest | SSE-S3 / KMS verfügbar | SSE verfügbar | Nein — clientseitig (OpenTofu/SOPS), TLS-Transport |
| Support / Ansprechpartner | Ticket, EN | Ticket, EN | Direkt, deutsch, RZ-Team |
Wer bereits das AWS-S3-Backend nutzt, migriert mit minimalem Diff: Im bestehenden backend "s3"-Block setzen Sie region = "de-fra", ergänzen endpoints = { s3 = "https://de-fra.i3storage.com" } sowie die drei skip_-Flags und use_lockfile = true — und entfernen die alte Zeile dynamodb_table. AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY zeigen Sie auf Ihre intercolo-SigV4-Schlüssel. Ein terraform init -migrate-state kopiert den State aus AWS in den Frankfurter Bucket. Ihre Ressourcen, Module und Provider bleiben unangetastet — es zieht nur der State um. Zur Kontrolle zeigt terraform plan danach keine Änderungen an.
Funktioniert mit HashiCorp Terraform 1.10+ (use_lockfile) und OpenTofu 1.8+ — derselbe Backend-Block für beide. OpenTofu bringt zusätzlich native, clientseitige State- und Plan-Verschlüsselung (ab 1.7) mit, falls Sie den State verschlüsselt ablegen wollen.
In GitLab CI, GitHub Actions, Atlantis oder Jenkins hinterlegen Sie AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY (SigV4) und region = de-fra als geschützte Variablen. Das native Lock serialisiert parallele Pipeline-Läufe — zwei Merge Requests können nicht gleichzeitig applyen.
Trennen Sie dev/stage/prod über Terraform-Workspaces oder eigene key-Prefixe (env:/prod/...) — in einem oder mehreren Buckets. Kombiniert mit je eigenem SigV4-Schlüsselpaar pro Umgebung bleibt jeder State organisatorisch und schlüsseltechnisch isoliert.
Nach dem apply liefert der nächste Lesezugriff sofort den aktuellen State — strong read-after-write-Konsistenz. Keine veralteten Statedateien, keine Races zwischen unmittelbar aufeinanderfolgenden Läufen, wie sie eventually-consistente Speicher provozieren.
Unsere Erfahrung spricht für sich: Wir haben bereits erfolgreich Migrationen mit mehreren Petabyte an Daten und über 500 Millionen Dateien durchgeführt.