Inhaltsverzeichnis
- Voraussetzungen
- Warum OpenTofu?
- Der einfache Fall
- Falle 1: Die State-Version ist eine Einbahnstraße
- Falle 2: terraform_remote_state propagiert die State-Version
- Schnelldurchlauf: der Kleinkram
- Fazit
Voraussetzungen
- eine bestehende Terraform-Konfiguration, die du auf OpenTofu umstellen möchtest
tofuist installiert (OpenTofu >= 1.6)- dein State liegt in einem Remote-Backend (z. B. S3) mit aktiviertem Versioning — oder du legst vor der Migration ein Backup an
Warum OpenTofu?
Im August 2023 hat HashiCorp die Lizenz von Terraform von der quelloffenen MPL 2.0 auf die Business Source License (BSL) umgestellt. Die letzte unter MPL veröffentlichte Version ist Terraform 1.5.7. Alles danach ist nicht mehr Open Source im klassischen Sinn.
OpenTofu ist der von der Linux Foundation getragene Fork genau dieser letzten freien Version — quelloffen, herstellerunabhängig und damit ein Baustein digitaler Souveränität: kein Vendor-Lock-in, keine Lizenz-Überraschung von oben.
Der Fork-Punkt — nachgewiesen
Man muss das nicht glauben, man kann es sehen. OpenTofu zweigt nachweisbar von Terraform ab. Der gemeinsame Vorfahr beider Git-Historien lässt sich exakt bestimmen:
git clone https://github.com/hashicorp/terraform.git
git clone https://github.com/opentofu/opentofu.git
mkdir compare && cd compare && git init
git remote add terraform ../terraform
git remote add opentofu ../opentofu
git fetch terraform
git fetch opentofu
git merge-base opentofu/main terraform/main
git merge-base liefert den Commit, an dem sich die beiden Historien das letzte Mal trafen — den Verzweigungspunkt. OpenTofu ist also kein Re-Implementierungsversuch von außen, sondern teilt sich die Vergangenheit mit Terraform.
Der einfache Fall
Hat man ein einziges, isoliertes Projekt, ist die Migration tatsächlich beinahe ein Nicht-Ereignis. Statt terraform ruft man tofu auf:
tofu init
tofu plan
tofu init baut den lokalen .terraform-Cache neu auf, tofu plan vergleicht deinen Code mit dem State. Im Idealfall meldet OpenTofu:
No changes. Your infrastructure matches the configuration.
Kein Diff, keine geplanten Änderungen — OpenTofu liest denselben State und dieselbe Konfiguration wie Terraform zuvor. Genau das wollen wir.
Das Problem: Fast niemand hat nur ein Projekt. Sobald mehrere Konfigurationen im Spiel sind, beginnt die eigentliche Migration — und mit ihr die Fallen.
Falle 1: Die State-Version ist eine Einbahnstraße
Jeder State hat eine Format-Version. Migrierst du ein Projekt auf OpenTofu und führst dort einen apply aus, kann die Version des State-Files angehoben werden. Das ist an sich harmlos — solange alle Werkzeuge, die diesen State lesen, das neue Format auch verstehen.
Der Haken: Diese Anhebung ist eine Einbahnstraße. Älteres Terraform (z. B. das eingefrorene 1.5.7) kann einen auf eine neuere Version gehobenen State nicht mehr lesen. Es gibt kein „Downgrade” des State-Formats.
Quick-Win: so sicherst du dich ab
- State sichern, bevor du den ersten
applymit OpenTofu fährst. - Bucket-Versioning aktivieren (bei S3 & Co.), damit du jederzeit auf die vorherige State-Version zurückkannst.
- Niemals zuerst in Produktion migrieren — übe in einer unkritischen Umgebung, bis der Ablauf sitzt.
Das klingt nach Pflichtprogramm — und das ist es auch. Denn genau dieser Mechanismus ist der Auslöser für die große Falle.
Falle 2: terraform_remote_state propagiert die State-Version
In der Praxis sind Konfigurationen aufgeteilt — z. B. eine network-Konfiguration und eine app-Konfiguration. Die app greift über terraform_remote_state lesend auf den State der network-Konfiguration zu:
data "terraform_remote_state" "network" {
backend = "s3"
config = {
bucket = "mein-state-bucket"
key = "network/terraform.tfstate"
region = "eu-central-1"
}
}
Und hier wird es gefährlich. terraform_remote_state liest nicht nur einzelne Outputs heraus — es liest das komplette State-File ein, inklusive seiner Format-Version.
Das Szenario:
- Du migrierst die
network-Konfiguration auf OpenTofu und fährst einenapply. Die State-Version dernetworkwird angehoben. - Die
app-Konfiguration läuft aber noch mit dem alten Terraform. - Beim nächsten Lauf will die
appüberterraform_remote_statedennetwork-State lesen — und kann das angehobene Format nicht mehr parsen. - Die
appsteht still. Obwohl an ihrem eigenen Code nichts geändert wurde.
Das ist der Moment, in dem ein Team ausgebremst wird, ohne zu verstehen, warum: Die Ursache liegt in einer anderen Konfiguration.
Die Lösung: als ein Paket migrieren
Interdependente Konfigurationen, die über terraform_remote_state verbunden sind, gehören gemeinsam migriert — in der richtigen Reihenfolge, als ein zusammenhängendes Paket. Migriere nicht die network, lass die app zurück und hoffe das Beste. Plane den Schnitt so, dass alle Beteiligten danach dasselbe Werkzeug (OpenTofu) und damit dasselbe State-Format sprechen.
Übrigens: Den Daten-Block heißt weiterhin
terraform_remote_state— auch unter OpenTofu. Es gibt hier nichts umzubenennen.
Details dazu im offiziellen Guide: Migrating multiple configurations.
Schnelldurchlauf: der Kleinkram
Drei Kleinigkeiten, die in der Praxis trotzdem stolpern lassen:
required_version— Versions-Constraints, die auf Terraform-Versionen zielen, prüfen. OpenTofu hat eine eigene Versionsreihe (ab 1.6).- Lock-File neu erzeugen — die
.terraform.lock.hclreferenziert die Provider-Registry. Nach der Migration neu generieren, damit Provider ausregistry.opentofu.orggezogen werden. - Binary-Name
tofu— durchsuche CI-Pipelines, Makefiles und Skripte nach hartcodiertenterraform-Aufrufen und stelle sie auftofuum.
Falle: der sso-Backend-Cache-Fehler
Eine Falle, die beim ersten tofu init mit S3-Backend zuverlässig zuschlägt:
Error: Failed to decode current backend config
The backend configuration created by the most recent run of "tofu init"
could not be decoded: unsupported attribute "sso".
Run "tofu init -reconfigure" to force re-initialization.
Ursache: Der lokale Backend-Cache .terraform/terraform.tfstate (das ist nicht dein echter State!) wurde von Terraform >= 1.6 geschrieben. Dessen s3-Backend kennt ein sso-Attribut (AWS IAM Identity Center). OpenTofus s3-Backend kennt dieses Attribut nicht — also scheitert das Decoding.
Fix — der Remote-State bleibt dabei völlig unangetastet:
tofu init -reconfigure
# Notnagel mit gleichem Effekt:
rm -rf .terraform && tofu init
Bewusst nicht -migrate-state: Das Backend wechselt ja gar nicht, nur der lokale Cache wird neu aufgebaut.
Fazit
Der Wechsel von Terraform zu OpenTofu ist in Isolation ein Einzeiler — die Tücken stecken im Zusammenspiel mehrerer Konfigurationen. Du hast in diesem Tutorial gelernt:
- warum OpenTofu (Lizenzwechsel, nachgewiesener Fork-Punkt via
git merge-base), - dass der einfache Fall dank
tofu init/tofu plan→ „No changes” trivial ist, - dass die State-Version eine Einbahnstraße ist — und wie du dich mit Backup und Versioning absicherst,
- wie
terraform_remote_stategenau diese Version über interdependente Konfigurationen propagiert und ein Team lahmlegen kann — und dass die Lösung das gemeinsame Migrieren als Paket ist, - und wie du Kleinkram wie den
sso-Backend-Cache-Fehler mittofu init -reconfigureausräumst.
Migriere in der richtigen Reihenfolge, und der Wechsel auf einen offenen, souveränen Stack ist kein Drama, sondern ein Routine-Schritt.
trutz.io --newsletter
Newsletter
Erhalte praxisnahe Tutorials, Best Practices und echte Lösungen für die häufigsten DevOps-Probleme direkt in Dein Postfach.
Datenschutz: Deine E-Mail-Adresse wird DSGVO-konform in Deutschland gespeichert. Keine Spam, nur relevante Inhalte. Eine E-Mail alle 1 bis 2 Wochen.