AWS, AZURE, GOOGLE CLOUD → STACKIT · TERRAFORM UND OPENTOFU
Terraform- und OpenTofu-Migration zu STACKIT, Schritt für Schritt
Ihr Terraform- oder OpenTofu-Code beschreibt bereits, was Ihre Umgebung sein soll, und ist damit der beste Ausgangspunkt für eine Migration zu STACKIT, sofern das Werkzeug jedes Modul und jede Variable sieht. StackToIT liest die Konfiguration, ordnet jede Einheit einem STACKIT-Ziel zu und schreibt einen neuen STACKIT-Terraform-Entwurf. Dieser Leitfaden geht den Weg an einer kleinen Umgebung mit zwei Modulaufrufen, einer Variablendatei und einer Queue durch und zeigt, was bei einer fehlenden Eingabe passiert. Die Demo-Umgebung ist AWS; die StackToIT-Leitfäden für Azure und Google Cloud dokumentieren denselben assess-Befehl für Code mit den Providern azurerm, azapi und Google; ihre Zuordnungen unterscheiden sich je Dienst.
Der Weg in sieben Schritten
Vom Quell-Repository zur geprüften STACKIT-Konfiguration.
Root-Module und Variablendateien sammeln
Listen Sie jedes Root-Modul auf, das bewertet werden soll, dazu die Variablendateien, die ihm in Ihren Pipelines Werte geben (terraform.tfvars, Umgebungsdateien, TF_VAR-Einstellungen), und die .terraform.lock.hcl. Bewertet wird der Ordner, der die Infrastruktur deklariert. Ohne Lock-Datei warnte der Demo-Lauf, dass kein Eintrag den AWS-Provider 5.100.0 festschreibt, und die Dokumentation nennt die Lock-Datei als Voraussetzung für die Validierung der Quelle.
Eingaben vollständig machen
Eine Variable ohne Default und ohne Wert führt dazu, dass jede Einheit, die sie liest, abgelehnt wird. In der Demo lesen alle drei Einheiten den Umgebungsnamen, deshalb schrieb der erste Lauf keinen Entwurf. Dateien mit Standardnamen werden ohnehin gelesen; eine Datei wie prod.tfvars übergeben Sie mit --var-file, in der Reihenfolge, in der OpenTofu die Dateien lesen würde.
Bewertung ausführen
Führen Sie stacktoit assess für den Root-Ordner aus. Ergänzen Sie --offline, wenn kein Netzwerkzugriff auf Remote-Module erlaubt ist. Lokale Module werden von der Platte geladen.
Modulübersicht lesen
Die Konsole listet jeden Modulaufruf, ob er lokal oder extern ist und wie viele Einheiten und Ressourcen daraus entstanden. Ein Modul, das nicht heruntergeladen wurde oder ungültig ist, hinterlässt für seine Einheiten kein STACKIT-Paket.
Terraform-Entwurf prüfen
Der Entwurf ist eine neue Konfiguration mit eigenem Provider-Block, keine geänderte Kopie der Quelle. Prüfen Sie ihn mit dem Plattformteam, bevor Sie etwas anwenden.
Werte und Entscheidungen liefern, erneut ausführen
Offene Variablen gehören in review/target-values.tfvars, Designantworten in review/inputs.yaml, und der nächste Lauf liest sie.
Auf frischen State anwenden
Wenden Sie den geprüften Entwurf auf einen eigenen State an, mit Reihenfolge und Voraussetzungen aus execution/terraform/apply.md. Der Quell-State bleibt unberührt, bis Sie die Quelle stilllegen.
Die Eingabe: zwei Modulaufrufe, eine Variablendatei, eine Queue
Eine kleine AWS-Umgebung, für diese Seite geschrieben. Das Modul wird zweimal verwendet, einmal mit einer Variable und einmal mit einem festen Wert, und prod.tfvars liefert den Umgebungsnamen.
variable "environment" {
type = string
}
variable "retention_days" {
type = number
default = 30
}
module "exports" {
source = "./modules/bucket"
bucket_name = "acme-${var.environment}-exports"
retention_days = var.retention_days
}
module "archive" {
source = "./modules/bucket"
bucket_name = "acme-${var.environment}-archive"
retention_days = 365
}
resource "aws_sqs_queue" "jobs" {
name = "acme-${var.environment}-jobs"
visibility_timeout_seconds = 60
}resource "aws_s3_bucket" "this" {
bucket = var.bucket_name
}
resource "aws_s3_bucket_versioning" "this" {
bucket = aws_s3_bucket.this.id
versioning_configuration {
status = "Enabled"
}
}
resource "aws_s3_bucket_lifecycle_configuration" "this" {
bucket = aws_s3_bucket.this.id
rule {
id = "expire"
status = "Enabled"
filter {}
expiration {
days = var.retention_days
}
}
}environment = "prod"
retention_days = 90Warum diese Form
Echte Umgebungen verwenden Module wieder und lesen Werte aus Dateien. Ignoriert das Werkzeug eines von beidem, ist der Entwurf falsch, ohne so auszusehen.
Ohne Werte verweigert der Lauf das Raten
Beide Läufe wurden am 4. November 2026 von StackToIT über denselben Ordner ausgeführt. Der erste hat keine Variablendatei und endet ohne Entwurf. Der zweite übergibt --var-file und bewertet alle sieben Ressourcen.
Source inputs missing: 1 required input is not in the package, so what reads it was not assessed.
variable environment · main.tf:39 · aws_sqs_queue.jobs.name, module.archive.aws_s3_bucket.this.bucketResources scanned: 7 (1 in the root module · 6 inside 2 module calls)
Migration units: 3 (3 instances)
Unit dependencies: 0
Modules: 2 module calls (0 external, 2 local): 2 loaded, 0 not downloaded, 0 invalid
module.archive ./modules/bucket 1 unit (RECONFIGURE 1) · 3 resources
module.exports ./modules/bucket 1 unit (RECONFIGURE 1) · 3 resources
Source checks: Built-in source checks passed — OpenTofu validation of the source was not runWas die Verweigerung schützt
Der erste Lauf schrieb weder einen Ordner terraform noch Wellen. Alle drei Einheiten lesen den fehlenden Wert: die beiden Bucket-Namen und den Queue-Namen. Das Werkzeug erfindet keinen Wert für acme-${var.environment}-exports.
Erklärte Auslassungen
Fehlt eine Eingabe absichtlich, erklärt --omitted-inputs sie. Der Lauf deckt dann nur einen Teil ab: Einheiten, die sie lesen, werden namentlich abgelehnt, die übrigen werden entworfen.
Das entworfene STACKIT-Terraform
Ressourcenblöcke aus dem zweiten Lauf. Die Prüfkommentare über den Blöcken sind hier weggelassen; die S3-API-Dokumente sind die Dateien, die der Lauf für Einstellungen schreibt, für die der Provider keine Attribute hat.
terraform {
# Write-only attributes (e.g. a VPN pre-shared key) need Terraform/OpenTofu 1.11 or later.
required_version = ">= 1.11.0"
required_providers {
stackit = {
source = "stackitcloud/stackit"
version = "0.121.0"
}
}
}
provider "stackit" {
default_region = var.region
}resource "stackit_objectstorage_bucket" "archive_this" {
project_id = var.project_id
name = "acme-prod-archive"
}
resource "stackit_objectstorage_bucket" "exports_this" {
project_id = var.project_id
name = "acme-prod-exports"
}{
"Rules": [
{
"ID": "expire",
"Status": "Enabled",
"Filter": {
"Prefix": ""
},
"Expiration": {
"Days": 90
}
}
]
}{
"Rules": [
{
"ID": "expire",
"Status": "Enabled",
"Filter": {
"Prefix": ""
},
"Expiration": {
"Days": 365
}
}
]
}Variablen wurden pro Modul aufgelöst
Die Lifecycle-Regel von module.exports trägt 90 Tage aus prod.tfvars, die Regel von module.archive den festen Wert 365 Tage.
Ein flacher Entwurf
Jede Modulinstanz wurde zu einer eigenen Bucket-Ressource (archive_this, exports_this). Die Modulstruktur bauen Sie auf der Zielseite selbst wieder auf, wenn Sie sie wollen.
Was der Lauf mit jedem Quellkonstrukt gemacht hat
Aus dem zweiten Lauf gelesen.
| Quellkonstrukt | Ergebnis im Lauf | Wo nachzulesen |
|---|---|---|
| module "exports" und module "archive", lokale Quelle | Zwei Modulaufrufe geladen, 6 Ressourcen darin gescannt, je 1 Einheit | Konsolenzusammenfassung, architect-report.md |
| Modulressourcen Bucket, Versioning, Lifecycle | Eine Einheit je Instanz: RECONFIGURE, STACKIT Object Storage | migration/technical-sequencing.md |
| var.retention_days mit Default 30, in prod.tfvars auf 90 | Regel läuft nach 90 Tagen ab; das Literal 365 bleibt 365 | terraform/s3api/*/lifecycle.json |
| aws_sqs_queue.jobs | REPLATFORM auf eine STACKIT-RabbitMQ-Instanz, mit offenen Variablen für Plan, Version und Zugriffsliste | terraform/messaging.tf, review/target-values.tfvars |
| Provider-Region eu-central-1 | In var.region abgelegt, Default eu01; der Datenstandort ändert sich und ist einmal zu bestätigen | engineering/architect-report.md |
| required_version >= 1.6 | Der Entwurf verlangt >= 1.11.0; der Kommentar im Kopf begründet diese Untergrenze mit Write-only-Attributen, etwa einem VPN-Pre-Shared-Key. Prüfen Sie die Version in Ihrer Pipeline | terraform/terraform.tf |
Klassen sind ein Vorschlag. Eine Klasse benennt die Art der Arbeit und genehmigt sie nicht.
Entscheidungen Ihrer Architekten
Der Lauf entwirft. Diese Entscheidungen bleiben bei Ihnen.
Modulstruktur im Ziel
Der Entwurf ist flach. Entscheiden Sie, ob wiederkehrende Buckets wieder in ein Modul gehören und wie sie heißen.
State und Pipeline
Entscheiden Sie, wo der neue State liegt und welche Pipeline ihn anwendet. Prüfen Sie, ob Ihre OpenTofu- oder Terraform-Version die Anforderung des Entwurfs von 1.11.0 oder höher erfüllt.
Provider-Version
Der Entwurf legt den STACKIT-Provider auf 0.121.0 fest. Der am 4. November 2026 gelesene Registry-Eintrag nennt 0.122.0 als aktuell, veröffentlicht am 3. November. Prüfen Sie die Version vor dem Apply gegen die Registry.
API-Opt-in für S3-Einstellungen
Versioning und Lifecycle laufen über STACKIT-S3-API-Aufrufe (vier Skripte unter execution/api), die der Plan erst nach Ihrer Antwort auf die Opt-in-Entscheidung ausführt. Dieselbe Entscheidung hält einen alternativen Weg für die Queue über eine STACKIT-Messaging-API zurück, die nicht allgemein verfügbar ist; die RabbitMQ-Blöcke des Entwurfs warten nicht darauf.
Queue-Design
Die RabbitMQ-Instanz braucht Plan, Version und Zugriffsliste, die die Quelle nicht liefern kann. Der Lauf lässt sie als Variablen ohne Default.
Was außerhalb von Terraform bleibt
Alles, was der Provider nicht ausdrücken kann, bleibt ein dokumentierter Schritt: Der Lauf führt diese Einstellungen als nicht übernommen oder als S3-API-Dokumente auf. Zwei Hinweise aus dem Lauf: Einmal aktiviertes Versioning lässt sich auf STACKIT nur aussetzen, nicht abschalten, und solange die Lifecycle-Regeln nicht angewendet sind, läuft nichts ab.
Fragen von Teams zu Terraform und OpenTofu
Liest StackToIT meine State-Datei?
Die dokumentierten Eingaben sind Konfiguration, Variablen und Module, ein State gehört nicht dazu. Die Bewertung beschreibt, was Ihr Code deklariert. Vergleichen Sie selbst mit Ihrem State, wenn Drift eine Rolle spielt.
Und Remote-Module?
Remote-Module werden zuerst aus vorhandenen lokalen Quellen aufgelöst. Abruf über das Netzwerk erfolgt bei Bedarf, sofern nicht --offline gesetzt ist. In der Demo waren beide Modulaufrufe lokal, und die Konsole zählte 0 externe.
Kann ich eine Ressource nach der anderen umwandeln?
Der Lauf bewertet das ganze Root-Modul, damit Abhängigkeiten sichtbar sind, und ordnet die Einheiten dann in Wellen. Welche Blöcke des Entwurfs Sie zuerst anwenden, entscheiden Sie.
Validiert StackToIT die Quelle mit OpenTofu?
Ja, automatisch, wenn die Maschine die Bedingungen aus der Dokumentation erfüllt: OpenTofu im Pfad, eine Sandbox ohne Netzwerkzugriff und die Provider in einem lokalen Mirror (--provider-mirror) oder Plugin-Cache; für die Quelle zusätzlich eine Lock-Datei. Heruntergeladen wird nichts. --no-validate überspringt die Validierung, --validate lässt den Lauf scheitern, wenn sie nicht laufen kann. Die Demo-Läufe nutzten --no-validate, und die Konsole sagt das.
Lässt sich die Ausgabe gefahrlos unverändert anwenden?
Nein. Das Paket ist ein Vorschlag, nichts darin ist genehmigt. Wenden Sie erst nach Ihrer Prüfung an, in der Reihenfolge der Apply-Datei.
Quellen
Ihr nächster Schritt: STACKIT.
Erzählen Sie uns von Ihrer Umgebung. Wir zeigen Ihnen, was StackToIT dafür liefert: Zielarchitektur, Terraform-Artefakte und einen strukturierten Migrationsplan.