Terraform auf Azure: 10 Best Practices für Enterprise-Scale-Deployments
Praxiserprobte Terraform-Praktiken für Azure im Enterprise-Umfeld — State-Management, Module, Policy-as-Code und Drift-Erkennung.
Terraform auf Azure zum Laufen zu bringen dauert einen Tag. Terraform zuverlässig, sicher und über dutzende Subscriptions hinweg zu betreiben — das ist die eigentliche Ingenieursleistung. Aus unserer Erfahrung mit Enterprise-Kunden im DACH-Raum haben wir zehn Praktiken destilliert, die wir für unverzichtbar halten.
1. Remote State mit Locking — ohne Ausnahme
Lokale State-Dateien sind in jedem Teamszenario eine tickende Zeitbombe. Speichern Sie den State in einem Azure Storage Account mit Blob-Level-Locking.
- Aktivieren Sie Soft Delete und Versionierung auf dem Container, um bei versehentlicher State-Korruption wiederherstellen zu können.
- Verwenden Sie eine dedizierte Resource Group für State-Speicherung, gesichert mit
CanNotDelete-Management-Locks. - Trennen Sie State-Dateien pro Umgebung und pro logischer Komponente. Eine einzelne monolithische State-Datei für die gesamte Landing Zone wird bei Plans irgendwann in Timeouts laufen.
Tipp: Verwenden Sie sprechende Prefixe für Ihre State-Keys:
networking/terraform.tfstate,identity/terraform.tfstate. Das macht das Browsen im Storage Account intuitiv.
2. Module nach Lifecycle strukturieren, nicht nach Ressourcentyp
Ein häufiger Fehler: pro Azure-Ressourcentyp ein Modul (module "vnet", module "nsg", module "route_table"). Gruppieren Sie stattdessen Ressourcen, die gemeinsam deployed und geändert werden.
- Ein „Spoke Network"-Modul, das VNet, Subnetze, NSGs, Routentabellen und Peering enthält, ist operativ sinnvoller als vier separate Module.
- Halten Sie Module klein genug zum Verstehen, aber groß genug, um eine sinnvolle Infrastruktureinheit abzubilden.
- Dokumentieren Sie jedes Modul mit einer
README.md, Input/Output-Beschreibungen und einer Beispiel-tfvars-Datei.
3. Provider- und Modul-Versionen pinnen
Offene Provider-Constraints (>= ohne obere Grenze) garantieren eine überraschende Breaking Change zum denkbar ungünstigsten Zeitpunkt.
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.95" # erlaubt nur 3.95.x Patches
}
}
}- Nutzen Sie den pessimistischen Constraint-Operator (
~>), um Patch-Updates zuzulassen und Minor/Major-Bumps zu blockieren. - Führen Sie wöchentlich
terraform init -upgradein einem dedizierten PR aus, um neue Provider-Versionen isoliert zu evaluieren. - Verfolgen Sie das AzureRM-Changelog — API-Änderungen von Microsoft manifestieren sich häufig als Breaking Changes auf Provider-Ebene.
4. Policy-as-Code von Anfang an implementieren
Azure Policy und Terraform setzen an unterschiedlichen Stellen an. Nutzen Sie beide.
- Terraform-seitig: Verwenden Sie Tools wie OPA/Conftest oder Checkov, um Plans vor dem Apply zu validieren. Fangen Sie Probleme wie öffentliche Storage Accounts oder fehlende Tags im CI ab — nicht erst nach dem Deployment.
- Azure-seitig: Deployen Sie Azure-Policy-Assignments über Terraform selbst. So sind Policy-Definitionen versioniert, reviewed und reproduzierbar.
- Starten Sie im Audit-Modus, sichten Sie die Ergebnisse, und schalten Sie dann auf Deny um. Direkt mit Deny zu starten erzeugt Reibungsverluste, die das Vertrauen in die Plattform untergraben.
5. Variable-Dateien als Konfiguration behandeln, nicht als Code
Ihre .tf-Dateien definieren was deployed wird. Ihre .tfvars-Dateien definieren wo und wie viel. Halten Sie das sauber getrennt.
- Speichern Sie umgebungsspezifische
tfvarsin einem dedizierten Verzeichnis:environments/dev.tfvars,environments/prod.tfvars. - Codieren Sie niemals umgebungsspezifische Werte hart in Module. Wenn ein Wert zwischen Dev und Prod abweicht, gehört er in eine Variable.
- Nutzen Sie Variable-Validation-Blöcke, um ungültige Eingaben frühzeitig abzufangen:
variable "environment" {
type = string
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "Environment muss dev, staging oder prod sein."
}
}6. Plans in Pull Requests automatisieren
Jeder Pull Request, der Terraform-Code berührt, sollte einen Plan triggern und die Ausgabe als PR-Kommentar posten. Das ist die wirkungsvollste CI-Integration überhaupt.
- Verwenden Sie Terraform Cloud, Spacelift oder eine eigene Pipeline (GitHub Actions / Azure DevOps) für die Plan-Ausführung.
- Konfigurieren Sie die Pipeline so, dass der PR fehlschlägt, wenn der Plan Fehler oder Policy-Verletzungen enthält.
- Fordern Sie mindestens eine Freigabe durch einen Infrastruktur-Reviewer, bevor
terraform applyausgeführt wird.
Warnung: Führen Sie niemals
terraform applymit Auto-Approve in Produktionspipelines aus, ohne dass ein Mensch den Plan zuvor geprüft hat.
7. Secrets außerhalb des State verwalten
Terraform-State-Dateien enthalten sensible Werte im Klartext. Das ist eine bekannte Einschränkung, kein Bug.
- Verwenden Sie Azure Key Vault für Secrets und referenzieren Sie diese über
data-Sources oder dieazurerm_key_vault_secret-Ressource. - Markieren Sie sensible Outputs mit
sensitive = true, um sie in der CLI-Ausgabe zu unterdrücken (im State erscheinen sie dennoch). - Verschlüsseln Sie Ihren State-Storage at rest (Azure Storage macht das standardmäßig) und beschränken Sie den Zugriff mit Azure RBAC — nicht mit Storage-Account-Keys.
8. Drift-Erkennung implementieren
Configuration Drift — wenn Azure-Ressourcen von dem abweichen, was Terraform erwartet — ist in Enterprise-Umgebungen unvermeidlich. Portal-Änderungen, Support-Tickets, automatische Remediations: alle verursachen Drift.
- Planen Sie nächtliche
terraform plan-Läufe, die Drift erkennen, ohne Änderungen anzuwenden. - Leiten Sie Drift-Reports an einen Slack-Channel oder ein Azure-DevOps-Dashboard weiter.
- Kategorisieren Sie Drift: manches ist harmlos (automatisch generierte Tags), manches ist kritisch (geänderte Firewall-Regeln). Etablieren Sie einen Triage-Prozess, nicht nur Erkennung.
9. Workspaces sparsam einsetzen — Directory-Trennung bevorzugen
Terraform Workspaces sind verlockend für die Umgebungstrennung, bringen aber versteckte Komplexität mit sich.
- Workspaces teilen sich dieselbe Backend-Konfiguration, was es leicht macht, versehentlich die falsche Umgebung anzusteuern.
- Verzeichnisbasierte Trennung (ein Root-Modul pro Umgebung) ist expliziter, einfacher zu auditieren und leichter in CI/CD zu handhaben.
- Falls Sie Workspaces verwenden, erzwingen Sie mindestens die Workspace-Auswahl in Ihrer Pipeline und fügen Sie Guardrails hinzu, die Verwechslungen verhindern.
10. Nach Team-Grenzen schneiden, nicht nach technischen Grenzen
Die wirkungsvollste architektonische Entscheidung ist, wie Sie Ihre Terraform-Codebasis auf Teams aufteilen.
- Richten Sie State-Grenzen an der Team-Ownership aus. Wenn das Netzwerk-Team VNets besitzt und das Applikationsteam App Services, sollten sie separate State-Dateien und separate Pipelines haben.
- Nutzen Sie Data Sources und Remote State Outputs für teamübergreifende Referenzen statt hart codierter Ressourcen-IDs.
- Etablieren Sie eine Modul-Registry (selbst wenn es nur ein Git-Repo mit semantischer Versionierung ist), damit Teams gemeinsame Module konsumieren, ohne sie zu kopieren.
Fazit
Diese Praktiken sind nicht theoretisch — es sind die Muster, die wir in Kunden-Landing-Zones quer durch Azure deployen. Der rote Faden ist Blast-Radius-Reduzierung: kleinere State-Dateien, eingeschränkte Berechtigungen, automatisierte Guardrails und klare Ownership-Grenzen.
Wenn Ihr Team Terraform über eine Handvoll Subscriptions hinaus skaliert und es zunehmend fragil wird, liegt das Problem selten an Terraform selbst. Es liegt fast immer an den operativen Praktiken drumherum.
Weiterführende Ressourcen
- Infrastructure-as-Code-Strategie — Die strategische Grundlage für Ihre Terraform-Praxis.
- GitOps für Kubernetes mit Flux — Erweitern Sie IaC-Prinzipien auf Ihre Kubernetes-Deployments.
- DevSecOps-Pipeline-Design — Integrieren Sie Sicherheitsscans in Ihre Terraform-CI/CD-Pipelines.
Sie benötigen Unterstützung bei Ihrer Azure-Terraform-Architektur? Kontaktieren Sie unser Team — wir haben das branchenübergreifend umgesetzt, von Finanzdienstleistungen bis Automotive.