Testinfrastrukturcode
Wir testen Anwendungscode. Warum nicht die Infrastruktur? Die Werkzeuge und die Kompromisse.
Wir testen Anwendungscode. Warum nicht die Infrastruktur? Die Werkzeuge und die Kompromisse.

Fragen Sie einen Entwickler, ob er Anwendungscode ohne Tests zusammenführen würde, und er wird Sie seltsam ansehen. Wenn man das gleiche über Terraform fragt, dann schütteln viele Teams mit den Schultern: plan und schau es dir an".
Ein Plan zu lesen ist nützlich, aber es ist nicht dasselbe wie zu testen. Es zeigt nicht, ob das Modul wie vorgesehen funktioniert, ob eine Änderung etwas anderes verletzt oder ob Sicherheitsregeln befolgt werden. Der Infrastrukturcode braucht auch Tests, nur eine andere Art.
Wie bei Anwendungs-Tests gibt es auch bei Infrastruktur-Tests Schichten, von billig und schnell bis langsam und teuer:
Der größte Teil des Wertes stammt aus den ersten beiden Schichten. Das letzte ist es wert für wichtige gemeinsame Module.
Diese Tests sollten bei jedem Commit durchgeführt werden, vorzugsweise als Pre-Commit-Hooks und in CI:
terraform fmt -check -recursive
terraform validate
tflint --recursive
checkov -d . # or: trivy config .
fmt und validate Syntax und Formatierungsprobleme.Sie sind schnell, frei und fangen eine überraschende Anzahl von echten Problemen auf.
Der beste Infrastrukturfehler ist der, der vorher erwischt wurde.
terraform planIch habe nie mit deiner Wolke gesprochen.
Seit Version 1.6 verfügt Terraform über ein integriertes Test-Framework (OpenTofu hat ein Äquivalent mit tofu test) Die Tests werden in HCL, in .tftest.hcl Akten:
# tests/bucket.tftest.hcl
variables {
name = "acme-test-logs"
environment = "staging"
}
run "bucket_is_private_and_encrypted" {
command = plan
assert {
condition = aws_s3_bucket_public_access_block.this.block_public_acls == true
error_message = "Bucket must block public ACLs."
}
assert {
condition = aws_s3_bucket.this.tags["environment"] == "staging"
error_message = "Bucket must be tagged with its environment."
}
}
Mit command = planDie Tests gehen gegen den Plan, ohne etwas zu schaffen. Mit command = apply, sie schaffen echte Ressourcen und zerstören sie danach. Sie können auch Schein-Anbieter, wodurch die Einheitstests schnell und kostenlos werden.
Für Modul-Autoren ist dies der einfachste Weg, um mit dem Testen zu beginnen. Keine neue Sprache, keine zusätzlichen Werkzeuge.
Terratest, von Gruntwork, ist eine Go-Bibliothek für Integrationstests. Es setzt echte Infrastruktur ein, führt Kontrollen gegen sie durch (HTTP-Anfragen, SSH-Befehle, API-Aufrufe) und zerstört sie.
func TestWebModule(t *testing.T) {
opts := &terraform.Options{TerraformDir: "../examples/web"}
defer terraform.Destroy(t, opts)
terraform.InitAndApply(t, opts)
url := terraform.Output(t, opts, "url")
http_helper.HttpGetWithRetry(t, url, nil, 200, "OK", 30, 10*time.Second)
}
Es ist mächtig, weil es testet, ob die Infrastruktur tatsächlich funktioniert, nicht nur, ob sie richtig konfiguriert ist. Es ist auch langsamer, braucht Go-Kenntnisse und kostet echtes Geld für jeden Lauf.
Die Richtlinien antworten "Ist das erlaubt?" für jede Änderung, unabhängig davon, wer sie geschrieben hat:
Beispielregeln: keine öffentlichen S3-Buckets, alle Ressourcen müssen ein Eigentümertag haben, nur genehmigte Instanztypen, Produktionsdatenbanken müssen Löschschutz haben.
terraform plan -out=plan.out
terraform show -json plan.out > plan.json
conftest test plan.json --policy policies/
Integrationstests kosten Geld. Möglichkeiten, es unter Kontrolle zu halten:
Fügen Sie heute statische Kontrollen an CI hinzu. Schreib ein paar . terraform test Behauptungen für Ihr am häufigsten verwendetes Modul. Fügen Sie ein oder zwei Richtlinien zu Ihren wichtigsten Regeln hinzu. Nur dann wird Terratest hinzugefügt, wenn ein Modul kritisch genug ist, um die Zeit und Kosten zu rechtfertigen.
Meine Meinung: Infrastruktur versagt auf kostspielige Weise. Ein paar billige Tests sparen jetzt eine sehr teure Lektion später.
Desly