Eine Variable stark typisieren.
→Primitive: `string`, `number`, `bool`. Sammlungen: `list(<type>)`, `set(<type>)`, `map(<type>)`. Strukturell: `object({...})`, `tuple([...])`. Verwenden Sie `any` nur, wenn es wirklich polymorph ist.
Referenz↗
Den `environment` auf dev/staging/prod beschränken.
→`variable "environment" { validation { condition = contains(["dev","staging","prod"], var.environment); error_message = "..." } }`. Mehrere `validation`-Blöcke erlaubt; alle müssen bestehen.
Referenz↗
Ein Datenbankpasswort ausgeben, ohne dass es in `terraform output` erscheint.
→`output "db_password" { value = ...; sensitive = true }`. CLI zeigt `(sensitive value)`. Immer noch über `terraform output db_password` oder `-json` lesbar (absichtlich – für Skripte).
Referenz↗
Einen Wert einmal berechnen und über viele Ressourcen hinweg wiederverwenden.
→`locals { common_tags = merge(var.tags, { Project = var.project }) }`. Referenzieren als `local.common_tags`. Nicht von außerhalb des Moduls überschreibbar.
Referenz↗
Ein bestehendes AMI nachschlagen, ohne es zu verwalten.
→`data "aws_ami" "ubuntu" { most_recent = true; filter { ... } }`. Schreibgeschützt. Attribute referenzieren als `data.aws_ami.ubuntu.id`.
Referenz↗
N ähnliche Ressourcen erstellen – `count` oder `for_each` wählen.
→`for_each` (mit Map oder Set), wenn Elemente eine stabile Identität haben (Regionsnamen, Umgebungsschlüssel). `count` für "Ich brauche N Kopien, Reihenfolge ist egal, Identität ist nur ein Index". Hinzufügen/Entfernen in der Mitte von `count` führt zu Destroy/Recreate; `for_each` bewahrt die Identität.
Referenz↗
Eine Ressource pro Element in einer Liste von Strings erstellen.
→`for_each = toset(["a", "b", "c"])`. `each.key` und `each.value` ergeben beide den String. Für Maps: `for_each = var.users` — `each.key` = Map-Schlüssel, `each.value` = Map-Wert.
Referenz↗
Eine variable Anzahl verschachtelter Blöcke generieren (z.B. Ingress-Regeln).
→`dynamic "ingress" { for_each = var.rules; content { from_port = ingress.value.from; ... } }`. Das `iterator`-Argument kann den Iterator bei Bedarf umbenennen.
Referenz↗
Eine Liste von Attributen über alle Instanzen einer `count`-Ressource abrufen.
→`aws_instance.web[*].id` gibt eine Liste von IDs zurück. Funktioniert mit `count` und `for_each` (aber `for_each` erzeugt eine ungeordnete Map, also `values(aws_instance.web)[*].id`).
Referenz↗
Einen Wert basierend auf einer Bedingung setzen.
→Ternär: `var.is_prod ? 5 : 1`. Beide Zweige müssen denselben Typ erzeugen.
Referenz↗
Zwei Maps kombinieren; Werte der zweiten Map gewinnen bei Schlüsselkollision.
→`merge(local.defaults, local.overrides)`. Rechteste Map gewinnt. Nützlich für die Tag-Komposition.
Referenz↗
Einen Map-Wert mit einem Standardwert lesen, wenn der Schlüssel fehlt.
→`lookup(var.config, "region", "us-east-1")`. Gibt den Standardwert zurück, wenn der Schlüssel nicht vorhanden ist. Für tief optionale Strukturen bevorzugen Sie das optionale `try()`.
Referenz↗
Verschachtelte Listen in eine flache Liste umwandeln.
→`flatten([["a","b"], ["c"], [["d","e"]]])` → `["a","b","c","d","e"]`. Rekursives Abflachen von Listen; Reihenfolge wird beibehalten.
Referenz↗
Eine Terraform-Map in ein IAM-Policy-Dokument einbetten.
→`jsonencode({Version = "2012-10-17", Statement = [...]})`. Erzeugt einen JSON-String. Inverse: `jsondecode()`.
Referenz↗
Ein templated User-Data-Skript mit Werten aus Variablen rendern.
→`templatefile("init.sh.tpl", { region = var.region, env = var.env })`. Template verwendet `${region}`-Syntax. Neuere Alternative für statisches Rendern: `file()` + `format()`.
Referenz↗
Subnetz-CIDRs aus einem VPC-Bereich ausschneiden.
→`cidrsubnet("10.0.0.0/16", 8, 0)` → `10.0.0.0/24`. Erstes Argument = Parent, zweites = Bits zum Erweitern, drittes = Subnetznummer.
Referenz↗
Einen Wert lesen, der möglicherweise nicht existiert; auf einen Standardwert zurückgreifen.
→`try(yamldecode(file("config.yaml")), { defaults = true })`. Wertet von links nach rechts aus; gibt den ersten nicht fehlerhaften Ausdruck zurück.
Referenz↗
Über Dateien iterieren, die einem Glob-Muster entsprechen.
→`fileset(path.module, "configs/*.json")` gibt ein Set von Pfaden zurück. Kombinieren Sie dies mit `for_each`, um eine Ressource pro Datei zu verwalten.
Referenz↗
Derselbe Provider in zwei Regionen (z.B. AWS us-east-1 + us-west-2).
→Zwei `provider "aws" { alias = "..." }`-Blöcke. Ressourcen wählen sich über `provider = aws.us_west` ein. Module akzeptieren Aliase über `configuration_aliases`.
Referenz↗
Einen Shell-Befehl auf einer neu erstellten VM ausführen.
→`remote-exec` Provisioner innerhalb einer Ressource. Letztes Mittel – bevorzugen Sie Cloud-init, Benutzerdaten oder Konfigurationsmanagement. Provisioner werden nicht im State verfolgt und werden bei Drift nicht erneut ausgeführt.
Referenz↗
Einen Befehl ausführen, der keiner Cloud-Ressource entspricht (z.B. CLI-Aufruf).
→`resource "null_resource" "trigger" { triggers = { sha = sha1(file(".")) }; provisioner "local-exec" { command = "..." } }`. Wird erneut ausgeführt, wenn sich `triggers` ändern.
Referenz↗
Eine Laufzeitinvariante (z.B. Health-Endpunkt gibt 200 zurück) kontinuierlich überprüfen, ohne den Apply zu blockieren.
→`check "endpoint" { data "http" "h" { url = "..." }; assert { condition = data.http.h.status_code == 200; error_message = "..." } }`. Läuft bei Plan/Apply; Fehler ist eine Warnung, kein harter Fehler.
Warum: `check` erlaubt das Scoping von Datenquellen, die nur innerhalb des Checks verwendbar sind. `precondition`/`postcondition` sind harte Fehler bei Plan/Apply.
Referenz↗
Den Plan fehlschlagen lassen, wenn ein AMI zu alt ist.
→`lifecycle { precondition { condition = data.aws_ami.x.creation_date > "2024-01-01"; error_message = "..." } }`. Harter Fehler, wird je nach Bedarf vor/nachher ausgewertet.
Referenz↗
Variable mit einem positionalen Wert fester Form.
→`type = tuple([string, number, bool])` erfordert genau drei Elemente in dieser Reihenfolge. Anders als eine Liste (homogen, variable Länge).
Referenz↗
Einen strukturierten Input stark typisieren (z.B. `database = { instance_class = string, allocated_storage = number }`).
→`type = object({ instance_class = string, allocated_storage = number, multi_az = optional(bool, false) })`. `optional(<type>, <default>)` macht Attribute optional.
Referenz↗
Wie werden `*.tfvars`-Dateien geladen?
→`terraform.tfvars` und `*.auto.tfvars` laden automatisch (lexikalische Reihenfolge für `auto`). Andere Namen erfordern `-var-file=path.tfvars`.
Referenz↗
Automatisierte Tests für ein Terraform-Modul schreiben.
→`.tftest.hcl`-Dateien mit `run "name" { command = plan|apply, assert { condition = ..., error_message = ... } }`. `command = plan` ist ohne Nebenwirkungen; `command = apply` erstellt tatsächlich Ressourcen.
Referenz↗
Variablen in Testläufe übergeben.
→Dateiebene `variables { ... }`-Block gilt für alle Läufe. Pro-Lauf `variables { ... }` überschreibt nur für diesen Lauf.
Referenz↗