This is a personal lab writeup, not a claimed production project. I set it up to practice the workflow and tooling involved in a VM-to-Kubernetes migration, using a small sample service rather than a real company's infrastructure.

Goal

Get hands-on with the pieces that make up a typical Kubernetes migration, end to end:

  1. Provision an EKS cluster with Terraform instead of clicking through the AWS console.
  2. Package the service with Helm so config is versioned and repeatable.
  3. Wire up ArgoCD for GitOps-style deployment instead of manual kubectl apply.
  4. Add Prometheus and Grafana for cluster and application metrics.
  5. Run the pipeline through GitHub Actions so image builds and Helm releases are automated.

What I practiced

  • Writing Terraform modules for VPC, subnets, and an EKS control plane, and tearing it down cleanly afterward (terraform destroy) to avoid runaway AWS costs on a personal account.
  • Structuring a Helm chart with separate values files per environment, and using helm diff to review changes before they hit the cluster.
  • Pointing ArgoCD at a Git repo and watching it reconcile drift instead of trusting manual deploys.
  • Setting resource requests/limits and a basic HorizontalPodAutoscaler, then load-testing to see when pods actually scaled.
  • Hooking up the kube-prometheus-stack and building a couple of Grafana dashboards for pod restarts and request latency.

What I'd still want to test on a real workload

  • Zero-downtime cutover strategies (blue/green vs. canary) under real traffic, not synthetic load.
  • Database migration alongside the app — stateful services are the part this lab skipped entirely.
  • Cost comparison against the VM baseline with real numbers, not estimates.

Notes for next time

Terraform state management got messy once I started iterating quickly — next time I'd set up remote state with locking from the start instead of retrofitting it. ArgoCD's health checks also needed tuning for a custom readiness probe; the defaults reported "healthy" before the app was actually ready to take traffic.