Start / Seminare / Terraform und OpenTofu in der Praxis
Modul
State, Backends und Zusammenarbeit
Modul 6 von 14 aus dem Seminar Terraform und OpenTofu in der Praxis
5 Kapitel in diesem Modul-Video · Laufzeit
Für Teams
Die Videos zeigen, wie es geht. Die Schulung sorgt dafür, dass Ihr Team es danach tut.
Ein Video kann niemanden fragen, warum es ausgerechnet in Ihrem Repository nicht funktioniert. Es kann kein Team auf eine gemeinsame Konvention bringen. Und es setzt sich niemand freiwillig drei Tage hin. In der Schulung sind am Ende alle auf demselben Stand, gearbeitet wurde am eigenen Code, und die offenen Fragen sind entschieden — in ein paar Tagen statt irgendwann nebenbei.
Vorgespräch am Telefon · Programm nach Maß · ab 1 Tag (8 Unterrichtseinheiten) · Teilnahmezertifikat
Transkript
Der gesprochene Text dieses Moduls zum Mitlesen, Überfliegen und Durchsuchen. Ein Klick auf einen Zeitstempel springt an die Stelle im Video.
State, Backends und Zusammenarbeit
0:00 Solange eine einzelne Person an Saatplan arbeitet, fällt der State kaum auf. Er liegt als Datei im Arbeitsverzeichnis und tut still seine Arbeit. Das ändert sich in dem Moment, in dem ein zweiter Kollege bei der Gärtnerei Lindenhof mitarbeitet oder eine Pipeline ins Spiel kommt. Plötzlich gibt es mehrere Kopien, und keiner weiß, welche stimmt.
0:19 In diesem Modul schauen wir uns an, was im State eigentlich steht, wie man ihn in ein gemeinsames Backend in PostgreSQL verlegt, wie man das Henne-Ei-Problem beim Anlegen dieses Backends löst und wie Konfigurationen untereinander Daten austauschen. Am Ende steht ein State, der teamfähig ist — und sich im Notfall wiederherstellen lässt.
State, Backends und Zusammenarbeit
0:38 Mit diesem Modul schließen wir den zweiten Tag ab. Der Leitsatz bringt es auf den Punkt: Wer den State verliert, verliert nicht die Container — die laufen weiter. Er verliert das Wissen, welche davon ihm gehören. Wir gehen in fünf Schritten vor, vom Inhalt der State-Datei über das Remote Backend mit Sperre, die Migration dorthin und den Austausch zwischen Konfigurationen bis zur Übung.
1:00 Danach haben Sie das Fundament für alles, was an den folgenden Tagen im Team und in Pipelines passiert.
Was im State steht
1:06 Bevor wir den State verschieben, sollten wir wissen, was wir da eigentlich verschieben. Es ist mehr als eine Liste von Ressourcen — und manches davon ist heikler, als man denkt. Stellen Sie sich das Beetbuch einer Gärtnerei vor. Draußen stehen die Pflanzen, und im Buch steht, welches Beet zu welcher Bestellung gehört. Die Pflanzen wachsen auch ohne Buch weiter — aber niemand weiß mehr, welche man umpflanzen oder abräumen darf. Genau diese Rolle spielt der State.
1:34 Er verbindet jede Adresse in der Konfiguration, etwa den API-Container im Saatplan-Modul, mit genau einem realen Objekt auf dem Docker-Host. Dazu merkt er sich Attribute, Abhängigkeiten und den zuletzt genutzten Provider. Ohne diese Zuordnung könnten weder Terraform noch OpenTofu entscheiden, was sie ändern oder löschen dürfen. Der State ist also nicht Beiwerk, sondern das Gedächtnis des Werkzeugs.
1:59 Diese Schichten zeigen, dass der State mehr ist als ein Inhaltsverzeichnis. Ganz oben steht die Bindung, also die Zuordnung von Adresse zu Objekt — das, was wir gerade besprochen haben. Darunter die Attribute, ein Zwischenspeicher aller bekannten Werte. Dann die Metadaten, die man leicht unterschätzt: Abhängigkeiten und Provider werden gebraucht, um Ressourcen in der richtigen Reihenfolge zu löschen, auch wenn sie längst aus dem Code verschwunden sind.
2:24 Die unterste Schicht ist die wichtigste Warnung dieses Kapitels. Sensible Werte stehen im State im Klartext, auch wenn sie im Code als sensitive markiert sind. Das bestimmt, wie man den State behandeln muss: wie ein Geheimnis. Hier sehen Sie die lesenden Werkzeuge. Mit terraform state list bekommen Sie die Adressen aller verwalteten Ressourcen — man erkennt sofort das Netz, das Volume, die Datenbank und den API-Container im Modul aus dem letzten Kapitel.
2:51 Mit state show schauen Sie sich eine einzelne Ressource im Detail an. Und terraform show mit JSON-Ausgabe ist der Weg, wenn ein Skript oder Werkzeug den State auswerten soll. Warum nicht einfach die Datei direkt lesen? Die Fußzeile gibt die Antwort: Das interne Format kann sich mit jeder Version ändern. Die JSON-Ausgaben von show und output dagegen sind die Schnittstelle, auf die man sich verlassen darf.
3:15 Diese vier Fehler passieren nicht aus Nachlässigkeit, sondern meist aus gutem Willen. Die State-Datei landet im Git, weil man ja alles versionieren will — und mit ihr jeder Wert, der darin im Klartext steht. Der State wird von Hand bearbeitet, weil das schneller scheint als die passenden Kommandos. Zwei Ressourcen zeigen auf dasselbe Objekt, und dann weiß niemand mehr, wem der Container gehört.
3:38 Und der vierte Fall ist der gefährlichste, weil er so logisch klingt: Die Container laufen doch, also kann der State weg. Der nächste Plan sieht dann nur leere Beete und will alles neu anlegen.
Remote Backend mit Locking
3:49 Ein State für alle, und immer nur einer, der gerade schreibt — das sind die zwei Versprechen eines Remote Backends. Wir setzen es mit PostgreSQL um, weil das ohne jeden Cloud-Account auskommt. Der Vergleich macht deutlich, was sich mit dem Umzug ändert. Lokal hat jede Person ihre eigene Kopie, und die Sperre wirkt nur auf demselben Rechner.
4:11 Zwei Kollegen an zwei Laptops merken also nichts voneinander. Mit dem pg-Backend lesen und schreiben alle Läufe denselben Stand in einer Tabelle, und ein Advisory Lock in PostgreSQL sorgt dafür, dass nie zwei gleichzeitig schreiben. Die letzte Zeile ist der Preis dafür, und den sollten Sie kennen: Lokal gibt es immerhin eine Backup-Datei mit dem Vorgänger, im pg-Backend nur den aktuellen Stand.
4:33 Eine Sicherung ist dort also nicht eingebaut, sondern Ihre Aufgabe — wir kommen darauf zurück. Auffällig ist hier vor allem, was fehlt. Der Backend-Block im Code ist leer. Verbindung, Benutzer, Passwort und Schema kommen vollständig aus Umgebungsvariablen. Das Passwort wird dabei interaktiv eingelesen, damit es nicht einmal in der Shell-Historie landet.
4:54 Der Grund steht in der Fußzeile: Was im Code oder über die Option backend-config übergeben wird, landet im Verzeichnis punkt terraform und sogar in gespeicherten Plan-Dateien. Werte aus der Umgebung dagegen nicht. Eine Zeile verdient noch einen Blick: Das Abschalten von TLS ist ausdrücklich nur fürs Labor gedacht. In jeder echten Umgebung gehört die Verbindung zur State-Datenbank verschlüsselt — schließlich stehen darin Geheimnisse im Klartext.
5:21 Jetzt sehen wir die Sperre in Aktion. Im ersten Terminal läuft ein apply und wartet auf die Bestätigung — der State ist damit gesperrt. Im zweiten Terminal versucht ein plan denselben State zu sperren und bricht mit einer klaren Meldung ab. Das ist kein Fehler, sondern genau das gewünschte Verhalten. Ohne diese Sperre würde der zweite Lauf das Ergebnis des ersten einfach überschreiben.
5:44 Für Pipelines, in denen sich Läufe kurz überschneiden können, gibt es die Option lock-timeout: Statt sofort abzubrechen, wartet der Lauf eine Weile. Die Option, den Lock ganz abzuschalten, existiert zwar — aber sie hebt genau den Schutz auf, für den wir das Backend eingerichtet haben. Diese Tabelle ist Ihr Spickzettel für das pg-Backend, und die Logik dahinter ist schlicht: Alles ist eine Zeile in einer Tabelle.
6:08 Jeder Workspace bekommt eine eigene Zeile, ohne Workspaces heißt sie default. Daraus folgt die wichtigste Regel aus der Fußzeile: Jedes Root Module braucht sein eigenes Schema, sonst teilen sich zwei Konfigurationen dieselbe Zeile und überschreiben sich gegenseitig. Zwei Besonderheiten sollten Sie kennen. Die Datenbank muss vor dem ersten init existieren, das Backend legt sie nicht selbst an.
6:30 Und ein hängender Lock lässt sich nicht per force-unlock lösen. Weil Advisory Locks an der Sitzung hängen, verschwinden sie aber mit dem Ende der Verbindung.
Backend-Bootstrap und Migration
6:40 Jetzt stoßen wir auf ein klassisches Rätsel. Die Datenbank für den State ist selbst Infrastruktur. Wer verwaltet eigentlich deren State? Die Antwort ist pragmatisch — und sie gilt in der Cloud genauso. Ein Backend kann sich nicht selbst verwalten. Es muss existieren, bevor das erste init läuft, und kann seinen eigenen State daher nicht in sich ablegen.
7:02 Die Lösung ist eine kleine, getrennte Bootstrap-Konfiguration, die nur die State-Datenbank startet und ihren State lokal behält — diese eine Datei sichert man mit. Die Datenbank tfstate selbst entsteht entweder über createdb oder gleich beim ersten Start des PostgreSQL-Images. Bemerkenswert ist der letzte Punkt: In der Cloud ist es exakt dasselbe Muster, nur heißt das Backend dort Bucket oder Storage Account.
7:26 Wer das Prinzip einmal mit Docker verstanden hat, erkennt es überall wieder. Die Migration selbst ist erstaunlich unspektakulär, und genau so soll sie sein. Zuerst wird der lokale State kopiert, wie es die Doku vor jeder Migration empfiehlt. Dann tragen Sie den leeren Backend-Block ein, setzen die Umgebung und rufen terraform init mit der Option migrate-state auf.
7:48 Das Werkzeug erkennt den Wechsel und überträgt den bisherigen Stand. Entscheidend ist der dritte Schritt: Die Prüfung. Dieselben Adressen in der Liste und ein leerer Plan beweisen, dass nichts verloren gegangen ist. Mit OpenTofu läuft das identisch. Vorsicht bei der ähnlich klingenden Option reconfigure — sie lässt den alten State einfach zurück, statt ihn mitzunehmen.
8:10 Wir haben vorhin gesehen, dass das pg-Backend keine Historie führt. Deshalb gehört eine Sicherung fest dazu, und hier gibt es zwei Ebenen. Die gründliche ist die Datenbanksicherung mit pg_dump, die auch die Sequenz im Schema public mitnimmt. Auf der Folie wird der Verlust sogar bewusst geübt: Datenbank weg, neu angelegt, Dump zurückgespielt.
8:31 Die zweite Ebene arbeitet über das Werkzeug selbst, mit state pull und state push für einen einzelnen Stand. Dabei schützt eine eingebaute Prüfung: Push verweigert einen State aus fremder Herkunft oder einen älteren Stand. Die Option force hebt diese Prüfung auf — wer sie nutzt, sollte sehr genau wissen, warum. Alle vier Fallen kreisen um dieselbe Frage: Kommt man im Ernstfall wirklich zurück? Ohne geplanten pg_dump gibt es keinen Stand von gestern — das Backend hält nur den aktuellen.
9:00 Eine Sicherung im selben Volume wie die Datenbank ist keine Sicherung, denn sie fällt im selben Moment aus. Heikel ist auch das Zurückspielen eines alten Stands mit Gewalt, während die Container inzwischen anders aussehen; dann stimmt das Gedächtnis nicht mehr mit der Wirklichkeit überein. Und der vierte Punkt betrifft gemischte Teams: Seit OpenTofu 1.10 sperrt das Backend beim Anlegen anders.
9:23 Unterschiedliche Versionen sollten deshalb nie parallel auf dieselbe Datenbank zugreifen.
Daten zwischen Konfigurationen austauschen
9:28 Größere Infrastrukturen bestehen selten aus einer einzigen Konfiguration. Irgendwann braucht die eine einen Wert aus der anderen. Outputs sind dafür die Schnittstelle — aber der Zugriff ist weitreichender, als es aussieht. Angenommen, das Netz von Saatplan wird in einer eigenen Basiskonfiguration verwaltet, und die Anwendung braucht dessen Namen.
9:50 Die Datenquelle terraform_remote_state liest dafür den State der Basis aus dem pg-Backend, gezielt aus deren eigenem Schema. Anschließend stehen deren Root-Outputs zur Verfügung, etwa der Netzname. Das ist praktisch und schnell eingerichtet. Wichtig ist auch hier, was in der Konfiguration fehlt: Benutzer und Passwort kommen wieder aus der Umgebung, nie aus dem config-Block.
10:12 Sonst stünden die Zugangsdaten zur State-Datenbank am Ende im Code jeder Konfiguration, die etwas lesen möchte. Die nächste Folie zeigt, warum dieser Zugriff mit Bedacht vergeben werden sollte. Hier steckt ein Haken, der oft übersehen wird. Sichtbar werden zwar nur die Root-Outputs der anderen Konfiguration, doch technisch braucht man Lesezugriff auf deren gesamten State.
10:35 Und wer den ganzen State lesen darf, sieht auch alle sensiblen Werte darin. Das ist, als gäbe man jemandem den Schlüssel zum ganzen Archiv, nur weil er ein einziges Blatt braucht. Daraus folgen zwei Empfehlungen. Erstens: Outputs genauso bewusst auswählen und beschreiben wie bei Modulen, denn sie werden zum Vertrag zwischen Teams.
10:54 Zweitens empfiehlt die Doku, geteilte Werte lieber getrennt zu veröffentlichen, etwa als DNS-Eintrag oder in einem Konfigurationsspeicher. Diese Tabelle ordnet die state-Kommandos nach ihrem Risiko. Oben stehen die lesenden, die nichts verändern. Pull und push bewegen ganze Stände, mit den Prüfungen, die wir eben gesehen haben.
11:14 Interessant sind die mittleren Zeilen: Für das Umadressieren und das Lösen einer Bindung gibt es heute deklarative Alternativen im Code, nämlich moved- und removed-Blöcke. Die sind nachvollziehbar, landen im Review und laufen durch den normalen Plan. Ganz unten steht force-unlock — ein Werkzeug für den Notfall, nur zu nutzen, wenn sicher kein Lauf mehr schreibt.
11:35 Beruhigend ist die Fußzeile: Jedes ändernde Kommando legt automatisch ein Backup an.
Übung
11:41 Jetzt machen wir den State von Saatplan teamfähig. Sie verlegen ihn ins gemeinsame Backend, provozieren einen Konflikt und spielen einen Verlust durch — einmal in Ruhe, damit es im Ernstfall Routine ist. In dieser Übung geht es um zwei Fähigkeiten, die im Betrieb zählen: eine Migration sicher durchzuführen und mit Sperre und Wiederherstellung umgehen zu können.
12:02 Das Erfolgskriterium ist bewusst doppelt formuliert. Ein zweiter Lauf soll mit einer Lock-Meldung abbrechen, statt zu schreiben — damit sehen Sie, dass der Schutz greift. Und nach der Wiederherstellung soll der Plan keine Änderungen zeigen, denn erst das beweist, dass das Gedächtnis wieder zur Wirklichkeit passt. Der Hinweis ist dabei keine Formalie: Kein Passwort gehört in die Backend-Datei oder in eine separate Konfigurationsdatei, sondern nur in die Umgebung.
12:29 Der Weg folgt der Reihenfolge des Moduls. Zuerst entsteht die State-Datenbank über die eigene Bootstrap-Konfiguration — das Henne-Ei-Problem wird also gleich zu Beginn gelöst. Danach folgt die Migration, abgesichert durch eine Kopie des lokalen States. Im dritten Schritt erleben Sie den Lock-Konflikt selbst und lösen ihn durch Warten statt durch Abschalten.
12:49 Der vierte Schritt ist der mutigste: die Datenbank absichtlich verlieren und zurückholen. Zum Schluss belegen Sie mit Liste und Plan, dass nichts verloren ging. Damit ist der zweite Tag abgeschlossen. Im nächsten Modul geht es um Secrets — und nach diesem Modul wissen Sie, warum der State dabei eine zentrale Rolle spielt.
Dieses Modul als Schulung für Ihr Team
Das Video zeigt den Stoff. In der Schulung arbeitet Ihr Team damit — an Ihrem eigenen Code, mit Übungen und mit den Fragen, die ein Video nicht beantwortet. Sie wählen die Module aus Terraform und OpenTofu in der Praxis, wir bauen daraus ein Programm.
5 Tage·ab 900 EUR netto pro Tag (bis 3 Teilnehmende) ·Termin nach Vereinbarung