Einführung
Zwei Teams benötigen denselben kleinen Entwurf für einen Berichtsspeicher, jedoch mit unterschiedlichen Namen, Eigentümern und Berichtstexten. Vervollständigen Sie die Schnittstelle eines bereitgestellten Moduls, rufen Sie es aus zwei unabhängigen Stammverzeichnissen auf und erweitern Sie eine Berichtssammlung mit stabilen Schlüsseln, ohne vorhandene Einträge zu ersetzen.
Sie sollten lokale Module, Variablen, Ausgabewerte und Ressourcenadressen verstehen. Das Ressourcengerüst und die Eingaben der aufrufenden Konfigurationen sind bereitgestellt; Sie definieren deren Schnittstellenvertrag und stellen die Ressourcen in dieser frischen Umgebung mit vorbereiteten Werkzeugen und ohne persönliches AWS-Konto bereit.
Bezug zu Zertifizierungen
| Zertifizierung | Prüfungsaufgabe | Übung |
|---|---|---|
| CloudOps Engineer – Associate (SOA-C03) | Task 3.1, Skill 3.1.6 | Terraform-Grundlagenübung: Infrastruktur durch geprüfte Konfigurations- und State-Änderungen warten und dabei funktionierende Ressourcen erhalten. |
Lab-Überblick

Eine typisierte Modulschnittstelle definieren
In diesem Schritt vervollständigen Sie den Vertrag für die Ein- und Ausgaben eines kleinen wiederverwendbaren Speichermoduls. Ein untergeordnetes Modul bündelt Ressourcen hinter einer Schnittstelle; ein Root-Modul liefert konkrete Eingaben und besitzt seinen eigenen State.
cd /home/labex/project/reusable-reports
cat modules/report-store/main.tf
cat dev/main.tf
Das bereitgestellte Ressourcengerüst verwendet var.bucket_name, var.owner und var.reports. for_each erstellt pro Map-Schlüssel eine Objektinstanz mit Adressen wie aws_s3_object.reports["daily"]. Stabile benannte Schlüssel halten ein vorhandenes Objekt von einem neu hinzugefügten Eintrag getrennt. Die Ressource für die Bucket-Versionierung ist eine explizite Abhängigkeit, damit beim Schreiben von Berichten Versionsidentitäten entstehen.
Definieren Sie die Schnittstelle. map(object({ body = string })) akzeptiert eine benannte Sammlung, deren Einträge jeweils Berichtstext liefern müssen. Dadurch werden die Erwartungen des Moduls ausdrücklich festgelegt, statt sich auf undokumentierte Eingabestrukturen zu verlassen:
cat > modules/report-store/variables.tf <<'HCL'
variable "bucket_name" {
type = string
description = "Unique bucket name supplied by this environment root."
}
variable "owner" {
type = string
description = "Owner tag supplied by the caller."
}
variable "reports" {
type = map(object({ body = string }))
description = "Stable report keys and their text content."
}
HCL
Ausgabewerte stellen nützliche Ressourceninformationen bereit, ohne dass eine aufrufende Konfiguration auf interne Details des Moduls zugreifen muss. Der folgende for-Ausdruck erstellt eine Zuordnung von Sammlungsschlüsseln zu Objektschlüsseln:
cat > modules/report-store/outputs.tf <<'HCL'
output "bucket_id" {
value = aws_s3_bucket.store.id
}
output "object_keys" {
value = { for key, report in aws_s3_object.reports : key => report.key }
}
HCL
Initialisieren Sie das dev-Stammverzeichnis und prüfen Sie den Schnittstellenvertrag:
terraform -chdir=dev init
terraform -chdir=dev validate
terraform -chdir=dev plan
Erwarten Sie eine gültige Konfiguration und 3 to add: den Bucket, seine Versionierungskonfiguration und das tägliche Berichtsobjekt. Wenden Sie die Änderungen erst an, nachdem Sie den Bucket-Namen, den Eigentümer und den Berichtstext in der aufrufenden Konfiguration geprüft haben. Die unabhängige Referenz des Finanzteams gehört nicht zu diesem Modul und muss unverändert bleiben.
Dasselbe Modul aus zwei unabhängigen Stammverzeichnissen aufrufen
In diesem Schritt stellen Sie dev und preview über dasselbe Modul mit unterschiedlichen Eingaben bereit. Die Stammverzeichnisse teilen sich die Modulquelldateien, jedoch keinen State. Ihre separaten Arbeitsverzeichnisse verwenden derzeit getrennte lokale States; for_each unterscheidet lediglich Ressourcen innerhalb eines States.
Prüfen Sie den gespeicherten Plan für dev und führen Sie ihn aus:
terraform -chdir=dev plan -out=dev.tfplan
Erwarten Sie 3 to add, 0 to change, 0 to destroy.
terraform -chdir=dev apply dev.tfplan
Lesen Sie die aufrufende Konfiguration für preview, bevor Sie sie initialisieren:
cat preview/main.tf
terraform -chdir=preview init
terraform -chdir=preview validate
terraform -chdir=preview plan -out=preview.tfplan
Ihre unterschiedlichen Eingaben wählen module-preview-reports, den Eigentümer preview und preview daily report aus. Erwarten Sie einen weiteren Plan zur Erstellung von drei Ressourcen, ohne Änderungen an dev.
terraform -chdir=preview apply preview.tfplan
Untersuchen Sie die Ausgabewerte und die stabile Instanzadresse in jedem Stammverzeichnis:
terraform -chdir=dev output
terraform -chdir=preview output
terraform -chdir=dev state list
terraform -chdir=preview state list
Beide Stammverzeichnisse stellen bucket_id und object_keys bereit; jedes hat eine Berichtsinstanz mit dem Schlüssel "daily". Diese Adressen gehören jedoch zu unterschiedlichen lokalen States und unterschiedlichen Buckets. Lesen Sie den tatsächlichen Inhalt:
aws s3 \
cp s3://module-dev-reports/reports/daily.txt -
aws s3 \
cp s3://module-preview-reports/reports/daily.txt -
Erwarten Sie dev daily report und preview daily report. AWS View zeigt zwei unabhängige Speicher sowie die Referenz des Finanzteams. Zeigen Sie die aktuelle VersionId des täglichen Berichts von dev an, damit Sie sie nach der Erweiterung der Sammlung vergleichen können:
aws s3api \
head-object \
--bucket module-dev-reports \
--key reports/daily.txt \
--query VersionId \
--output text
Einen Eintrag mit stabilem Schlüssel hinzufügen und vorhandene Berichte erhalten
In diesem Schritt erweitern Sie nur die Map von dev. Wenn Sie die Schlüssel einer Sammlung ändern, ändert sich die Identität der Ressourceninstanzen. Das Beibehalten des Schlüssels daily und das Hinzufügen von weekly sollten das tägliche Objekt unverändert lassen.
Ersetzen Sie die aufrufende dev-Konfiguration durch dieselben bisherigen Eingaben und einen neuen Eintrag:
cat > dev/main.tf <<'HCL'
module "report_store" {
source = "../modules/report-store"
bucket_name = "module-dev-reports"
owner = "dev"
reports = {
daily = { body = "dev daily report\n" }
weekly = { body = "dev weekly report\n" }
}
}
output "bucket_id" { value = module.report_store.bucket_id }
output "object_keys" { value = module.report_store.object_keys }
HCL
Prüfen Sie die Änderung:
terraform -chdir=dev plan -out=extra.tfplan
Erwarten Sie 1 to add, 0 to change, 0 to destroy. Dabei wird nur module.report_store.aws_s3_object.reports["weekly"] hinzugefügt. Falls das vorhandene tägliche Objekt oder der Bucket ersetzt werden soll, halten Sie an und vergleichen Sie die Schlüssel sowie die unveränderten Eingaben.
terraform -chdir=dev apply extra.tfplan
Vergleichen Sie die VersionId des täglichen Berichts mit der Ausgabe aus dem vorherigen Schritt:
aws s3api \
head-object \
--bucket module-dev-reports \
--key reports/daily.txt \
--query VersionId \
--output text
Es muss dieselbe ursprüngliche Version sein. Lesen Sie den neuen Eintrag und den unabhängigen Vorschau-Bericht:
aws s3 \
cp s3://module-dev-reports/reports/weekly.txt -
aws s3 \
cp s3://module-preview-reports/reports/daily.txt -
Erwarten Sie dev weekly report und den unveränderten Text preview daily report. Die Hintergrundprüfung vergleicht die nativen Versionen des ersten Schreibvorgangs, statt identische Bytes in Ersatzobjekten zu akzeptieren.
terraform -chdir=dev output
terraform -chdir=dev plan
terraform -chdir=preview plan
Die Ausgabe-Map von dev enthält beide Schlüssel; preview enthält weiterhin nur daily. Beide Stammverzeichnisse sollten mit No changes einen übereinstimmenden Zustand anzeigen. Lassen Sie die genutzten Speicher verfügbar. Dieses Modul definiert eine Schnittstelle und eine Ressourcensammlung; die Wahl separater Schlüssel für entfernte Backends ist eine zusätzliche Entscheidung zur Umgebungsisolierung, die später behandelt wird.
Informationen zur Verwendung von Moduleingaben und -ausgaben als Grenzen finden Sie in HashiCorps Leitfaden zur Modulkomposition.
Zusammenfassung
Sie haben eine typisierte Modulschnittstelle erstellt, nützliche Ausgabewerte an zwei unabhängige Root-Module zurückgegeben und einen for_each-Eintrag mit stabilem Schlüssel hinzugefügt, ohne ursprüngliche Berichte zu ersetzen. Eine Ressourcensammlung unterscheidet sich von der State-Grenze einer Umgebung.



