🏗️ Terraform Lektion 13/15 ~7 Min. Experte

Import und Migration

Bestehende Infra in Terraform importieren.

📝 Meine Notizen

Lernziele

Nach dieser Lektion kannst du bestehende Cloud-Ressourcen in Terraform importieren und typische Migrationsstrategien skizzieren. Du kennst terraform import, den modernen Import-Block (Terraform 1.5+) und den Workflow „Config schreiben → importieren → plan bis No changes”. Außerdem weißt du, wann Import sinnvoll ist — und wann Neubau die bessere Wahl.

Das Problem: Jahre ClickOps, neuer CTO will IaC

Die Realität in den meisten Unternehmen: Infrastruktur existiert bereits — manuell angelegt, per CloudFormation-Stack aus 2019, oder halb in Terraform, halb in der Console. „Fangt an, alles in Terraform zu schreiben” heißt nicht grüne Wiese, sondern Brownfield-Migration.

Der naive Ansatz — Ressource in der Console löschen und per Terraform neu anlegen — ist bei Stateful Resources (Datenbanken, DNS-Zonen, Buckets mit Daten) inakzeptabel. Import übernimmt bestehende Ressourcen in den State, ohne sie physisch zu verändern.

Import: State-Mapping herstellen

Grundprinzip: Du schreibst HCL, das die Resource beschreibt, und sagst Terraform: „Diese Resource in meinem Code ist jene ID in der Cloud.”

Klassisch: terraform import

# HCL muss existieren — auch wenn Attribute noch ungenau sind
resource "aws_s3_bucket" "legacy" {
  bucket = "company-legacy-data"
}

terraform import aws_s3_bucket.legacy company-legacy-data
terraform plan   # zeigt Diff zwischen Code und Realität

Der Import schreibt nur in den State — er ändert nichts in der Cloud. Der nachfolgende plan zeigt, wo dein HCL von der Realität abweicht. Ziel: Code iterativ anpassen, bis plan No changes meldet.

Modern: import-Block (Terraform 1.5+)

Import deklarativ in HCL — planbar und reviewbar:

import {
  to = aws_s3_bucket.legacy
  id = "company-legacy-data"
}

resource "aws_s3_bucket" "legacy" {
  bucket = "company-legacy-data"
}
terraform plan   # zeigt Import + eventuelle Changes
terraform apply  # führt Import aus und gleicht ab

Mehrere Ressourcen in einem Plan — terraform import war immer einzeln. Für größere Migrationen ist der Import-Block deutlich handhabbarer.

Der Migrations-Workflow Schritt für Schritt

  1. Inventarisieren: Was existiert? AWS Config, Resource Explorer, oder terraformer/former2 als Hilfsmittel — nicht als Dauerlösung.
  2. Stack-Grenzen ziehen: Nicht alles in einen State. VPC hier, Datenbanken dort — wie bei Greenfield (Lektion 6).
  3. HCL schreiben: Minimal starten — nur Pflicht-Attribute; terraform show -json nach Import hilft beim Vergleich.
  4. Importieren: Einzeln oder per import-Block.
  5. Plan iterieren: Diff eliminieren — oft fehlen Tags, Lifecycle-Regeln oder Defaults.
  6. Ab freeze: Kein ClickOps mehr für importierte Ressourcen.

Generated Code: Tools wie terraform import mit -generate-config (Terraform 1.5+) oder terraformer erzeugen HCL aus bestehenden Ressourcen. Der Output ist ein Startpunkt, kein Production-Code — manuell bereinigen.

Was schiefgeht — und wie du es vermeidest

Attribute-Mismatch: Importiert, aber Plan will Replace (-/+). Ursache: Pflicht-Attribut im Code weicht ab (z. B. bucket-Name vs. bucket_prefix). Lösung: terraform state show aws_s3_bucket.legacy und Code angleichen.

Abhängigkeiten fehlen: Importierst eine EC2, aber nicht das zugehörige Security Group — Terraform will neue SG anlegen oder die falsche referenzieren. Importiere in Abhängigkeitsreihenfolge: Netzwerk → SG → Instanz.

Resource-Typ geändert: AWS splittet Ressourcen (S3-Bucket vs. Bucket-Versioning als separate Resources). Alter Code passt nicht zum neuen Provider-Schema — Changelog lesen, ggf. moved-Block.

Teilimport: Nur die Hälfte eines Stacks importiert — der Rest existiert als Waisen oder wird doppelt angelegt. Migrationsplan schriftlich, mit Checkliste pro Resource.

Wann Import — wann Neubau?

ImportNeubau
Stateful (RDS, S3 mit Daten)Stateless (ASG, Lambda)
DNS, Zertifikate mit hartem CutoverDev/Test-Umgebungen
Compliance-Audit verlangt HistorieArchitektur sowieso falsch

Manchmal ist Parallel-Betrieb + Cutover besser als Import: Neue Umgebung in Terraform, Traffic umstellen, Altes abschalten.

Praxis: Import mit random-Provider simulieren

Der random-Provider hat keine echte „bestehende” Resource — aber du kannst den Flow üben:

mkdir import-lab && cd import-lab
cat > main.tf <<'EOF'
resource "random_id" "existing" {
  byte_length = 4
}
EOF

terraform init && terraform apply -auto-approve
REAL_ID=$(terraform state show random_id.existing | grep '^id ' | awk '{print $3}' | tr -d '"')

# State löschen — simuliert „Terraform kennt Resource nicht"
terraform state rm random_id.existing

# Import-Block
cat >> main.tf <<EOF

import {
  to = random_id.existing
  id = "$REAL_ID"
}
EOF

terraform plan    # Import im Plan
terraform apply   # State wiederhergestellt
terraform plan    # No changes
terraform destroy

In AWS sieht der Flow identisch aus — nur die ID ist ein ARN oder Name statt einer Hex-Zeichenkette.

Typische Stolperfallen

Import ohne anschließenden plan: Wer importiert und aufhört, hat Code und Realität potenziell desynchron — der nächste Apply macht unerwartete Changes.

Alles auf einmal importieren: Big-Bang-Migrationen scheitern. Inkrementell pro Stack, mit funktionierendem plan nach jedem Schritt.

Lifecycle ignore_changes als Default: ignore_changes = all nach Import unterdrückt Drift — aber auch legitime Updates. Nur gezielt für Felder, die außerhalb TF gemanaged werden.

Import in falschen State: Prod-Resource in Dev-State importiert — Chaos beim Apply. Backend und Workspace vorher verifizieren.

Interview-Vorbereitung

„Wie importierst du bestehende Infrastruktur?” — HCL schreiben, terraform import oder import-Block, plan iterieren bis No changes; nie blind löschen und neu anlegen bei Stateful Resources.

Follow-ups:

  • „Unterschied import vs. data source?” — Import: Terraform verwaltet die Resource; Data Source: nur lesen.
  • „Was ist der import-Block?” — Deklarativer Import ab TF 1.5, planbar im normalen Workflow.
  • „Was tun bei Replace nach Import?” — Code an Realität anpassen; state show zum Vergleich; ggf. lifecycle { prevent_destroy } bis Code stimmt.
  • „Wann würdest du nicht importieren?” — Wenn Architektur falsch ist oder Neubau günstiger als Angleichung.

Zusammenfassung

Import bringt bestehende Ressourcen unter Terraform-Verwaltung, ohne sie physisch zu verändern. Der Workflow ist: Config schreiben, importieren, planen, Code angleichen, wieder planen — bis No changes. Der import-Block macht das seit Terraform 1.5 reviewbar und batch-fähig. Brownfield-Migration ist Inkrementarbeit mit klaren Stack-Grenzen — kein Big-Bang.

In der nächsten Lektion bündeln wir Best Practices für production-ready Terraform-Projekte.