GCP TERRAFORM → STACKIT TERRAFORM
GCP Terraform naar STACKIT Terraform
StackToIT leest uw Google Cloud-Terraform zoals uw engineers het schreven, inclusief modules en variabelen, en schrijft STACKIT-providercode die uw platformteam kan beoordelen, versioneren en via de eigen pipeline kan toepassen. De run op deze pagina beoordeelde de openbare Jump Start Solution "Dynamic Python Web App" van Google Cloud (37 resources in 18 bestanden) ongewijzigd, op één vastgezette commit: 11 migratie-eenheden plus 5 die pas tijdens de planfase vaststaan. Van de 16 eenheden zijn er 11 uitgewerkt als 10 STACKIT-resourceblokken die de OpenTofu-validatie accepteert. De volledige run staat op stacktoit.com/examples/gcp-python-webapp/.
Eén echte conversie: Cloud SQL naar PostgreSQL Flex
De database van de Dynamic Python Web App van Google Cloud, ongewijzigd beoordeeld met een variabelenbestand van één regel (project_id = "example-project"). Links de Cloud SQL-instance precies zoals Google die publiceert, rechts het blok precies zoals StackToIT het in de run schreef. De opmerkingen die het concept boven elk blok bewaart, zijn hier weggelaten.
resource "google_sql_database_instance" "postgres" {
name = var.random_suffix ? "${var.instance_name}-${random_id.suffix.hex}" : var.instance_name
database_version = "POSTGRES_14"
project = var.project_id
region = var.region
deletion_protection = false
settings {
tier = "db-custom-2-4096" # 2 CPU, 4GB Memory
user_labels = var.labels
}
depends_on = [module.project_services]
}resource "stackit_postgresflex_instance" "postgres" {
project_id = var.project_id
name = "postgres"
version = "14"
flavor_id = "2.4"
storage = {
class = var.postgresflex_storage_class
size = var.postgres_storage_size
}
backup_schedule = "0 2 * * *"
network = {
acl = var.postgres_allowed_cidrs
}
retention_days = 32
}Engine, versie en omvang overgenomen
POSTGRES_14 wordt een PostgreSQL Flex-instance op versie 14. De tier db-custom-2-4096 (2 CPU, 4 GB geheugen) wordt flavor 2.4: 2 vCPU en 4 GiB op één node in de eu01-catalogus van 18 oktober 2026.
Back-ups en bewaartermijn
De bron noemt geen starttijd voor back-ups. Het concept gebruikt daarom de standaard 02:00 dagelijks (0 2 * * *) en meldt dat. De bewaartermijn van de bron is statisch niet zichtbaar; retention_days staat op 32, het minimum van STACKIT (32 tot 90).
Openstaande waarden worden variabelen
De bron noemt geen schijfgrootte. Een Cloud SQL-schijf groeit vanzelf, een PostgreSQL Flex-opslag heeft een vaste grootte: postgres_storage_size is een variabele (5 tot 4000 GB) die u instelt nadat u de huidige schijf hebt bekeken. Ook de opslagklasse en de toegestane CIDR's, die het endpoint van de instance met een ACL beperken, zijn variabelen.
Elke eigenschap verantwoord
Van de 12 betekenisvolle eigenschappen op deze Cloud SQL-eenheid (instance, database en gebruiker) zijn er 6 overgenomen of toegelicht en 6 benoemd als niet overgenomen: de labels, het wachtwoord van de gebruiker, beide namen en beide verwijderbeleiden ABANDON. Er blijft geen eigenschap onverklaard. STACKIT genereert het wachtwoord van de gebruiker, en de gebruiker en de database maakt u zelf aan met stackit_postgresflex_user en stackit_postgresflex_database.
Tweede conversie: Cloud Run-service naar STACKIT Kubernetes Engine
STACKIT kent geen Cloud Run, dus de Django-API-service wordt een workload op STACKIT Kubernetes Engine. Links de service precies zoals Google die publiceert. Rechts de Kubernetes-manifesten die StackToIT ervoor schreef; ze draaien op het cluster stackit_ske_cluster.containers uit terraform/kubernetes.tf, dat ook de migratiejob draagt.
resource "google_cloud_run_v2_service" "server" {
name = var.random_suffix ? "${var.service_name}-${random_id.suffix.hex}" : var.service_name
location = var.region
deletion_protection = false
template {
service_account = google_service_account.server.email
containers {
image = local.server_image
env {
name = "DJANGO_ENV"
value_source {
secret_key_ref {
secret = google_secret_manager_secret.django_settings.secret_id
version = "latest"
}
}
}
env {
name = "PYTHONPATH"
value = ""
}
env {
name = "DJANGO_SETTINGS_MODULE"
value = "avocano_api.settings"
}
# These variables are a standard part of OpenTelemetry SDK configuration.
# Details are available at
# https://opentelemetry.io/docs/reference/specification/sdk-environment-variables/#exporter-selection
env {
name = "OTEL_METRICS_EXPORTER"
value = "none"
}
env {
name = "OTEL_TRACES_EXPORTER"
value = "gcp_trace"
}
env {
name = "OTEL_PYTHON_EXCLUDED_URLS"
value = "healthy"
}
# Supply the custom suffix, if used, to support automated CSRF code in application settings
env {
name = "DEPLOYMENT_SUFFIX"
value = var.random_suffix ? random_id.suffix.hex : ""
}
volume_mounts {
name = "cloudsql"
mount_path = "/cloudsql"
}
liveness_probe {
http_get {
path = "/healthy"
}
}
}
labels = var.labels
volumes {
name = "cloudsql"
cloud_sql_instance {
instances = [google_sql_database_instance.postgres.connection_name]
}
}
}
traffic {
percent = 100
type = "TRAFFIC_TARGET_ALLOCATION_TYPE_LATEST"
}
depends_on = [
google_secret_manager_secret_version.django_settings
]
lifecycle {
ignore_changes = [
scaling,
]
}
}apiVersion: v1
kind: ConfigMap
metadata:
name: server-env
labels:
app.kubernetes.io/name: server
data:
DEPLOYMENT_SUFFIX: "" # fill in: the value is not copied from the source
DJANGO_SETTINGS_MODULE: "" # fill in: the value is not copied from the source
OTEL_METRICS_EXPORTER: "" # fill in: the value is not copied from the source
OTEL_PYTHON_EXCLUDED_URLS: "" # fill in: the value is not copied from the source
OTEL_TRACES_EXPORTER: "" # fill in: the value is not copied from the source
PYTHONPATH: "" # fill in: the value is not copied from the source
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: server
labels:
app.kubernetes.io/name: server
spec:
replicas: REQUIRED_SERVER_REPLICAS
selector:
matchLabels:
app.kubernetes.io/name: server
template:
metadata:
labels:
app.kubernetes.io/name: server
spec:
containers:
- name: container-1
image: "us-docker.pkg.dev/hsa-public/containers/terraform-python-dynamic-webapp/server:v1.13.4"
ports:
- containerPort: 8080
protocol: TCP
env:
- name: PORT
value: "8080"
- name: DJANGO_ENV
valueFrom:
secretKeyRef:
name: server-secrets
key: DJANGO_ENV
- name: PYTHONPATH
valueFrom:
configMapKeyRef:
name: server-env
key: PYTHONPATH
- name: DJANGO_SETTINGS_MODULE
valueFrom:
configMapKeyRef:
name: server-env
key: DJANGO_SETTINGS_MODULE
- name: OTEL_METRICS_EXPORTER
valueFrom:
configMapKeyRef:
name: server-env
key: OTEL_METRICS_EXPORTER
- name: OTEL_TRACES_EXPORTER
valueFrom:
configMapKeyRef:
name: server-env
key: OTEL_TRACES_EXPORTER
- name: OTEL_PYTHON_EXCLUDED_URLS
valueFrom:
configMapKeyRef:
name: server-env
key: OTEL_PYTHON_EXCLUDED_URLS
- name: DEPLOYMENT_SUFFIX
valueFrom:
configMapKeyRef:
name: server-env
key: DEPLOYMENT_SUFFIX
livenessProbe:
httpGet:
path: "/healthy"
port: 8080
readinessProbe:
tcpSocket:
port: 8080
---
apiVersion: v1
kind: Service
metadata:
name: server
labels:
app.kubernetes.io/name: server
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: server
ports:
- name: p8080-tcp
port: 8080
targetPort: 8080
protocol: TCPImage, poort en health check overgenomen
Het containerimage en het liveness-pad /healthy komen rechtstreeks uit de service. De bron noemt geen poort, dus het concept gebruikt 8080, de standaard van Cloud Run, en voegt een readiness-controle op die poort toe.
Secret en omgeving gescheiden
DJANGO_ENV komt uit een Secret Manager-secret en wordt een verwijzing naar een Kubernetes-secret, server-secrets, dat u zelf aanmaakt. De vijf gewone variabelen worden de sleutels van de ConfigMap server-env; hun waarden neemt het concept niet over, die vult u in.
Eén cluster voor service en job
Het cluster stackit_ske_cluster.containers heeft een nodepool met de naam workloads. Machinetype en minimaal en maximaal aantal nodes zijn variabelen zonder standaardwaarde, en de zones staan standaard op eu01-1, eu01-2 en eu01-3. De migratiejob wordt een Kubernetes Job op hetzelfde cluster.
Aantal replica's vastgehouden, bereikbaarheid open
Het aantal pods is verplichte invoer, dus de apply blijft staan tot u het instelt: 0 voor de apply-stap, daarna het aantal dat de bron draait zodra de data is geladen. De Service is een ClusterIP en maakt nog niets bereikbaar: een Ingress of een Service van het type LoadBalancer, met certificaat en DNS-record, is uw beslissing.
Benoemd als niet overgenomen
Het serviceaccount van de revisie, de labels, de verkeersverdeling tussen revisies, de verwijderbeveiliging en het volume voor de Cloud SQL-verbinding. De pods draaien onder het standaard-ServiceAccount tot u de identiteit bepaalt, en bereiken de database via het netwerkadres.
Hoe de conversie werkt
Verwerk de omgeving
18 bestanden en de registermodule project_services 18.0.0 worden één afhankelijkheidsgraaf: 37 resources, 11 migratie-eenheden en 29 afhankelijkheden, offline gelezen. Vijf andere eenheden hangen van variabelen af en staan pas vast wanneer OpenTofu plant.
Beslis per resource
Een versiebeheerde regelbasis geeft elke resource een STACKIT-doel en een migratieklasse, op basis van de feitelijke configuratie en met een zekerheidsniveau.
Schrijf STACKIT-code
10 resourceblokken in bestanden per domein: data, Kubernetes, messaging, opslag, identiteit en beveiliging, plus 13 variabelen, Kubernetes-manifesten en de op 0.121.0 vastgezette STACKIT-provider. Vier eenheden worden voorgesteld als modules die uitgeschakeld blijven.
Controleer en herleid
StackToIT voerde zijn 20 conceptcontroles uit en geen enkele vond een overtreding. OpenTofu 1.13.1 draaide tofu init en tofu validate op het concept en accepteerde het. Elk blok draagt een trace-ID die terugleidt naar de bronresource.
Wat de run meldde
Geselecteerde regels van de samenvatting in de console van deze run, letterlijk.
Source files: 18
Resources scanned: 37 (34 in the root module · 3 inside 1 module call)
Migration units: 11 known-present (11 instances) · 5 conditional
Unit dependencies: 29
Modules: 1 module call (1 external, 0 local): 1 loaded, 0 not downloaded, 0 invalid
Source checks: Built-in source checks passed — OpenTofu validation of the source did not run (LOCK_FILE)
DIRECT 0
RECONFIGURE 6 ████████████████ 54%
REPLATFORM 2 █████ 18%
CONTAINERIZE 2 █████ 18%
REDESIGN 0
MANUAL_REVIEW 1 ██ 9%
BLOCKED 0 (the mapping class BLOCKED, not the execution blockers, which Migration readiness counts)
Confidence HIGH 0 · MEDIUM 10 · LOW 1
69 source properties checked across 11 generated units: 29 carried or explained, 40 NOT CARRIED, 0 unaccounted — see engineering/architect-report.md.
STACKIT draft (this folder/terraform): 11 units generated · 4 proposed, switched off · 0 need no resource · 1 left for the architect · 13 variables
StackToIT draft checks: PASSED (20 checks, none found a violation)
OpenTofu validation: PASSED (tofu init -backend=false and tofu validate accepted the draft; tofu 1.13.1)
tofu validate: STATIC_TERRAFORM_VALIDATION_PASSED — deployment readiness and live target behaviour not verified
Next action Allow the calls of STACKIT APIs that are not generally available — Owner: Platform Architect · details: index.html37 resources, 11 eenheden, 5 tijdens de planfase
34 resources staan in de rootmodule en 3 in de registermodule. Onderliggende resources horen bij de eenheid die ze dienen, en 8 ondersteunende resources worden gelezen door de eenheden die ze gebruiken. Vijf andere eenheden bestaan alleen als een variabele tijdens de planfase geldt; ze zijn ook beoordeeld en als zodanig gemarkeerd.
11 van de 16 eenheden in het concept
11 eenheden hebben gegenereerde STACKIT-resources, geschreven als 10 blokken. 4 zijn voorgesteld en blijven uitgeschakeld tot u beslist, en het Firebase-project blijft bij uw architect. Het concept heeft 13 variabelen.
69 eigenschappen, 0 onverklaard
29 eigenschappen zijn overgenomen of toegelicht en 40 zijn benoemd als niet overgenomen, in het bestand engineering/not-carried.csv. De controle omvat de 11 gegenereerde eenheden.
Een klasse voor elke eenheid
De run bepaalde 6 keer RECONFIGURE, 2 keer REPLATFORM, 2 keer CONTAINERIZE en 1 keer MANUAL_REVIEW, en assessment.json geeft de reden per eenheid.
De eerstvolgende actie heeft een eigenaar
Het plan telt 78 stappen. 10 van de 12 geautomatiseerde stappen zijn vrij van beslissingen en wachten alleen op waarden zoals project_id. 6 beslissingen staan open; de eerste, bij de Platform Architect, is het toestaan van STACKIT-API's die niet algemeen beschikbaar zijn. 27 invoerverzoeken staan open.
Hoe de 11 eenheden en de 5 uit de planfase zijn bepaald
| Google Cloud-bron | STACKIT-concept | Klasse |
|---|---|---|
| google_sql_database_instance.postgres | stackit_postgresflex_instance, versie 14, flavor 2.4 | Replatforming |
| google_pubsub_topic.faux | stackit_rabbitmq_instance, gedeeld: het topic wordt een exchange, handmatig aangemaakt in RabbitMQ | Replatforming |
| google_cloud_run_v2_service.server | Kubernetes Deployment, ConfigMap en Service op stackit_ske_cluster.containers | Containerisatie |
| google_cloud_run_v2_job.migrate | Kubernetes Job op hetzelfde cluster | Containerisatie |
| google_secret_manager_secret.django_settings | stackit_secretsmanager_instance.migrated_secrets, gedeeld | Herconfiguratie |
| google_secret_manager_secret.django_admin_password | Dezelfde stackit_secretsmanager_instance; de waarden schrijft een API-stap, ze worden nooit gekopieerd | Herconfiguratie |
| google_storage_bucket.media | stackit_objectstorage_bucket.media; de objecten worden met rclone gekopieerd | Herconfiguratie |
| google_service_account.server | stackit_service_account.server | Herconfiguratie |
| google_service_account.client | stackit_service_account.client | Herconfiguratie |
| google_service_account.automation | stackit_service_account.automation | Herconfiguratie |
| google_firebase_project.default | Geen STACKIT-doel: STACKIT heeft geen backendplatform voor mobiele apps of webapps, uw architect beslist per app | Beslissing van de architect |
| google_service_account.init (bepaald tijdens de planfase) | stackit_service_account.init | Herconfiguratie |
| google_cloudbuild_trigger.activategcb (bepaald tijdens de planfase) | Voorgesteld, uitgeschakeld: een workflow in STACKIT Git Pipelines of uw eigen CI/CD | Redesign |
| google_cloudbuild_trigger.init (bepaald tijdens de planfase) | Voorgesteld, uitgeschakeld: een workflow in STACKIT Git Pipelines of uw eigen CI/CD | Redesign |
| google_cloudbuild_trigger.placeholder (bepaald tijdens de planfase) | Voorgesteld, uitgeschakeld: een workflow in STACKIT Git Pipelines of uw eigen CI/CD | Redesign |
| google_firebase_hosting_site.client (bepaald tijdens de planfase) | Voorgesteld, uitgeschakeld: Object Storage als origin van een CDN-distributie met een eigen domein | Redesign |
Klassen zoals de run ze bepaalde. De eerste 11 rijen zijn de eenheden die in de bron staan; de laatste 5 bestaan alleen als een variabele geldt wanneer OpenTofu plant, en die geldt met de standaardwaarden van deze run.
Wat in terraform/ terechtkomt
De STACKIT-Terraform van deze run, ingedeeld zoals een platformteam het onderhoudt.
- data.tf
- PostgreSQL Flex-instance voor de Cloud SQL-instance
- kubernetes.tf
- Eén SKE-cluster met een nodepool voor de Cloud Run-service en -job
- kubernetes/
- Manifesten voor server (ConfigMap, Deployment, Service) en migrate (Job)
- messaging.tf
- RabbitMQ-instance voor het Pub/Sub-topic
- rabbitmq/
- Topologiebestand en script voor exchanges en queues, die de provider niet aanmaakt
- storage.tf
- Object Storage-bucket voor de mediabucket
- identity.tf
- De 4 serviceaccounts
- security.tf
- Secrets Manager-instance en de migratiegebruiker die de secrets schrijft
- proposals.tf, proposals/
- 8 modules, elk achter een schakelaar die uit blijft tot u beslist
- handover/
- Voorbereidende notities voor de databaseverhuizing, de mediakopie en de clustertoegang
- variables.tf
- De 13 waarden die uw team instelt of bevestigt, elk met een beschrijving
- terraform.tf
- Vastgezette STACKIT-provider
- README.md
- Wat het concept bevat, welke diensten u eerst inschakelt, de beveiligingschecklist en wat niet wordt overgenomen
Wat met de Terraform meekomt
Dezelfde run schrijft het materiaal waarmee uw architecten en beheerders werken.
- assessment.json
- Per eenheid: klasse, zekerheidsniveau, STACKIT-doel, reden en bevindingen
- engineering/not-carried.csv
- De 40 eigenschappen die het concept niet overneemt, één rij per eigenschap, met de reden
- engineering/trace/
- Eén tracebestand per conceptbestand, van elk blok terug naar de bron
- architecture/
- Diagrammen van de huidige en de doelarchitectuur, de netwerkbeveiliging en de datastromen
- migration/technical-sequencing.md
- 4 golven, berekend uit de afhankelijkheden tussen eenheden
- execution/
- Het uitvoeringspakket: 24 werkpakketten met 64 handmatige stappen, 2 API-stappen, een deploymentscript en een pipelinevoorbeeld
- decisions.json
- Het gestructureerde beslissingsregister, met in deze run 6 te nemen beslissingen
- financial/
- Prijsregels en dekking: 2 van 8 STACKIT-regels geprijsd, geen vergelijking opgenomen
- review/
- Templates voor uw antwoorden en doelwaarden, die de volgende run inleest
Bewezen op een echte Google Cloud-omgeving
De Dynamic Python Web App van Google Cloud, een openbaar Terraform-project van Google, door StackToIT beoordeeld en volledig gepubliceerd, precies zoals de run het heeft opgeleverd.
Casestudy bekijken (Engels)- 37
- Terraform-resourcedeclaraties geanalyseerd
- 11
- migratie-eenheden geïdentificeerd
- 11
- doeleenheden gegenereerd, van de 16 onderzochte eenheden
- 78
- planstappen uitgeschreven
Vragen van platformteams
Converteert StackToIT Terraform-modules?
Ja. StackToIT verwerkt registermodules en lokale modules. Deze omgeving roept één registermodule aan, project_services 18.0.0, die de run samen met de rootmodule downloadde en las: de 3 resources ervan horen bij de 37 en vormen geen eigen migratie-eenheid.
Werkt het met OpenTofu?
Ja. StackToIT leest Terraform- en OpenTofu-rootmodules. In deze run draaide OpenTofu 1.13.1 tofu init -backend=false en tofu validate op het STACKIT-concept en beide slaagden. Dat is statische validatie tegen het vastgezette providerschema; er is geen plan uitgevoerd tegen een STACKIT-project.
Wat gebeurt er met een Cloud Run-service en -job?
STACKIT kent geen Cloud Run. De run deelt de service server en de job migrate in als CONTAINERIZE: beide worden Kubernetes-workloads op één SKE-cluster. Image, poort, health check en secretverwijzingen worden overgenomen; machinetype, aantal nodes en aantal pods zijn invoer, en wie de service mag aanroepen bepaalt een mens.
Wat gebeurt er met Pub/Sub?
Het topic wordt een exchange op een gedeelde STACKIT RabbitMQ-instance (REPLATFORM), de subscriptions worden queues. Namen, aflevering, bewaartermijn en push-instellingen worden niet gegenereerd; een topologiebestand en een script zijn bijgeleverd. Twee API-stappen, voor de RabbitMQ-topologie en voor Secrets Manager, roepen STACKIT-API's aan die de run als voorlopige versie behandelt (de messaging-API is een voorlopige versie, de Secrets Manager-API vermeldt geen releasestatus). Het plan voert ze daarom pas uit na uitdrukkelijke toestemming.
En Firebase?
Het Firebase-project is ingedeeld als MANUAL_REVIEW. Geen van de 115 resourcetypen van de vastgezette STACKIT-provider is een backendplatform voor mobiele apps of webapps (gecontroleerd op 5 november 2026), dus een mens beslist per app welke backend de Firebase-diensten vervangt. De hostingsite wordt voorgesteld als Object Storage achter een CDN-distributie en blijft uitgeschakeld.
Wat gebeurt er met het databasewachtwoord?
Dat wordt niet gekopieerd. STACKIT genereert het wachtwoord van de PostgreSQL Flex-gebruiker en u geeft het nieuwe wachtwoord door aan de applicatie.
Waarom is het zekerheidsniveau beperkt tot MEDIUM?
De repository bevat geen .terraform.lock.hcl en beperkt google tot ">= 6, < 8", wat de release 8.4.0 uitsluit waartegen de kennisbank is gecontroleerd. De OpenTofu-validatie van de bron draaide daarom niet, en elke eenheid blijft op zekerheidsniveau MEDIUM of lager. De oplossing staat erbij: commit het lockbestand dat tofu init schrijft en draai opnieuw.
Is er een prijsvergelijking?
Niet in deze run. De prijscache bevat geen Google Cloud-prijs, dus het rapport noemt geen besparing. 2 van de 8 STACKIT-regels zijn geprijsd, 164,67 EUR per maand als gedeeltelijk bedrag tegen lijstprijzen, en het rapport toont de opdrachten waarmee u de ontbrekende prijzen ophaalt.
Hoe herhaal ik de run?
Kloon de upstream-repository op commit 7c9e8fb, maak een variabelenbestand met de ene regel project_id = "example-project" en draai stacktoit assess in de map infra: stacktoit assess . ../../run-python-webapp --var-file ../../example.tfvars. Draai daarna stacktoit verify op de uitvoermap; bij de gepubliceerde kopie komen 146 bestanden overeen met manifest.json.
Wie past de STACKIT-Terraform toe?
Uw team, via uw eigen pipeline, nadat uw architecten het concept hebben beoordeeld. StackToIT wijzigt niets in welke cloud dan ook; de regiovariabele staat standaard op eu01 en is de ene standaardwaarde die het rapport door een mens laat bevestigen.
Bronnen
- StackToIT-voorbeeld: Google Cloud Dynamic Python Web App, de volledige run
- GitHub: GoogleCloudPlatform/terraform-dynamic-python-webapp (Apache-2.0, vastgezette commit)
- STACKIT-documentatie: Terraform-provider
- STACKIT-documentatie: PostgreSQL Flex
- STACKIT-documentatie: Kubernetes Engine
- STACKIT-documentatie: RabbitMQ
- Google Cloud-documentatie: introductie van Cloud SQL
- Google Cloud-documentatie: wat is Cloud Run
Uw volgende stap: STACKIT.
Vertel ons over uw omgeving, dan laten wij zien wat StackToIT daarvoor oplevert: doelarchitectuur, Terraform-artefacten en een gestructureerd migratieplan.
Laat uw gegevens achter, onze specialisten nemen contact met u op.
Liever zelf een e-mail sturen? connect@stacktoit.com
Hartelijk dank.
Uw verzoek is bij ons binnengekomen. Onze specialisten nemen contact met u op.