Handbuch - TF-PRO HashiCorp Terraform Authoring and Operations Professional
Zuletzt überprüft: Mai 2026
Eine übersichtliche Referenz der Architekturmuster, die in der TF-PRO-Prüfung getestet werden. Von oben nach unten lesen oder zu einem Abschnitt springen.
HCL und Konfiguration
Eine Ressource benötigt eine variable Anzahl identischer verschachtelter Blöcke (z. B. Ingress-Regeln), die von einer Liste/Map gesteuert werden.
Verwenden Sie einen `dynamic`-Block, dessen `for_each` die Sammlung iteriert; referenzieren Sie jedes Element über den Block-Iterator (Standardname = Blocklabel) innerhalb von `content {}`.
Warum: Dynamische Blöcke generieren wiederholte verschachtelte Blöcke ohne Copy-Paste; der Iterator bindet jeden generierten Block an sein Ursprungselement.
Erstellen Sie eine Ressource pro Eintrag in einer Map von Objekten, stabil schlüsselbasiert, sodass eine Neuanordnung niemals einen Ersatz erzwingt.
Setzen Sie `for_each = var.objects` (eine Map). Verwenden Sie `each.key` für den stabilen Schlüssel und `each.value.<attr>` für Felder. Vermeiden Sie hier `count` - Indexverschiebungen verursachen unnötige Änderungen.
Warum: Map-Schlüssel sind stabile Identitäten im Zustand; Listenindizes sind positionsbezogen und verschieben sich, wenn Elemente hinzugefügt/entfernt werden.
Entscheiden Sie zwischen count und for_each für mehrere Instanzen.
Verwenden Sie `for_each`, wenn Instanzen unterschiedliche Identitäten haben (ein Set/Map); verwenden Sie `count` nur für N identische, reihenfolge-unempfindliche Kopien. Bevorzugen Sie for_each für alles, was wachsen oder schrumpfen kann.
Warum: for_each adressiert nach Schlüssel (resource["key"]); count adressiert nach Index (resource[0]), was sich bei Einfügungen/Löschungen neu anordnet.
Eine Eingabevariable ist ein Objekt, bei dem einige Attribute optional sind und Standardwerte benötigen.
Typisieren Sie es als `object({ name = string, size = optional(number, 10) })`. `optional(type, default)` liefert den Standardwert, wenn der Aufrufer das Attribut weglässt.
Warum: optional() mit einem Standardwert hält Aufrufer prägnant und garantiert gleichzeitig einen konkreten Wert nachgelagert - kein Null-Handling überall.
Validieren Sie eine Annahme über eine Ressource vor dem Anwenden oder garantieren Sie ein Ergebnis danach.
Verwenden Sie `lifecycle { precondition { ... } }`, um Eingaben vor dem Erstellen/Aktualisieren zu prüfen, und `postcondition`, um Ausgaben danach zu prüfen. Beide akzeptieren `condition` + `error_message`.
Warum: Benutzerdefinierte Bedingungen schlagen schnell mit einer klaren Meldung fehl, anstatt einen fehlerhaften Apply oder einen verwirrenden nachgelagerten Fehler zu erzeugen.
Eine Ressource muss neu erstellt werden, wann immer eine andere Ressource oder ein Attribut geändert wird.
Fügen Sie `lifecycle { replace_triggered_by = [aws_x.y.id] }` hinzu. Wenn sich der referenzierte Wert ändert, erzwingt Terraform den Ersatz dieser Ressource.
Warum: Drückt eine Ersatz-Abhängigkeit deklarativ aus und vermeidet manuelles `-replace` bei jeder zugehörigen Änderung.
Das Ersetzen einer Ressource führt zu Ausfallzeiten, da die alte zerstört wird, bevor die neue existiert.
Setzen Sie `lifecycle { create_before_destroy = true }`, damit Terraform zuerst den Ersatz bereitstellt und dann den alten zerstört. Stellen Sie eindeutige Namen/keine harten Konflikte sicher.
Warum: Ersatz ohne Ausfallzeiten; achten Sie jedoch auf Namenskollisionen und Quotenlimits, während beide kurzzeitig existieren.
Ungültige Eingabewerte frühzeitig ablehnen (z. B. eine Umgebung, die nicht dev/stage/prod ist).
Fügen Sie einen `validation { condition = contains(["dev","stage","prod"], var.env), error_message = "..." }`-Block zur Variable hinzu.
Warum: Fängt fehlerhafte Eingaben zur Planzeit mit einer lesbaren Meldung ab, anstatt tief in einem Provider-Aufruf zu scheitern.
Referenzieren Sie einen Wert, der möglicherweise nicht existiert, ohne den Plan abstürzen zu lassen.
Verwenden Sie `try(local.maybe.value, "default")`, um bei Fehlern zurückzufallen, oder `can(expr)`, um einen Booleschen Wert zu erhalten, ob ein Ausdruck erfolgreich ist.
Wandeln Sie eine Liste in eine Map um oder filtern/formen Sie eine Sammlung für ein Ressourcenargument.
Verwenden Sie einen `for`-Ausdruck: `{ for u in var.users : u.name => u.role if u.active }` (Map) oder `[for x in list : upper(x)]` (Liste).
Warum: for-Ausdrücke sind der idiomatische Weg, Daten umzugestalten; die `if`-Klausel filtert, die Form `k => v` erstellt Maps.
Eine Variable oder Ausgabe enthält ein Geheimnis, das nicht im Plan/Apply-Output erscheinen sollte.
Markieren Sie die Variable als `sensitive = true` (und auch Ausgaben). Terraform schwärzt sie im CLI-Output, obwohl sie weiterhin im Zustand gespeichert ist.
Warum: Verhindert unbeabsichtigte Offenlegung in Logs/CI-Output; der Zustand selbst muss weiterhin geschützt werden (verschlüsseltes Backend, Zugriffskontrolle).
Ressourcen in zwei Regionen/Accounts innerhalb einer Konfiguration verwalten.
Deklarieren Sie aliased Provider (`provider "aws" { alias = "west" region = "us-west-2" }`) und setzen Sie `provider = aws.west` für Ressourcen oder übergeben Sie sie an Module.
Warum: Aliase ermöglichen einer Konfiguration, mehrere Provider-Instanzen anzusprechen; Module empfangen sie explizit über das `providers`-Argument.
Eine versteckte Abhängigkeit (nicht durch Referenzen ausgedrückt) verursacht Reihenfolgeprobleme.
Fügen Sie `depends_on = [aws_iam_role_policy.x]` hinzu, um die Reihenfolge zu erzwingen. Sparsam verwenden - bevorzugen Sie implizite Abhängigkeiten über Attributreferenzen.
Warum: Explizites depends_on behandelt Abhängigkeiten, die der Graph nicht ableiten kann, aber übermäßiger Gebrauch führt zu konservativen, langsameren Plänen.
Eine Konfigurationsdatei/Benutzerdaten aus einer Vorlage mit strukturierten Variablen rendern.
Verwenden Sie `templatefile("${path.module}/tpl.tftpl", { items = local.items })`; die Vorlage verwendet `%{ for } / ${}`-Interpolation.
Warum: templatefile hält das Rendering rein/zur Planzeit (im Gegensatz zum veralteten Template-Provider) und unterstützt Schleifen/Bedingungen.
Erstellen Sie eine flache Liste jeder (Subnetz, Regel)-Kombination, um einen einzelnen for_each zu versorgen.
Verwenden Sie `setproduct(var.subnets, var.rules)` für das Kreuzprodukt oder `flatten([for ...])`, um verschachtelte Listen zu einer zusammenzufassen.
Warum: Diese Funktionen wandeln verschachtelte Daten in die flache, eindeutig schlüsselbare Sammlung um, die for_each benötigt.
Module
Ein Registry-Modul ändert sich und verändert unerwartet die Infrastruktur beim nächsten Init.
Mit `version = "~> 4.2"` festlegen (nur Registry-Module). Für Git-Quellen einen `?ref=v4.2.0`-Tag festlegen. Führen Sie `terraform init -upgrade` bewusst aus, um Fixierungen zu verschieben.
Warum: Nicht festgelegte Module verwenden die neueste Version; das Festlegen macht Upgrades beabsichtigt und überprüfbar.
Ein Root-Modul benötigt einen Wert, der tief innerhalb eines Kindmoduls erzeugt wird.
Geben Sie es als `output` im Kindmodul frei und referenzieren Sie dann `module.child.output_name`. Werte, die nicht ausgegeben werden, sind für Aufrufer nicht zugänglich.
Warum: Module sind gekapselt; Ausgaben sind der einzige Weg, wie Daten die Modulgrenze nach oben überschreiten können.
Instanziieren Sie dasselbe Modul einmal pro Team/Umgebung aus einer Map.
Setzen Sie `for_each` auf den Modulblock: `module "env" { for_each = var.envs; source = "./env"; name = each.key }`. Referenzieren Sie `module.env["prod"]`.
Warum: for_each auf Modulen skaliert ein Muster ohne das Kopieren von Blöcken; Schlüssel bieten stabile Adressen.
Ein Kindmodul muss Ressourcen in einem nicht standardmäßigen (aliased) Provider erstellen.
Provider explizit übergeben: `module "x" { providers = { aws = aws.west } }`. Das Kindmodul deklariert den Provider in `required_providers` mit `configuration_aliases`.
Warum: Module erben aliased Provider nicht implizit; die Provider-Map verbindet den Eltern-Alias mit dem Kind.
Das Umbenennen einer Ressource oder das Verschieben in ein Modul würde normalerweise diese zerstören und neu erstellen.
Fügen Sie einen `moved { from = aws_instance.old; to = module.compute.aws_instance.new }`-Block hinzu. Terraform aktualisiert die Zustandadressen ohne Zerstörung.
Warum: moved-Blöcke machen Refactorings im Code sicher und überprüfbar, indem sie das manuelle `terraform state mv` ersetzen.
Ein monolithisches Modul ist unübersichtlich geworden und vermischt Netzwerk-, Compute- und Datenbelange.
Zerlegen Sie es in fokussierte Kindmodule und komponieren Sie diese in einem Root-Modul, wobei die Ausgaben eines Moduls als Eingaben für das nächste dienen. Halten Sie Module auf einen einzigen Zweck ausgerichtet.
Warum: Komposition verbessert Wiederverwendbarkeit und Testbarkeit; eng gefasste Module versionieren und entwickeln sich unabhängig voneinander.
Verbraucher übergeben ungültige Kombinationen von Eingaben an ein gemeinsam genutztes Modul.
Fügen Sie `validation`-Blöcke und `precondition`s innerhalb des Moduls hinzu, um Verträge durchzusetzen, und dokumentieren Sie Eingaben mit `description`.
Warum: Ein Modul besitzt seinen Vertrag; die Validierung im Inneren schützt jeden Aufrufer, nicht nur eine Root-Konfiguration.
Tief verschachtelte Module erschweren es, den Datenfluss und die Provider-Übergabe nachzuvollziehen.
Halten Sie die Verschachtelung flach (1-2 Ebenen). Übergeben Sie Provider und Schlüsseleingaben explizit auf jeder Ebene; vermeiden Sie es, sich auf tiefe implizite Vererbung zu verlassen.
Warum: Flache Bäume sind leichter zu verstehen; tiefe Verschachtelung erhöht die Komplexität der Provider-Übergabe und der Output-Verkabelung.
Ein wiederverwendbares Modul in der privaten Registry veröffentlichen und weiterentwickeln, ohne Aufrufer zu beeinträchtigen.
Veröffentlichen Sie Versionen mit Semver (`v1.2.0`); brechende Änderungen bei Eingaben/Ausgaben erhöhen die Hauptversion. Aufrufer fixieren mit `~>`-Einschränkungen.
Warum: Semantische Versionierung ermöglicht es Konsumenten, Fixes/Funktionen sicher zu übernehmen und bewusst breaking changes zu wählen.
Wählen Sie, woher ein Modul für ein gegebenes Reifegrad bezogen werden soll.
Lokale Pfade (`./modules/x`) für im Repo, Git (`git::...?ref=tag`) für geteilte, aber unveröffentlichte, Registry (`namespace/name/provider`) für versionierte/veröffentlichte Module.
Warum: Der Quelltyp entspricht dem Freigabebereich; nur Registry-Quellen unterstützen das `version`-Argument und die Auflösung von Einschränkungen.
Eine Modulausgabe enthält ein Geheimnis, das vom Root-Modul verwendet wird.
Markieren Sie die Modulausgabe als `sensitive = true`. Die Verwendung in einem nicht-sensitiven Kontext führt zu einem Fehler, bis Sie sie ebenfalls als sensitiv behandeln.
Warum: Sensitivität breitet sich über die Modulgrenze aus und verhindert unbeabsichtigte Lecks im Root-Output.
Ein bestehender Count-basierter Ressourcensatz muss zu for_each werden, ohne Instanzen zu zerstören.
Fügen Sie `moved`-Blöcke hinzu, die jeden `resource[0]`-Index der neuen `resource["key"]`-Adresse zuordnen, und wechseln Sie dann zu for_each.
Warum: moved-Blöcke ändern die Schlüssel des Zustands von positionsbezogener zu identitätsbasierter Adressierung, wodurch Zerstörung/Neuerstellung vermieden wird.
CLI und Zustandsverwaltung
Sie haben eine Ressource in der Konfiguration umbenannt; der Plan möchte nun die alte zerstören und eine neue erstellen.
Bevorzugen Sie einen `moved`-Block in der Konfiguration. Für Ad-hoc-/CLI-Fixes verwenden Sie `terraform state mv aws_x.old aws_x.new`, um auf das bestehende Objekt umzuzielen.
Warum: Beide aktualisieren die Zustandsadresse, sodass Terraform das bestehende Objekt als die umbenannte Ressource erkennt - keine Zerstörung.
Eine bestehende, manuell erstellte Ressource unter Terraform-Verwaltung bringen.
Fügen Sie einen `import { to = aws_x.y; id = "i-123" }`-Block hinzu und führen Sie `terraform plan -generate-config-out=gen.tf` aus, um die Konfiguration zu erstellen, dann verfeinern und anwenden.
Warum: Konfigurationsgesteuerter Import ist überprüfbar und generiert eine Startkonfiguration, im Gegensatz zum älteren imperativen `terraform import`.
Eine Ressource nicht mehr mit Terraform verwalten, sie aber in der Cloud weiterlaufen lassen.
Führen Sie `terraform state rm aws_x.y` aus. Terraform vergisst das Objekt; es wird nicht zerstört. Entfernen Sie auch dessen Konfiguration, um einen erneuten Erstellungsplan zu vermeiden.
Warum: state rm trennt, ohne zu löschen - nützlich, wenn eine Ressource an ein anderes Tool/Team übergeben wird.
Zustand von einem lokalen Backend nach S3 (oder zu HCP Terraform) verschieben.
Fügen Sie den `backend`/`cloud`-Block hinzu/ersetzen Sie ihn, führen Sie `terraform init` aus - Terraform erkennt die Änderung und fordert Sie auf, den bestehenden Zustand zum neuen Backend zu migrieren.
Warum: init orchestriert das Kopieren; die Beantwortung mit Ja migriert den Zustand sicher, anstatt leer zu starten.
Zwei Ingenieure führen gleichzeitig apply auf denselben Remote-Zustand aus.
Verwenden Sie ein Backend, das Locking unterstützt (S3+DynamoDB, HCP Terraform usw.). Terraform erwirbt pro Operation eine Sperre; der zweite Durchlauf wartet oder meldet einen Fehler.
Warum: Locking verhindert gleichzeitige Schreibvorgänge, die den Zustand beschädigen würden. Deaktivieren Sie es niemals leichtfertig.
Ein abgestürzter Apply hat eine veraltete Sperre hinterlassen und nun ist jeder Durchlauf blockiert.
Bestätigen Sie, dass keine Operation tatsächlich läuft, dann `terraform force-unlock <LOCK_ID>`. Verwenden Sie die ID aus der Fehlermeldung.
Warum: force-unlock löscht eine verwaiste Sperre; dies während einer laufenden Operation zu tun, birgt das Risiko einer Zustandsbeschädigung.
Drift zwischen Konfiguration/Zustand und realer Infrastruktur erkennen, ohne Änderungen vorzuschlagen.
Führen Sie `terraform plan -refresh-only` (oder `apply -refresh-only`, um den Zustand zu aktualisieren) aus. Es meldet Unterschiede, ohne Ressourcenänderungen zu planen.
Warum: Trennt die Drift-Erkennung von der Änderungsplanung - Sie sehen, was sich in der Cloud geändert hat, bevor Sie sich für eine Abstimmung entscheiden.
Eine Ressource verhält sich fehlerhaft und Sie möchten sie neu erstellen, ohne die Konfiguration zu bearbeiten.
Führen Sie `terraform apply -replace="aws_instance.web"` aus. Dies ist der moderne Ersatz für das veraltete `terraform taint`.
Warum: -replace zwingt die Zerstörung und Neuerstellung einer Ressource beim nächsten Apply, deklarativ an der CLI.
Sie sind versucht, -target routinemäßig zu verwenden, um Applies zu beschleunigen.
Verwenden Sie `-target` nur zur Fehlerbehebung oder für gezielte Korrekturen. Vermeiden Sie es als normalen Workflow - es erzeugt partielle Applies und kann Abhängigkeiten überspringen.
Warum: Routinemäßiges Targeting verbirgt Abhängigkeitsprobleme und führt zu einem unvollständigen Zustand; HashiCorp dokumentiert es als außergewöhnliches Werkzeug.
Ein Provider hat den Namespace gewechselt (z. B. hashicorp/aws zu einem Fork) und der Zustand referenziert die alte Adresse.
Führen Sie `terraform state replace-provider registry.terraform.io/hashicorp/aws registry.example.com/org/aws` aus.
Warum: Schreibt Provider-Referenzen im Zustand um, damit init/plan die neue Quelle auflösen, ohne Ressourcen neu zu erstellen.
Eine Konfiguration benötigt Ausgaben, die von einer anderen Konfiguration/einem anderen Workspace erzeugt wurden.
Verwenden Sie die Datenquelle `terraform_remote_state` (oder HCP Terraform Run-Ausgaben), um die Ausgaben eines anderen Zustands schreibgeschützt zu lesen.
Warum: Teilt Werte über Zustandsgrenzen hinweg, ohne Ressourcen zu duplizieren; nur exportierte Ausgaben sind lesbar.
Backend-Einstellungen (Bucket, Key) unterscheiden sich pro Umgebung und sollten nicht fest kodiert werden.
Lassen Sie sie aus dem `backend`-Block heraus und übergeben Sie sie beim Init: `terraform init -backend-config=prod.hcl` (oder `-backend-config="key=..."`).
Warum: Partielle Konfiguration macht eine Konfiguration über Umgebungen hinweg wiederverwendbar, während umgebungsspezifische Backend-Werte beim Init bereitgestellt werden.
Sie benötigen einen separaten Zustand für dev/stage/prod aus einer Konfiguration.
Verwenden Sie CLI-Workspaces (`terraform workspace new prod`) für eine leichte Isolation oder separate Root-Konfigurationen/HCP-Workspaces für eine stärkere Trennung.
Warum: Jeder Workspace hat seinen eigenen Zustand; referenzieren Sie `terraform.workspace`, um Benennung/Größe zu variieren. Für starke Isolation bevorzugen Sie separate Backends/Workspaces.
HCP Terraform Operationen
Vermeiden Sie es, langlebige Cloud-Schlüssel in HCP Terraform Workspace-Variablen zu speichern.
Konfigurieren Sie dynamische Provider-Anmeldeinformationen: HCP Terraform verwendet OIDC/Workload-Identität, um kurzlebige Anmeldeinformationen von AWS/Azure/GCP/Vault pro Durchlauf zu erhalten.
Warum: Eliminiert statische Geheimnisse; Anmeldeinformationen werden Just-in-Time erstellt und laufen ab, wodurch der Schadenbereich verkleinert wird.
Dieselbe Variablen (Provider-Konfiguration, Tags) werden in vielen Workspaces benötigt.
Definieren Sie einen Variablensatz und wenden Sie ihn auf ein Projekt oder ausgewählte Workspaces an. Workspace-spezifische Variablen überschreiben die Werte des Variablensatzes.
Warum: Variablensätze vermeiden die Duplizierung gemeinsam genutzter Konfigurationen; die Präzedenz (Workspace > Set) ermöglicht es einem Workspace, bei Bedarf zu überschreiben.
Guardrails (kein öffentlicher S3, erforderliche Tags) bei jedem Durchlauf durchsetzen.
Fügen Sie einen Sentinel- oder OPA-Richtliniensatz hinzu. Legen Sie die Durchsetzungsstufe fest: beratend (Warnung), weich-obligatorisch (mit Genehmigung überschreiben) oder hart-obligatorisch (blockieren).
Warum: Policy-as-Code steuert Durchläufe zentral; Durchsetzungsstufen gleichen Strenge mit operativer Flexibilität ab.
Eine externe Prüfung (Kostenschätzung, Sicherheitsscan) in die Run-Pipeline integrieren.
Konfigurieren Sie eine Run-Task in einer Phase (Pre-Plan, Post-Plan, Pre-Apply). HCP Terraform ruft den externen Dienst auf und steuert den Run basierend auf dessen Ergebnis.
Warum: Run-Tasks erweitern die Pipeline um Drittanbieter-Checks ohne benutzerdefinierte CI-Implementierung.
Wählen Sie, wie Runs für einen Workspace ausgelöst werden.
VCS-gesteuert (Commit/PR löst Plan aus), CLI-gesteuert (`terraform plan/apply` gegen Remote) oder API-gesteuert (hochgeladene Konfiguration). Wählen Sie pro Team-Workflow.
Warum: VCS-gesteuert passt zu GitOps; CLI-gesteuert passt zur lokalen Iteration; API-gesteuert passt zu benutzerdefinierten Pipelines. Sie schließen sich pro Workspace gegenseitig aus.
Einem Team Schreibzugriff auf Staging-Workspaces, aber schreibgeschützten Zugriff auf die Produktion gewähren.
Berechtigungen auf Organisations-/Projekt-/Workspace-Ebene festlegen: Teamzugriff (Lesen/Planen/Schreiben/Admin) pro Projekt oder Workspace zuweisen; Projektgruppierung zur Verwaltung in großem Umfang nutzen.
Warum: Granulare, bereichsbezogene Berechtigungen setzen das Prinzip der geringsten Rechte durch; Projekt-Ebene-Zuweisungen reduzieren die Workspace-spezifische Verwaltung.
Ein Apply eines Netzwerk-Workspaces sollte automatisch einen Run in abhängigen App-Workspaces in die Warteschlange stellen.
Konfigurieren Sie einen Run-Trigger: Der nachgeschaltete Workspace abonniert den vorgeschalteten; ein erfolgreicher Apply stellt den nachgeschalteten Run in die Warteschlange.
Warum: Run-Trigger verketten abhängige Workspaces, damit Änderungen an der gemeinsamen Infrastruktur der Reihe nach verbreitet werden.
Nicht-Terraform-Benutzern ermöglichen, standardisierte Infrastruktur über ein Formular bereitzustellen.
Veröffentlichen Sie ein No-Code-Modul in der privaten Registry; Benutzer instanziieren es über die UI, wobei nur Eingaben bereitgestellt werden - keine HCL-Erstellung.
Warum: No-Code-Module demokratisieren die Self-Service-Bereitstellung, während die zugrunde liegende Konfiguration verwaltet und versioniert bleibt.
Geprüfte Module und Provider organisationsweit teilen.
Veröffentlichen Sie in der privaten HCP Terraform Registry; Konsumenten referenzieren `app.terraform.io/org/name/provider` mit Versionsbeschränkungen.
Warum: Eine private Registry zentralisiert die Erkennung, Versionierung und Governance interner Module.
Dutzende von Workspaces nach Team/Anwendung für Berechtigungen und Variablensätze organisieren.
Gruppieren Sie Workspaces in Projekte; wenden Sie Teamberechtigungen und Variablensätze auf Projektebene an.
Warum: Projekte skalieren die Governance - Sie verwalten den Zugriff und die gemeinsame Konfiguration pro Projekt statt pro Workspace.
Kontinuierlich erkennen, wenn die Produktion vom konfigurierten Zustand abweicht.
Aktivieren Sie Gesundheitsbewertungen (Drift-Erkennung / kontinuierliche Validierung) für den Workspace; HCP Terraform aktualisiert und meldet regelmäßig Abweichungen und fehlgeschlagene Zusicherungen.
Warum: Automatisierte Bewertungen decken Drift und fehlerhafte Postconditions zwischen Applies auf, bevor sie Vorfälle verursachen.
HCP Terraform muss Infrastruktur innerhalb eines privaten Netzwerks ohne öffentlichen Ingress erreichen.
Stellen Sie HCP Terraform Agents im privaten Netzwerk bereit und weisen Sie den Workspace einem Agent-Pool zu; Runs werden über den Agent ausgeführt.
Warum: Agents ermöglichen es HCP Terraform, in privaten/air-gapped Umgebungen zu operieren, ohne diese öffentlich zugänglich zu machen.
Ein fehlerhafter Apply hat den Zustand beschädigt und Sie müssen ihn wiederherstellen.
HCP Terraform speichert versionierten Zustand; setzen Sie auf eine frühere Zustandsversion über die Workspace-UI/API zurück und planen Sie neu.
Warum: Die integrierte Zustandsversionierung bietet Wiederherstellungspunkte, ohne dass Sie Backend-Snapshots selbst verwalten müssen.