Migrate a Kubernetes application to GCP from AWS
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Migrating a Kubernetes application from AWS to GCP is rarely just a matter of copying YAML from one cluster to another. The Kubernetes objects may be portable, but the surrounding storage, load balancing, IAM, DNS, observability, and CI assumptions are often cloud-specific. A clean migration starts with separating what is cluster-portable from what depends on AWS services, then planning a controlled cutover to GKE.
Start With an Inventory, Not a Cluster Create Command
Before creating anything in GCP, inventory the current application in AWS.
You need to know:
- namespaces and releases
- Deployments, StatefulSets, Services, Ingresses, and Jobs
- ConfigMaps and Secrets
- PersistentVolumeClaims and storage classes
- external dependencies such as RDS, S3, Route 53, IAM, and ECR
- CI pipelines and image registries
Useful commands for a first pass are:
This reveals which parts are Kubernetes-native and which parts are really AWS integrations hiding behind them.
Build the Target Environment in GCP
On the GCP side, prepare the target project, VPC, IAM model, container registry strategy, and GKE cluster before moving workloads.
A basic cluster creation flow can start from the CLI:
Then fetch credentials:
That only gives you a cluster. It does not yet solve ingress, DNS, secrets, storage classes, or image delivery.
Replace AWS-Specific Assumptions
This is where most migrations actually succeed or fail.
Examples of AWS-specific items that often need changes:
- EBS-backed storage classes must become GCE PD or another GKE-compatible class.
- Classic ELB or AWS ALB controller assumptions may need GKE Ingress or another ingress controller.
- IAM roles for service accounts may need a GCP Workload Identity design.
- ECR image references may need to move to Artifact Registry or another accessible registry.
- Route 53-driven DNS automation may need a GCP equivalent or a cross-cloud design.
A storage class reference that worked in EKS may need to change in a manifest or Helm values file:
Likewise, image references may need to change:
Move Data Separately From Deployments
Stateless services are usually the easy part. Stateful migration is the real project.
If your application relies on databases, object storage, or persistent volumes, migrate that data with its own plan. Do not treat data cutover as an afterthought.
A practical approach is often:
- stand up the GKE environment
- mirror or migrate the backing data store
- deploy the application against a staging copy
- validate behavior under load
- perform final sync and cut over production traffic
For Kubernetes resource backup and restore, tools such as Velero can help with cluster object migration. For databases, use database-native migration tooling rather than hoping PVC copies are enough.
Test Before DNS Cutover
A migration is not complete when pods are running. It is complete when traffic, secrets, storage, and observability work end to end.
Before switching DNS:
- test external connectivity and ingress
- verify service discovery and health checks
- confirm logs and metrics land in the expected destination
- run smoke tests and representative workload tests
- validate rollback steps
A common low-risk cutover is to reduce DNS TTL in advance, deploy the GKE stack, then switch traffic only after verification passes.
Use Helm or GitOps to Make the Move Repeatable
If the application is already managed by Helm or a GitOps flow, update that source of truth instead of hand-editing manifests on the destination cluster.
That usually means maintaining environment-specific values files such as:
Then deploy with:
This keeps the migration auditable and makes future cluster rebuilds much easier.
Common Pitfalls
The most common mistake is assuming Kubernetes portability means cloud portability. The YAML may be similar, but storage, networking, and IAM usually are not.
Another mistake is migrating stateless deployments first and discovering too late that the data plane still depends on AWS-specific services.
Teams also often skip a rollback plan. If cutover fails, you need to know whether traffic returns to AWS, how data divergence is handled, and who makes that decision.
Finally, do not leave observability for last. A migrated workload without logs, metrics, and alerts is much harder to stabilize under real traffic.
Summary
- Treat the migration as an application-platform move, not just a manifest copy.
- Inventory cloud-specific dependencies before building the GKE target.
- Replace AWS storage, ingress, IAM, registry, and DNS assumptions explicitly.
- Migrate stateful data with its own plan and validate before cutover.
- Use Helm or GitOps so the new GCP deployment remains reproducible.

