Runnable replatform example for STACKIT: migrate a Spring Boot workload to SKE with DNS and Observability.
- Optional target project creation
- SKE cluster (small default node pool)
- DNS zone and external-dns integration
- STACKIT Observability instance
- Spring Boot Deployment + Service (LoadBalancer)
- Optional Horizontal Pod Autoscaler (HPA) for Spring Boot
- Metrics exporter sidecar on port 9090
- Observability scrape config for Spring Boot metrics
- Grafana dashboard import
- Optional load-generator pod
- Terraform >= 1.5
- Service account key file
- Required permissions for SKE, DNS, Observability, and optional project creation
Copy the example file:
cp env.tfvars.example env.tfvarsThen edit env.tfvars.
target_project_owner_emailparent_container_idske_cluster_nameobservability_instance_namedns_zone_namedns_zone_display_name
target_project_owner_email: service account or owner email used for project creationparent_container_id: folder/container ID (forcreate_project = true)ske_cluster_name: max 11 charactersobservability_instance_name: unique readable instance namedns_zone_name: delegated DNS zone (for examplecmf-1234.runs.onstackit.cloud)dns_zone_display_name: display name for the DNS zone resource
service_account_key_pathtarget_project_nameregion,availability_zonenode_pool_machine_typespringboot_imageenable_springboot_hpa,springboot_hpa_*enable_load_generator,load_profile
For replatformed workloads on SKE, rightsizing can be applied at multiple layers:
- Pod layer: adjust requests/limits and optionally enable HPA.
- Node pool layer: tune node pool min/max and machine type.
- Storage layer: choose suitable storage classes for persistence characteristics.
Set in env.tfvars:
enable_springboot_hpa = true
springboot_hpa_min_replicas = 1
springboot_hpa_max_replicas = 5
springboot_hpa_target_cpu_utilization_percentage = 70Then apply:
terraform apply -var-file=env.tfvarsterraform init
terraform validate
terraform plan -var-file=env.tfvars
terraform apply -var-file=env.tfvarsmkdir -p .tmp
terraform output -raw kubeconfig > .tmp/replatform.kubeconfig
export KUBECONFIG=$PWD/.tmp/replatform.kubeconfig
kubectl get ns
kubectl get deploy,svc -n springboot
kubectl get pods -n springbootHOST=$(terraform output -raw springboot_hostname)
curl -sS "http://$HOST:9090/metrics" | head -n 30Expected: lines beginning with springboot_legacy_counter, springboot_legacy_gauge, springboot_legacy_metric.
terraform outputImportant outputs:
springboot_urlspringboot_hostnameobservability_grafana_urlproject_id
- If
metrics-exporterrestarts, inspect logs:
POD=$(kubectl get pod -n springboot -l app=springboot -o jsonpath='{.items[0].metadata.name}')
kubectl logs -n springboot "$POD" -c metrics-exporter --tail=200
kubectl logs -n springboot "$POD" -c metrics-exporter --previous --tail=200- If scrape exists but no data arrives, check target health in Prometheus/Grafana datasource (
up{job="<scrape-job>"}). - Scrape interval must be greater than
60sfor this environment (61sis set by default).
terraform destroy -var-file=env.tfvars