Skip to content
← All insights

Case study · Logistics SaaS platform (anonymized)

Migrating a monolith to EKS without a maintenance window

How a logistics platform moved from hand-managed EC2 to Kubernetes incrementally, keeping deploys running throughout.

CodeCirrus · · 2 min read

Results

  • Deploy time cut from ~40 minutes to under 6
  • Environment rebuild from code in ~25 minutes
  • Zero customer-facing downtime during cutover

Placeholder content. This case study is a structural template. Replace the client details, numbers, and narrative with a real engagement before publishing.

Context

The client ran a Rails monolith and four supporting services on EC2 instances that had been configured by hand over five years. Deploys were a Capistrano script one engineer knew how to run, and staging had drifted so far from production that it had stopped being a useful test.

The ask was Kubernetes. The actual problem was that nobody could recreate the environment.

Approach

We deliberately did not start with the migration.

First, we made production reproducible. Before moving anything, we captured the existing infrastructure in Terraform and stood up a parallel environment from that code. This surfaced eleven configuration details that existed only on the running instances - cron jobs, a patched gem, firewall rules added during an incident two years earlier.

Then we containerized the smallest service. Not the monolith. A background worker with no inbound traffic, where a bad rollout meant a delayed job rather than a customer-visible error. That service proved out the image build, the registry, the deployment manifests, and the observability wiring end to end.

Then we moved traffic gradually. The monolith ran on EC2 and EKS simultaneously behind the same load balancer, with a weighted target group. We shifted 5% of traffic, watched error rates and latency for a week, and increased from there. At any point the rollback was a weight change.

Finally, we deleted the old path. The EC2 autoscaling groups came down only after two weeks at 100% on EKS, and the Capistrano scripts were removed from the repository in the same pull request that documented the new deploy process.

What made it work

The weighted cutover was the technically interesting part, but the reproducibility work done first is what made it safe. Once the environment could be rebuilt from code, every subsequent step had a tested rollback.

The other decision that paid off was resisting the urge to modernize the application at the same time. The monolith that went into containers was the same monolith, with the same bugs. Mixing a platform migration with an application rewrite means that when something breaks, you cannot tell which change caused it.

Outcome

Deploys moved from a 40-minute ritual to a 6-minute pipeline that any engineer on the team can run. Staging is now rebuilt from the same modules as production, which ended the class of bug that only appeared after release.

The handover included runbooks for scaling, rollback, and incident triage, plus two working sessions with the client's engineers. They have run the platform without us since.