Start / Seminare / Terraform und OpenTofu in der Praxis

Modul

Umgebungen und größere Strukturen

Modul 8 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

Schulung anfragen So läuft eine Schulung ab

Vertonung mit synthetischer Stimme · Inhalte redaktionell verantwortet · © 2026 HECKER CONSULTING, alle Rechte vorbehalten

Transkript

Der gesprochene Text dieses Moduls zum Mitlesen, Überfliegen und Durchsuchen. Ein Klick auf einen Zeitstempel springt an die Stelle im Video.

Umgebungen und größere Strukturen

0:00 Willkommen zu Modul acht. Solange Saatplan nur eine Umgebung hatte, war die Struktur einfach: ein Verzeichnis, ein State, ein Docker-Host. In der Wirklichkeit der Gärtnerei Lindenhof gibt es aber eine Testumgebung und eine Produktion, und beide sollen sich gleichen, ohne sich zu gefährden. Darum geht es hier. Wir klären, wie man Umgebungen sauber trennt, wie man sie parametrisiert, statt Konfigurationen zu kopieren, wie eine Konfiguration mehrere Ziele anspricht und wie man viele States in eine sinnvolle Reihenfolge bringt.

0:31 Am Ende entwerfen Sie selbst die Struktur für zwei Docker-Hosts. Es ist ein Modul über Architektur, weniger über Syntax, und genau deshalb eines der folgenreichsten.

Umgebungen und größere Strukturen

0:41 Nach den Geheimnissen jetzt die Frage, wie ein wachsendes Projekt seine Form behält. Der Satz auf dieser Folie bringt es auf den Punkt. Eine Umgebung ist nicht einfach ein anderer Wert in einer Variable, sondern eine Grenze, an der ein Fehler aufhören soll. Wer das ernst nimmt, trifft andere Entscheidungen über States, Verzeichnisse und Zugänge. Und genau diese Entscheidungen sehen wir uns jetzt der Reihe nach an.

Umgebungen nach Risiko trennen

1:05 Dass Test und Produktion getrennt gehören, bestreitet niemand. Spannend ist die Frage, wie tief diese Trennung gehen muss, und dafür gibt es zwei grundverschiedene Antworten. Die Grundregel ist unverhandelbar: Test und Produktion teilen sich keinen State. Für die Umsetzung gibt es zwei Wege. CLI-Workspaces halten mehrere States derselben Konfiguration im selben Backend, ein bisschen wie mehrere Ordner in einem gemeinsamen Aktenschrank.

1:31 Getrennte Root Modules geben dagegen jeder Umgebung ein eigenes Verzeichnis mit eigenem Backend und eigenen Zugängen, also eher zwei Schränke in zwei Räumen mit zwei Schlüsseln. Saatplan geht bewusst den zweiten Weg, mit je einem Verzeichnis für test und für prod unter envs. Das bedeutet etwas mehr Struktur, aber es knüpft direkt an das vorige Modul an: Getrennte Zugänge gibt es nur bei getrennten Räumen.

1:55 Die Gegenüberstellung zeigt, dass beide Wege ihre Berechtigung haben, nur für unterschiedliche Zwecke. Workspaces sind schnell angelegt und schnell gewechselt, ein Befehl genügt. Damit eignen sie sich hervorragend für kurzlebige Kopien, etwa eine Umgebung je Feature-Branch, die nach dem Merge wieder verschwindet. Ihr Preis steht in der zweiten Zeile: dasselbe Backend, dieselben Zugänge. Getrennte Root Modules wechseln Sie, indem Sie das Verzeichnis wechseln.

2:23 Das klingt banal, ist aber ein Sicherheitsgewinn, denn niemand landet aus Versehen im falschen Workspace. Die Faustregel: Wo das Risiko gleich ist, genügen Workspaces. Wo es sich unterscheidet, wie zwischen test und prod, braucht es getrennte Root Modules. Wenn es nicht nur um Umgebungen geht, sondern auch darum, eine Umgebung in mehrere States zu teilen, helfen drei Fragen. Die erste ist der Lebenszyklus.

2:48 Netz und Datenvolume ändern sich selten, die API-Container ständig. Wer beides zusammenlegt, riskiert bei jedem kleinen Release das Fundament. Die zweite ist Zuständigkeit: Was ein Team allein verantwortet, bekommt einen eigenen State. Die dritte ist der Schadensradius. Ein misslungener Apply trifft höchstens das, was in seinem State steht.

3:09 Und der letzte Punkt erklärt noch einmal die Entscheidung gegen Workspaces: Auch die Dokumentation rät davon ab, sie für getrennte Zugänge zu verwenden. Ein gemeinsames Backend heißt, jeder Lauf erreicht jeden State.

Parameter ohne Konfigurationskopien

3:23 Getrennte Verzeichnisse wecken sofort eine Sorge: Schreiben wir jetzt alles doppelt? Die Antwort ist nein, wenn man die Arbeit richtig verteilt. Der Trick liegt in den Modulen aus Tag zwei. Beide Umgebungen rufen dasselbe Modul für die Saatplan-Anwendung auf. Unterscheiden dürfen sie sich nur in drei Dingen: wohin ihr State geht, welchen Docker-Host der Provider anspricht und welche Werte die Variablen haben.

3:48 Alles andere steht genau einmal im Modul. Vergleichen Sie es mit einem Rezept, das in zwei Küchen gekocht wird. Das Rezept ist dasselbe, nur Herd und Portionsgröße unterscheiden sich. Damit wird ein Root Module zu einer dünnen Hülle, die vor allem verdrahtet. Das hat einen angenehmen Nebeneffekt: Wer wissen will, was eine Umgebung besonders macht, muss nur wenige Zeilen lesen.

4:11 So dünn ist diese Hülle tatsächlich. Ein Backend-Block mit eigenem Schema im pg-Backend, ein Provider, der per SSH den Testhost anspricht, und der Aufruf des gemeinsamen Moduls mit dem Image-Tag als Parameter. Die Produktion sieht genauso aus, nur mit anderem Schema und anderem Host. Achten Sie auf die Fußzeile, denn dort steckt eine echte Falle.

4:31 Ohne eigenes Schema würden beide Umgebungen im pg-Backend denselben Standardeintrag verwenden und sich damit doch wieder einen State teilen. Alles, was wir im ersten Kapitel an Trennung aufgebaut haben, wäre mit einer fehlenden Zeile dahin. Gerade bei geteilten Backends lohnt ein zweiter Blick auf diese Kleinigkeit. Die Werte selbst stehen in Variablendateien, eine je Umgebung. Die Datei terraform.tfvars wird automatisch geladen, weitere lassen sich ausdrücklich angeben.

4:59 Interessant ist, was man hier sieht: Der Test läuft mit einem Release-Kandidaten des API-Images und einem einzigen Standort, die Produktion mit der aktuellen stabilen Version und allen drei Standorten der Gärtnerei. Das ist der ganze Unterschied, und er ist auf einen Blick lesbar. Die Fußzeile sagt, warum das so wertvoll ist.

5:19 Wer wissen will, wie sich test und prod unterscheiden, vergleicht zwei kleine Dateien. Bei kopierten Konfigurationen müsste er dafür hunderte Zeilen nebeneinanderlegen und hoffen, nichts zu übersehen. Diese Stolpersteine erzählen eigentlich eine einzige Geschichte. Sie beginnt harmlos: Die Produktion wird aus dem Testverzeichnis kopiert und kurz angepasst.

5:40 Ein paar Monate später sind es zwei eigenständige Konfigurationen, und ein Fix landet nur in der einen, weil niemand mehr weiß, dass es eine Kopie gibt. Der dritte Punkt ist die subtilere Variante: Die Unterschiede wandern als Bedingungen ins Modul, statt als Werte in die Variablendateien. Dann ist das Modul voller Sonderfälle.

5:59 Und der vierte Punkt ist die Kehrseite des gemeinsamen Moduls: Mit lokalem Modulpfad trifft jede Änderung beide Umgebungen zugleich. Das spricht für versionierte Module, wie wir sie in Modul fünf besprochen haben.

Mehrere Ziele ansprechen

6:12 Bisher spricht jedes Root Module genau einen Docker-Host an. Manchmal aber muss eine einzige Konfiguration zwei Ziele zugleich bedienen. Dafür gibt es ein kleines, aber wichtiges Sprachmittel. Getrennte Root Modules kommen meist mit einer einzigen Provider-Konfiguration aus. Verwaltet eine Konfiguration dagegen zwei Ziele, braucht es einen zweiten Provider-Block, und der bekommt einen alias, einen Zweitnamen.

6:38 Stellen Sie sich zwei Telefonleitungen auf demselben Schreibtisch vor, eine davon mit Etikett. Wer nichts angibt, telefoniert über die Standardleitung. Wer die andere will, wählt sie ausdrücklich. Ressourcen tun das über das Meta-Argument provider, Module bekommen die passende Konfiguration über providers übergeben. Das Prinzip ist schlicht, und genau deshalb lohnt es sich, es sauber zu beherrschen.

7:02 Es taucht in jedem Projekt auf, das über eine einzige Region oder einen einzigen Host hinauswächst. Hier sehen Sie beide Leitungen nebeneinander. Der erste Provider-Block ohne alias ist die Standardkonfiguration und zeigt auf den Testhost. Der zweite trägt den Namen prod und zeigt auf den Produktionshost. Das Netz saatplan-netz wählt den Produktionsprovider ausdrücklich.

7:25 Worauf es ankommt: Ohne diese Angabe würde die Ressource stillschweigend auf dem Standardziel landen. Es gibt keine Warnung, nur ein Netz am falschen Ort. Die Fußzeile zeigt, wie dasselbe bei Modulen funktioniert. Der module-Block reicht dem Modul den gewünschten Provider unter dem Namen weiter, den das Modul erwartet. So bleibt das Modul selbst völlig unabhängig davon, welchen Host es am Ende trifft.

7:49 Diese Tabelle schlägt die Brücke zu den großen Cloud-Anbietern, denn das Muster ist überall dasselbe. Wo bei uns ein Docker-Host steht, steht bei AWS ein Account samt Region, bei Azure eine Subscription, bei Google Cloud ein Projekt samt Region. Die Details im Provider-Block heißen jeweils anders, die Idee bleibt identisch: je Ziel eine Provider-Konfiguration, mehrere Ziele über alias.

8:13 Und die Fußzeile enthält den Satz, auf den es ankommt. Die Zugänge stehen nicht in der Konfiguration, sondern kommen aus der Umgebung des Laufs. Wer das bei Docker gelernt hat, findet sich in jeder Cloud sofort zurecht. Größere Strukturen sind fast immer auch organisatorische Strukturen. Die Schichtung zeigt, wie sich das bei Saatplan sauber abbilden lässt.

8:35 Ganz oben legt das Netzwerkteam das Netz an und nennt seinen Namen als Output. Darunter betreibt das Plattformteam die Docker-Hosts und die State-Datenbank. Das Anwendungsteam rollt API und Web aus, liest das Netz aber nur. Entscheidend ist die unterste Schicht, die Übergabe. Das Anwendungsteam findet das Netz über eine Datenquelle nach seinem Namen, statt Schreibzugriff darauf zu bekommen.

8:58 Das ist wie eine Postadresse: Man muss sie kennen, um etwas zu liefern, aber man braucht keinen Schlüssel zum Haus.

Orchestrierung über mehrere Konfigurationen

9:05 Mit jedem zusätzlichen State wächst eine neue Frage: In welcher Reihenfolge laufen sie, und wer sorgt dafür? Spätestens hier lohnt sich ein Blick auf Werkzeuge, die diese Ordnung übernehmen. Getrennte States brauchen eine Reihenfolge. Erst entstehen Netz und Datenbank, dann die Anwendung, die beides nutzt. Formal heißt das: Die Abhängigkeiten zwischen den States müssen ein gerichteter Graph ohne Kreise bleiben. Das klingt nach Informatik-Vorlesung, ist aber ganz handfest.

9:34 Stellen Sie sich zwei Handwerker vor, von denen jeder erst anfangen will, wenn der andere fertig ist. Liest State A aus State B und B aus A, lässt sich keiner von beiden mehr von Grund auf aufbauen. Im Alltag fällt das niemandem auf, weil ja beide schon existieren. Bemerkt wird es erst beim Neuaufbau, also genau dann, wenn man es am wenigsten gebrauchen kann.

9:56 Für diese Ordnung gibt es zwei verbreitete Werkzeuge, und die Tabelle zeigt, dass sie aus verschiedenen Welten kommen. Terraform Stacks sind eine Konfigurationsschicht von HCP Terraform. Sie laufen dort, beschreiben Bausteine als components und Umgebungen als deployments, und sie funktionieren nur mit Terraform. Terragrunt ist ein eigenständiges Werkzeug, das lokal und in jeder Pipeline läuft und mit OpenTofu ebenso arbeitet wie mit Terraform.

10:21 Die Entscheidung hängt also weniger an Funktionen als an der Plattform. Wer kein HCP Terraform nutzt oder mit OpenTofu arbeitet, für den stellt sich die Frage praktisch nicht, denn OpenTofu kennt kein Gegenstück zu Stacks. So sieht eine Terragrunt-Unit für die Anwendung in der Produktion aus. Sie bindet zuerst eine gemeinsame Wurzelkonfiguration ein, die sie in einem übergeordneten Verzeichnis sucht.

10:45 Dort steht, was alle Units teilen. Dann erklärt sie eine Abhängigkeit zur Unit mit den Daten und übernimmt deren Output als Eingabe. Damit ist die Reihenfolge nicht mehr Wissen im Kopf eines Kollegen, sondern steht in der Datei. Die Fußzeile beschreibt den Effekt: Ein einziger Befehl plant oder rollt alle Units aus und hält sich dabei an die Abhängigkeiten.

11:05 Erst kommen die Daten, dann die Anwendung, ohne dass jemand die Reihenfolge von Hand einhalten muss. Der erste Stolperstein ist der Kreis aus der Definition, ganz konkret gebaut: Zwei States lesen sich gegenseitig über die Datenquelle terraform remote state, und ein Neuaufbau ist unmöglich. Der zweite ist ein Reihenfolgefehler im Projekt. Terragrunt wird eingeführt, bevor die State-Grenzen geklärt sind.

11:29 Das Werkzeug ordnet aber nur, was schon geschnitten ist, die Architekturarbeit nimmt es Ihnen nicht ab. Der dritte ist eine Planungsfalle: Stacks werden eingeplant, obwohl das Team kein HCP Terraform nutzt. Und der vierte betrifft Platzhalter-Outputs für noch nicht existierende Abhängigkeiten. Begrenzen Sie sie auf validate und plan, sonst rutschen erfundene Werte bis in einen echten Apply.

Übung

11:53 Jetzt sind Sie der Architekt. In dieser Übung schneiden Sie Saatplan in Test und Produktion und entscheiden, wo die Grenzen verlaufen. Diese Übung ist eine Entwurfsaufgabe, und darin liegt ihr Reiz. Es gibt nicht die eine richtige Lösung, aber es gibt gut und schlecht begründete. Geübt wird die Fähigkeit, State- und Berechtigungsgrenzen nach Lebenszyklus, Zuständigkeit und Schadensradius festzulegen und sie gegenüber dem Team zu vertreten.

12:19 Fertig sind Sie, wenn test und prod je ein eigenes Root Module mit eigenem State und eigenem Docker-Host haben, jede Grenze begründet ist und kein State einen anderen zurückliest. Wer noch Zeit hat, skizziert dieselbe Struktur zusätzlich als Terragrunt-Units. Dann zeigt sich schnell, ob die gewählten Grenzen auch in der Reihenfolge tragen.

12:39 Der Weg führt vom Kleinen ins Große. Zuerst gruppieren Sie die Ressourcen von Saatplan nach Lebenszyklus und Zuständigkeit. Daraus ergeben sich die States je Umgebung und ihre Reihenfolge. Dann entwerfen Sie die beiden Umgebungsverzeichnisse mit Backend, Provider und Variablendatei. Halten Sie je State fest, wer lesen und wer ändern darf, und prüfen Sie den Graph der Übergaben auf Kreise.

13:02 Und nehmen Sie die Fußzeile ernst: Schreiben Sie die Entscheidung gegen Workspaces in zwei Sätzen auf. Diese Frage kommt wieder. Im nächsten Modul geht es dann um Infrastruktur, die schon existiert, bevor Terraform sie kennt, und darum, wie man sie übernimmt und umbaut.

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

Als Team-Schulung anfragenWie eine Schulung abläuft →