Overview
Section titled “Overview”This architecture maps the VM-based Spring Boot and PostgreSQL source to a Kubernetes runtime and managed database on STACKIT. The same application JAR is retained while provisioning, deployment, traffic management, data recovery, and operational responsibilities change.
The reference baseline uses one SKE worker and PostgreSQL Flex, with Envoy Gateway, STACKIT DNS, and Observability. It does not deploy the additional services or multi-zone topology shown in the optional extension pattern below.
Typical use case
Section titled “Typical use case”- Runtime standardization: replace a systemd-managed Java process with a reproducible Deployment and health checks.
- Database operations: move PostgreSQL to a managed service without redesigning the application schema.
- Controlled platform change: qualify rollout, scaling, network access, and recovery independently before production acceptance.
Architecture diagram
Section titled “Architecture diagram”Runtime and data boundaries
Section titled “Runtime and data boundaries”An init container verifies the commit-pinned JAR checksum before Java starts. Application containers are replaceable: authoritative album data lives in PostgreSQL Flex, not in a pod filesystem or Kubernetes PersistentVolume. Kubernetes Secrets inject database credentials; an external Secret Manager integration is not implemented in this baseline.
The Flex ACL defaults to actual SKE egress CIDRs. Both application and migration client require encrypted database connections. The migration client uses an isolated rehearsal database and only replaces the application data after explicit approval and a verified pre-cutover backup. No source-VM database connection or temporary public Flex ACL is required for the dump-based path.
Traffic and observability
Section titled “Traffic and observability”Terraform installs Envoy Gateway and then a local routing chart. The application Service is ClusterIP; Envoy supplies the public LoadBalancer. SKE-managed ExternalDNS publishes the HTTPRoute hostname from the Gateway address. This is Gateway API, not a legacy Ingress controller or a separately provisioned STACKIT Application Load Balancer service.
HTTP is the tested default. For HTTPS, supply a trusted TLS Secret and configure
gateway_tls_secret_name according to the repository procedure; certificate issuance and
renewal remain external responsibilities. The separate metrics listeners are public and
unauthenticated in the reference and require protection before sensitive use.
Boot 2 Actuator binds to pod-local loopback; the metrics adapter exposes selected measurements. The PostgreSQL exporter and the SKE monitoring integration feed Observability. Terraform creates the Grafana folder and dashboard, but dashboard availability alone does not establish application health, scrape continuity, or working alert delivery.
Availability and recovery decisions
Section titled “Availability and recovery decisions”The tested worker count, HTTP endpoint, and sample application are a functional baseline, not an HA production architecture. Select a supported SKE release and suitable zone capacity. Assess multiple workers, zone distribution, workload disruption budgets, replica safety, database availability, and the traffic layer as separate design decisions with failure tests.
Database rollback restores the pre-cutover target, while Flex managed backups serve service recovery. Neither automatically redirects users to the source VM. Define write ownership, traffic-switch authority, rollback deadline, retention, and recovery objectives before migration.
Optional extension pattern
Section titled “Optional extension pattern”The following broader design illustrates possible additions, not resources created by the reference Terraform. Additional node pools, topology rules, persistent volumes, RabbitMQ, Object Storage, and Secret Manager need their own implementation, ownership, and validation. Use them only for a demonstrated workload requirement; do not infer HA from this diagram.
Design best practices
Section titled “Design best practices”- Decouple runtime and data migration gates: validate database migration and runtime rollout independently.
- Design secret delivery explicitly: the reference uses Kubernetes Secrets and protected Terraform state; add a reviewed external secret integration when required.
- Standardize observability labels and dashboards: make cross-application operation and incident handling consistent.
- Keep RabbitMQ optional and explicit: add it when asynchronous integration or buffering is required.
- Qualify availability separately: a multi-zone design needs suitable worker capacity, placement rules, disruption budgets, and application and database failure testing; it is not enabled by the baseline.
Related migration assets
Section titled “Related migration assets”Repository usage and required settings
Section titled “Repository usage and required settings”- Copy the example file:
cp env.tfvars.example env.tfvars - Set required identity/project values:
service_account_key_path = "/path/to/stackit-sa-key.json"create_project = truetarget_project_owner_email = "owner@sa.stackit.cloud"parent_container_id = "cmf-parent-container-id"ske_cluster_name = "rpltfk8s01"observability_instance_name = "cmf-rpltf-observability"dns_zone_name = "cmf-example.runs.onstackit.cloud"dns_zone_display_name = "cmf-example"- Enable the target architecture switches:
observability_enabled = truecreate_observability_instance = truedns_enabled = truecreate_dns_zone = truedeploy_workload = trueenable_postgres_flex = trueenable_springboot_hpa = falseenable_load_generator = falsespringboot_replicas = 1deploy_postgres_migration_job = falsecreate_grafana_dashboard = true- Optional CMF flag wrapper (
flags.env):
setup_project=truesetup_observability=truesetup_database=truesetup_workload=truesetup_loadgen=falsesetup_dns=true- Apply:
terraform initterraform validateterraform plan -var-file=env.tfvars -out=tfplanterraform apply tfplanExpected result: springboot_url reaches the application through the Gateway, the application
uses PostgreSQL Flex, and grafana_dashboard_url opens the managed dashboard. Provisioning
does not import source data. Follow the separate rehearsal and cutover workflow after target
validation; keep HPA disabled throughout migration.
Asset historyActive 5 of the last 12 weeksLWUpdatedNo updates · 1 bar = 1 week i
- LWLukas WeberrußHead of STACKIT Cloud Migration Framework · STACKITOwner
Lukas WeberrußHead of STACKIT Cloud Migration Framework · STACKITOwnerActive 10 of the last 12 weeks · 47 updateswww.linkedin.com/in/lukas-weberruß-a360b081