Start / Seminare / Terraform und OpenTofu in der Praxis
Modul
CLI-Workflow und Projektstruktur
Modul 2 von 14 aus dem Seminar Terraform und OpenTofu in der Praxis
6 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.
CLI-Workflow und Projektstruktur
0:00 Im ersten Modul ging es um Begriffe und Bausteine. Jetzt wird es praktisch: Wir arbeiten an der Kommandozeile. Und gleich vorweg die wichtigste Unterscheidung dieses Moduls. Prüfen, planen und ausführen sind drei verschiedene Tätigkeiten, und nur die letzte verändert tatsächlich etwas. Wer das verinnerlicht, verliert die Scheu vor dem Werkzeug — und bekommt gleichzeitig Respekt vor dem einen Befehl, der zählt.
0:24 Wir legen fest, mit welcher Version das Team arbeitet, sehen uns an, wie Provider geladen und festgenagelt werden, durchlaufen den Kernzyklus und speichern Pläne so, dass genau das angewendet wird, was geprüft wurde. Am Ende steht Saatplan zum ersten Mal als laufende Anwendung da.
CLI-Workflow und Projektstruktur
0:41 Nach der Einordnung kommt das Handwerk. In diesem Modul entsteht das Repository saatplan-infra, das uns durch das ganze Seminar begleitet. Wir legen seine Struktur an, lernen die Befehle, mit denen man es bearbeitet, und schauen auch auf Umgebungen, in denen das Netz knapp ist. Danach wird ausgerollt, geändert und wieder abgebaut.
Werkzeug und Version festlegen
1:02 Bevor die erste Ressource entsteht, braucht ein Projekt eine Antwort auf eine banale Frage: Mit welcher Version arbeiten wir eigentlich? Die Frage klingt banal, ihre Folgen sind es nicht. Stellen Sie sich ein Orchester vor, in dem jede Musikerin eine andere Ausgabe der Partitur auf dem Pult hat. Es klingt fast richtig, aber eben nur fast.
1:22 Genauso geht es einem Team, in dem jeder eine andere CLI-Version installiert hat: Die Pläne unterscheiden sich, und am Ende streiten sich die Versionen um den State. Deshalb gehört die Version ins Projekt, nicht in den Zufall. Installiert wird eine festgelegte Version, nicht einfach die neueste. Und die Konfiguration selbst prüft, ob die CLI passt — mit einer klaren Meldung gleich am Anfang statt eines Abbruchs mitten im Lauf.
1:48 Dazu kommt Editor-Unterstützung, die beide Projekte liefern. Diese kleine Datei ist der Vertrag des Projekts mit seinen Werkzeugen. Oben steht, welche CLI-Version mindestens erwartet wird. Darunter die Provider, die das Projekt braucht — hier der Docker-Provider mit seiner Quelle und einer Versionsangabe, die Version 4.6 und kompatible Folgeversionen erlaubt.
2:10 Das ist bewusst ein Rahmen, keine exakte Nummer. Welche Version tatsächlich installiert wird, entscheidet eine andere Datei, zu der wir gleich kommen. Ein Hinweis für alle, die beide Werkzeuge im Blick haben: OpenTofu kann eine eigene Variante dieser Datei lesen. Das ist nötig, weil die Versionsnummern von Terraform und OpenTofu nicht vergleichbar sind.
2:32 Diese Tabelle beantwortet zwei Fragen auf einmal: Was gehört wohin, und was gehört ins Repository? Die Aufteilung in versions, providers, main und outputs ist reine Konvention. Das Werkzeug liest alle Dateien eines Verzeichnisses ohnehin als eine einzige Konfiguration. Die Aufteilung hilft also Menschen, nicht der Maschine.
2:51 Wichtiger ist die rechte Spalte. Das Lock File gehört ins Repository, obwohl es automatisch entsteht. Der Ordner mit heruntergeladenen Providern dagegen nicht, ebenso wenig der lokale State und gespeicherte Pläne. Bei den beiden letzten ist das keine Ordnungsfrage, sondern eine der Sicherheit: Sie können Geheimnisse enthalten.
Provider-Quellen und Dependency Lock File
3:12 Die Versionsangabe eben war ein Rahmen. Jetzt geht es um die Datei, die innerhalb dieses Rahmens tatsächlich entscheidet — und darum, warum sie ins Review gehört. Das Lock File ist so etwas wie der Kassenbon eines Einkaufs. Auf dem Einkaufszettel stand: Docker-Provider, Version 4.6 oder kompatibel. Auf dem Bon steht, was tatsächlich gekauft wurde — genaue Version und Prüfsummen.
3:36 Und solange der Bon existiert, kauft init beim nächsten Mal exakt dasselbe, auch wenn im Regal inzwischen eine neuere erlaubte Version liegt. Erst wer ausdrücklich ein Upgrade anfordert, wählt neu. Module stehen übrigens nicht auf diesem Bon. Der größte Gewinn liegt im Review: Weil die Datei im Repository liegt, wird jeder Versionswechsel eines Providers als Änderung sichtbar, statt still auf irgendeinem Rechner zu passieren.
4:02 Hier zeigt sich ein Problem, das erst im Team auffällt. Die Prüfsummen im Lock File hängen von der Plattform ab. Wer auf einem Mac init ausführt, schreibt zunächst Prüfsummen für den Mac. Der Kollege unter Windows oder der Linux-Runner in der Pipeline steht dann vor einem Lock File, das nicht zu ihm passt. Die Lösung ist der Befehl providers lock, der die Prüfsummen für alle genannten Plattformen auf einmal einträgt.
4:26 Daneben sehen Sie init mit Upgrade, um im erlaubten Rahmen bewusst neu zu wählen. OpenTofu macht es ab Version 1.12 bequemer und schreibt die Prüfsummen aller Plattformen bereits bei init.
Der Kernzyklus
4:37 Projektstruktur und Versionen stehen. Jetzt kommt der Teil, den Sie künftig jeden Tag ausführen werden: ein fester Ablauf von Befehlen, der aus einer Beschreibung eine laufende Infrastruktur macht. Dieser Fluss ist der Herzschlag der Arbeit mit Terraform und OpenTofu. Zuerst init, das Vorbereiten: Provider laden, Backend einrichten.
4:57 Dann formatieren und validieren — das ist wie die Rechtschreibprüfung vor dem Abschicken eines Briefs, sie kostet nichts und verhindert Peinlichkeiten. Mit plan schaut das Werkzeug auf die Wirklichkeit und schlägt Änderungen vor. Erst apply setzt sie um. Und danach helfen show und output beim Nachschauen. Beachten Sie die Reihenfolge: Bis einschließlich plan verändert nichts die Welt. Sie können diese Schritte so oft ausführen, wie Sie wollen.
5:24 Der eine Schritt, der wirkt, kommt bewusst spät. Die rechte Spalte ist der Schlüssel zu dieser Tabelle. Sie zeigt, welcher Befehl den Docker-Daemon überhaupt berührt. Die meisten tun es nicht: init, fmt, validate, show und output arbeiten nur mit Dateien und State. Plan liest, verändert aber nichts. Nur zwei Befehle schreiben tatsächlich ins Zielsystem — apply und destroy. Diese Einteilung gibt Sicherheit. Wer unsicher ist, darf alles andere bedenkenlos ausprobieren.
5:55 Eine Eigenheit von fmt sollten Sie kennen: Es arbeitet nur im aktuellen Verzeichnis. Wer Unterordner hat, braucht den Schalter für rekursives Arbeiten, sonst bleiben Dateien unformatiert, ohne dass es jemand merkt. So sieht ein Plan aus, wenn jemand einen Port korrigiert. Die Ausgabe ist gekürzt, das Wesentliche steht aber da. Die Kopfzeile verrät: Der Container wird ersetzt, nicht geändert.
6:20 Weiter unten steht der Grund — die Änderung des externen Ports erzwingt den Austausch, im Plan markiert mit forces replacement. Und die Schlusszeile fasst zusammen: eines hinzu, eines weg. Bei einem Webcontainer ist das unproblematisch. Aber gewöhnen Sie sich vor jedem apply drei Fragen an. Was wird ersetzt? Was wird entfernt? Und ist das wirklich gewollt? Diese drei Fragen sind die billigste Versicherung, die es in der Infrastruktur gibt.
Gespeicherte Pläne und maschinenlesbare Ausgaben
6:49 Bisher haben wir geplant und dann angewendet. Aber wer garantiert, dass zwischen beiden nichts passiert? Gespeicherte Pläne schließen genau diese Lücke — und sie sind die Grundlage jeder ernsthaften Pipeline. Der Unterschied ist klein im Befehl und groß in der Wirkung. Ein einfaches apply berechnet einen neuen Plan, und der kann von dem abweichen, den jemand geprüft hat.
7:12 Mit einem gespeicherten Plan wird dagegen exakt das angewendet, was vorher angesehen wurde. Dazwischen liegen zwei Arten des Lesens: show für Menschen, show mit JSON-Ausgabe für Werkzeuge, etwa für automatische Prüfungen. Zwei Dinge sollten Sie wissen. Ein apply mit Plandatei fragt nicht mehr nach — die Freigabe hat ja schon stattgefunden. Und die Plandatei enthält sensible Werte im Klartext.
7:36 Sie ist also ein Dokument, das man behandelt wie ein Passwort. Für Menschen ist ein Plan ein Text, für eine Pipeline ist er eine Zahl. Und genau diese Zahl ist ohne den passenden Schalter wenig aussagekräftig: Standardmäßig meldet plan Erfolg, ob nun Änderungen ausstehen oder nicht. Die Pipeline weiß dann nicht, ob sie jemanden zur Freigabe rufen soll. Mit dem detaillierten Exit-Code bekommt jede Lage ihre eigene Zahl.
8:03 Null heißt: alles wie beschrieben, niemand muss schauen. Eins heißt: Fehler. Zwei heißt: Es gibt Änderungen, bitte prüfen. Damit wird aus einem Plan eine Entscheidungsgrundlage für Automatisierung. In Modul elf, bei den Pipelines, wird genau das wichtig. Die erste Falle ist eigentlich eine Schutzfunktion. Hat sich der State seit dem Planen geändert, lehnt apply den gespeicherten Plan als veraltet ab.
8:28 Das ärgert im Moment, verhindert aber, dass ein alter Plan auf eine neue Wirklichkeit trifft. Die zweite ist ernster: Plandateien und ihre JSON-Fassung landen im Repository und mit ihnen sensible Werte. Die dritte ist ein Missverständnis — die Plandatei ist binär, lesen tut man sie über show. Und wer sowohl Lesbares als auch JSON braucht, muss nicht doppelt planen: OpenTofu kann ab Version 1.12 beides in einem Lauf erzeugen.
Provider in eingeschränkten Umgebungen
8:55 Bisher sind wir davon ausgegangen, dass das Internet einfach da ist und der Docker-Host auf dem eigenen Rechner läuft. In vielen Unternehmen stimmt beides nicht. Sehen wir uns an, wie man damit umgeht. Zwei Werkzeuge helfen, wenn das Netz knapp ist. Der Cache ist wie ein Vorratsschrank: Ein Provider, der einmal heruntergeladen wurde, liegt bereit und muss nicht in jedem Projekt neu geholt werden.
9:18 Den Ordner dafür müssen Sie allerdings selbst anlegen. Der Spiegel geht weiter. Er ersetzt die öffentliche Registry durch ein lokales Verzeichnis, hier bei der Gärtnerei Lindenhof. Die Konfiguration legt fest, dass Provider aus dieser Quelle nur vom Spiegel kommen und nie direkt aus dem Internet. Gefüllt wird der Spiegel einmal auf einem Rechner mit Internetzugang, mit dem Befehl providers mirror. Diese Einstellungen gelten für den Rechner, nicht für ein einzelnes Projekt.
9:46 Nicht jede Infrastruktur läuft auf dem eigenen Laptop. Hier spricht der Provider per SSH mit einem entfernten Docker-Host der Testumgebung. Die SSH-Option sorgt dafür, dass keine interaktive Rückfrage den Lauf anhält — wichtig, sobald später eine Pipeline statt eines Menschen am Werk ist. Dazu kommt die Anmeldung an der eigenen Registry der Gärtnerei.
10:07 Hier lauert ein Detail, das gern übersehen wird: Die Zugangsdaten der Registry liest der Provider aus der Docker-Konfiguration des Rechners, auf dem terraform läuft — nicht des entfernten Hosts. Wer sich also wundert, warum ein Image nicht geladen werden kann, sollte zuerst dort nachsehen.
Übung
10:25 Jetzt wird es ernst. Die Zerlegung aus dem ersten Modul wird zu Code, und Saatplan läuft zum ersten Mal aus einer Konfiguration heraus — und verschwindet am Ende wieder. In dieser Übung durchlaufen Sie den ganzen Lebenszyklus einer Infrastruktur, von init bis destroy. Das Ziel ist aber nicht, Befehle abzutippen. Sie sollen an einem Plan ablesen können, ob eine Änderung nur anpasst oder ersetzt — die Fähigkeit, die Sie vor jedem apply in Ihrer Laufbahn brauchen werden.
10:53 Erfolgreich sind Sie, wenn der gespeicherte Plan zur Portkorrektur das Ersetzen der Weboberfläche zeigt und nach dem Abbau kein Saatplan-Objekt mehr übrig ist. Ein ehrlicher Hinweis: Das Datenbankpasswort steht vorerst als Übungswert in der Konfiguration. Das ist bewusst so, und in Modul sieben räumen wir es auf. Die Schritte bauen aufeinander auf wie Stockwerke. Zuerst das Fundament: Versionen und Provider festlegen, init ausführen und das Lock File committen.
11:21 Dann die Teile, die nach innen gehören — Netz, Volume und Datenbank, bewusst ohne nach außen geöffneten Port. Erst danach kommt die Weboberfläche, und mit ihr der volle Zyklus aus Formatieren, Prüfen, Planen und Anwenden. Der vierte Schritt ist das Herzstück: eine kleine Korrektur, die eine große Wirkung hat, und Sie erklären, warum. Zum Schluss wird alles abgebaut und nachgeprüft.
11:44 Achten Sie dabei auf den Hinweis zum Pfad des Datenbank-Volumes — er hat sich mit dem aktuellen Postgres-Image geändert. Die erste Falle ist tückisch, weil nichts fehlschlägt. Hängt man das Volume beim aktuellen Postgres-Image am alten Pfad ein, landen die Daten in einem anonymen Volume — alles läuft, nur nicht dort, wo man denkt.
12:05 Die zweite ist ein Merksatz: destroy entfernt auch das Volume samt Daten. In der Übung ist das gewollt, in der Produktion darf es nie beiläufig passieren. Die dritte kennen Sie schon: State und Plandatei gehören nicht in den Commit. Und die vierte ist der Klassiker — ein Port nur zum Testen, und die Datenbank ist von außen erreichbar. Im nächsten Modul sehen wir uns die Sprache HCL genauer an.
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