The problem
A product platform of 40+ microservices was running on hand-managed EC2 virtual machines. Deployments were SSH-and-pray, scaling was manual, and every release carried downtime risk. The business requirement was blunt: move everything to Kubernetes without a single minute of customer-facing downtime — the platform processed live transactions around the clock, so there was no maintenance window to hide behind.
The approach
Infrastructure as Code first. Before any workload moved, I built the target EKS environment entirely in Terraform — VPC, node groups, IAM roles for service accounts, cluster add-ons. Nothing was clicked together in a console, so the whole environment could be reviewed, reproduced, and torn down.
GitOps as the deployment backbone. ArgoCD was installed as the single path to production. Every service got a Helm chart and an Argo Application; the Git repository became the source of truth, which meant rollback was a git revert, not an emergency SSH session.
Strangler-pattern cutover. Services moved one at a time behind the existing load balancer using weighted routing. Each service ran in both environments simultaneously while traffic shifted 5% → 25% → 50% → 100%, with error-rate and latency dashboards gating every step. Any regression automatically shifted weight back to the VMs.
Stateful services last. Databases and queues were migrated with replication established ahead of cutover, so the switch was a failover measured in seconds, rehearsed twice in staging before production.
The outcome
- 40+ services migrated, 0 minutes of downtime — no customer-facing
interruption across the entire program.
- Deploy frequency went from weekly, high-ceremony releases to on-demand
merges through ArgoCD.
- Autoscaling replaced capacity guesswork; the old VM fleet was decommissioned,
cutting the compute bill materially.
- The team inherited runbooks, dashboards, and a rehearsed rollback procedure —
the migration left them more operable, not just newer.