Phased Cloud Migration: The 5-Layer Tool Stack That Keeps Deploys Fast and Uptime Boring

A tool-by-tool guide to running a phased migration off your current platform provider: what to use for provisioning, delivery, traffic cutover, data replication, and developer self-service - and how to keep deployment frequency high while both stacks run in parallel.

Romaric Philogene
CEO & Co-founder
AUG 31, 2026 · 17 MIN
Phased Cloud Migration: The 5-Layer Tool Stack That Keeps Deploys Fast and Uptime Boring

Key Points:

  • A phased cloud migration needs five tool layers, and most plans staff four of them: infrastructure provisioning (OpenTofu, Terraform, Pulumi, Bicep, CDK), continuous delivery (Argo CD, Flux, GitHub Actions), traffic and DNS cutover (Route 53 weighted routing, Google Cloud Load Balancing traffic splitting, Azure Traffic Manager, Argo Rollouts), and data replication (AWS DMS, Google Database Migration Service, Azure Database Migration Service). The fifth layer, developer self-service, is the one that decides whether velocity survives.
  • Move in waves behind a routing layer using the strangler-fig pattern: one service or one environment at a time, both stacks live, rollback performed by shifting traffic rather than redeploying. The AWS 7 Rs guidance, Google Cloud's assess-plan-deploy-optimize path, and the Microsoft Cloud Adoption Framework all describe the same wave-based shape.
  • Deployment velocity collapses before uptime does. Developers lose the git-push workflow their old platform gave them and start filing tickets for every environment, so track DORA deployment frequency and lead time for change from wave 0, not just error rate and p95 latency.
  • An internal developer platform covers the fifth layer. Qovery runs inside your own AWS, GCP, Azure, or Scaleway account, or your existing Kubernetes cluster, and gives developers git-push deploys, per-pull-request preview environments, environment auto-stop, and per-environment RBAC while the migration is still half finished.
  • Budget 2 to 4 months of double-running and at least one full billing cycle of parallel operation before you decommission anything. Cutover should be a traffic decision, not a deployment decision, because that is what makes rollback cheap enough to actually use.

Qovery · Agentic Infrastructure Platform
Kubernetes, operated through one governed API
Learn more

Most cloud migrations do not fail on uptime. They fail on velocity. The team keeps the old stack alive, shifts traffic carefully, and the error graphs stay flat. What quietly breaks is shipping speed: developers trade a self-service platform for raw cloud primitives and a ticket queue, and deploy frequency falls off a cliff before anyone notices.

I have spent years running Kubernetes in production and talking to hundreds of CTOs about exactly this move, and the answer to "what services can help us execute a phased migration while keeping reliability and velocity high" is not one tool. You need five layers: provisioning, delivery, traffic, data, and developer self-service. No single vendor covers all five. Most plans staff the first four and forget the fifth, then wonder why engineers are slower on the shiny new cloud than they were on the platform they left.

Here is the concrete tool map for each layer, how to sequence the waves, what it costs, and where the reliability traps are.

What does a phased cloud migration actually look like in practice?

A phased cloud migration moves workloads in numbered waves behind a stable routing layer, with the old and new stacks running in parallel and rollback available at every wave. There is no weekend cutover. Each wave has written numeric exit criteria agreed before it starts, and traffic shifting, not redeployment, is the rollback mechanism.

Order the waves by blast radius: internal stateless services first, then customer-facing stateless services, then stateful services and data last. The mechanism that makes this safe is the strangler-fig pattern, where a routing layer (weighted DNS, a load balancer, or a gateway) decides what fraction of traffic reaches the new stack, so a rollback is a routing change measured in minutes rather than a redeploy (Martin Fowler, Microsoft).

Every major cloud publishes the same wave-based shape. AWS documents seven migration strategies, the 7 Rs: retire, retain, rehost, relocate, repurchase, replatform, and refactor or re-architect (AWS). Google Cloud documents four phases: assess, plan, deploy, and optimize (Google Cloud). The Microsoft Cloud Adoption Framework covers the same ground and explicitly recommends migrating in iterations, or waves, rather than all at once (Microsoft).

Set explicit numeric exit criteria per wave: error rate, p95 latency, deployment frequency, lead time for change, cost delta, and pages per week. The parallel-run period between "new stack live" and "old stack decommissioned" costs real money because you are paying for both. Budgeting for it up front is exactly what prevents a rushed cutover that breaks uptime.

FrameworkPhase names as publishedWhat happens in that phaseArtifact a phased team should producePrimary source
AWS 7 Rs strategiesRetire, retain, rehost, relocate, repurchase, replatform, refactorEach application is assigned one of seven disposition strategies before it is touchedA per-application disposition list mapping every workload to one RAWS Prescriptive Guidance
AWS Migration Acceleration ProgramAssess, mobilize, migrate and modernizeReadiness assessment, then a migration foundation and landing zone, then the waves themselvesA migration readiness assessment and a wave plan with landing zoneAWS
Google Cloud migration pathAssess, plan, deploy, optimizeInventory and assess, build the base cloud infrastructure, move workloads, then optimizeA workload inventory plus a landing zone and a deployment runbookGoogle Cloud
Microsoft Cloud Adoption FrameworkPlan, ready, adopt (migrate and modernize), govern, managePlan the portfolio, prepare the environment, migrate in iterations, then govern and operateAn iteration-based migration backlog and a governance baselineMicrosoft

Which services and tools do you actually need for each layer of the migration?

Map every migration task to one of five layers - provisioning, delivery, traffic, data, and developer self-service - and choose exactly one tool per layer. No single vendor covers all five, and plans go wrong when a team assumes their infrastructure-as-code tool or their hyperscaler migration service quietly covers the other four. It does not.

Provisioning is OpenTofu or HashiCorp Terraform, with Pulumi, AWS CloudFormation and CDK, Google Cloud Config Controller, and Azure Bicep as strong alternatives. OpenTofu is the Linux Foundation fork created after HashiCorp moved Terraform to the source-available BUSL 1.1 license in August 2023 (HashiCorp); it stays drop-in compatible with Terraform's HCL, provider protocol, and state model and shipped its first stable release, 1.6, in January 2024 (OpenTofu).

Delivery is GitOps reconciliation plus pipelines. Argo CD and Flux are the two mature choices, both CNCF graduated projects: the Argo project graduated in December 2022 (CNCF) and Flux graduated in November 2022 (CNCF). Pair either with GitHub Actions or GitLab CI for build pipelines and Helm or Kustomize for packaging.

Traffic and cutover is the routing layer that makes rollback cheap: Route 53 weighted routing policy (AWS), Google Cloud Load Balancing traffic splitting (Google Cloud), Azure Traffic Manager weighted routing (Microsoft), Istio or Linkerd for mesh-level shifting, and Argo Rollouts for canary and blue/green with automated rollback on analysis failure (Argo Rollouts).

Data is change data capture. AWS Database Migration Service, Google Database Migration Service, and Azure Database Migration Service all document continuous replication for minimal-downtime moves (AWS, Google Cloud, Microsoft). Dual-write is the alternative pattern, and it trades operational simplicity for a real risk of divergence if a write succeeds on one side and fails on the other.

Treat observability as the referee: Prometheus and Grafana, OpenTelemetry, Datadog, or cloud-native monitoring. Baseline the old platform's SLOs before wave 1 or you have nothing to compare against. The fifth layer, developer self-service, gets its own section below, because both infrastructure-as-code and GitOps assume the manifests already exist and that someone owns them.

LayerThe problem it solvesLeading optionsWhat that layer does NOT solveWho owns it during the migration
ProvisioningDeclares the cloud infrastructure so it is reproducible and reviewableOpenTofu, Terraform, Pulumi, AWS CloudFormation and CDK, Azure BicepDoes not deploy your application code or give developers a workflowPlatform or infrastructure team
Continuous deliveryReconciles what is running against what is in GitArgo CD, Flux, GitHub Actions, GitLab CIDoes not author the manifests or manage environments for developersPlatform team, with developers contributing manifests
Traffic and cutoverShifts a controllable fraction of traffic to the new stackRoute 53 weighted routing, Google Cloud Load Balancing, Azure Traffic Manager, Argo RolloutsDoes not replicate your data or keep the two databases consistentPlatform and networking owners
Data replicationMoves and keeps databases in sync with minimal downtimeAWS DMS, Google Database Migration Service, Azure DMSDoes not provision compute or give developers a deploy workflowData and platform teams together
Developer self-serviceLets developers deploy, preview, and roll back without ticketsAn internal developer platform (covered in its own section below), or a platform you build on top of the four layers aboveDoes not replace bespoke infrastructure-as-code or move your dataPlatform team, consumed by every developer

Why does deployment velocity drop during a cloud migration, and how do you stop it?

Velocity drops because the migration trades a self-service platform for raw cloud primitives, so every deploy, environment, and database now routes through a small platform team and a ticket queue. The fix is to rebuild the old platform's ergonomics in wave 1, before the first customer-facing service moves, rather than treating developer experience as a post-migration cleanup task.

The symptoms are concrete and predictable. Per-pull-request environments disappear. A deploy that used to be a git push becomes a Jira ticket. Onboarding a new service takes days of YAML instead of minutes. None of that shows up on an uptime dashboard, which is why teams miss it until a quarter of lost throughput has already gone by.

Measure it with the DORA four keys from wave 0: deployment frequency, lead time for changes, change failure rate, and failed deployment recovery time (DORA). In the 2024 State of DevOps report, elite teams deploy on demand, ship a change in under a day, and recover from a failed deployment in under an hour (Google Cloud). If your deployment frequency drops two bands during wave 3, that is a migration problem, not a developer problem.

Kubernetes and GitOps solve reconciliation, not developer self-service. Argo CD's own documentation calls it a declarative GitOps continuous delivery tool for Kubernetes (Argo CD), which presumes someone already authored and owns the manifests. That someone becomes the bottleneck. Kubernetes production use reached 80% in the 2024 CNCF Annual Survey, up from 66% a year earlier, and complexity remains one of the most cited barriers to running it well (CNCF). A five-person platform team cannot hand-hold every deploy for eighty engineers.

So protect a short list of ergonomics from day one: git push to deploy, an ephemeral environment per pull request, one-click rollback, and sane defaults for databases and networking. Pair that with guardrails, not gatekeeping: per-environment RBAC and policy checks, so self-service never means unreviewed production access.

Where does Qovery fit compared to OpenTofu, Argo CD, and the hyperscaler migration services?

Qovery is the developer-experience layer of a migration stack. It sits above your cloud account and Kubernetes cluster and replaces the platform ergonomics you are leaving behind. OpenTofu, Argo CD, and the hyperscaler migration services own provisioning, reconciliation, and data movement respectively, so they are complementary to Qovery, not alternatives to it.

Let me say the fair thing plainly. OpenTofu and Terraform are the right answer for infrastructure as code. Argo CD and Flux are the right answer for GitOps reconciliation, and both are CNCF graduated projects that earned that status back in 2022. AWS Migration Hub, Google Cloud Migration Center, and Azure Migrate are the right answer for discovery, assessment, and tracking, and their paired DMS products are the right answer for moving data (AWS, Google Cloud, Microsoft). Qovery does not compete with any of them.

What Qovery does is deploy into your own AWS, GCP, Azure, or Scaleway account, or your existing Kubernetes cluster. That is bring-your-own-cloud (BYOC), so the cloud contract, committed-use discounts, and Savings Plans stay in your name. The verified capabilities are git-push deployments, preview and ephemeral environments per pull request, environment auto-stop for non-production, managed cluster upgrades, per-environment RBAC, and databases backed by managed cloud services.

BYOC matters mid-migration because you are not swapping one lock-in for another. Qovery-managed workloads run beside hand-rolled Terraform workloads in the same account, on standard Kubernetes. And if you are phasing across two clouds - wave 3 lands on GCP, wave 4 lands on AWS - your developers keep one workflow on both.

I will be equally honest about the limits. Qovery does not move your data; that is DMS territory. It does not replace OpenTofu or Terraform for bespoke infrastructure. And it expects Kubernetes underneath. It is the fifth layer, not the whole stack.

ToolPrimary jobWhere workloads runDeveloper self-service out of the boxWho holds the cloud contract and discountsWhat it does not do
QoveryDeveloper self-service and environments on top of KubernetesYour own AWS, GCP, Azure, or Scaleway account, or your existing clusterDevelopers self-serve deploys and per-pull-request preview environments without a ticketYou do, because Qovery runs in your account under BYOCDoes not move data or replace infrastructure-as-code for bespoke infrastructure
OpenTofu / TerraformDeclares infrastructure as reproducible codeAnywhere the provider reaches; it provisions, it does not hostNo developer deploy workflow; it is an engineer-facing toolYou do, since it operates directly on your cloud accountsDoes not deploy application code or manage environments
Argo CD / FluxReconciles running state against GitInside the Kubernetes clusters you point it atRequires pre-authored manifests, so not self-service for app teamsYou do, as it runs in your own clustersDoes not author manifests or provision the cloud underneath
AWS Migration Hub with DMSAssessment, tracking, and database replicationAWS, for both the tooling and the destinationNot a developer workflow; it is a migration control planeAWS, as an AWS-native serviceDoes not give developers a deploy or preview workflow
Google Cloud Migration Center with DMSAssessment and database replication into Google CloudGoogle CloudNot a developer workflow; it is discovery and data movementGoogle CloudDoes not provide self-service application deployment
Azure Migrate with Azure DMSDiscovery, assessment, and database replication into AzureAzureNot a developer workflow; it is a migration toolsetMicrosoft AzureDoes not deploy or manage application environments for developers
Heroku or Render style PaaSFully managed application hosting with a developer workflowThe vendor's own infrastructure, not your accountDevelopers self-serve deploys, but on resold capacityThe PaaS vendor holds the underlying cloud contractDoes not run in your account, so committed-use discounts are not yours
Ship faster on infrastructure you control.
Qovery gives your team self-service deployments on your own AWS, GCP, Azure, or Scaleway account - or your existing Kubernetes cluster. Start deploying in under 10 minutes.

How do you sequence a phased migration wave by wave without breaking reliability?

Run six numbered waves - baseline, foundation, one internal service, customer-facing stateless, data, and decommission - and treat every wave as reversible until the parallel run proves itself. Write and rehearse the rollback before the wave starts, because a rollback plan first executed during an incident is not a rollback plan.

  • Wave 0, baseline. Record current SLOs, deployment frequency, lead time for change, change failure rate, incident rate, and monthly spend on the existing platform. You cannot prove the migration helped or hurt without this.
  • Wave 1, foundation. Landing zone, network, IAM, one Kubernetes cluster, CI pipeline, and consolidated alerting and observability. Nothing customer-facing. Developer self-service lands here, not later.
  • Wave 2, one boring internal service. Take a low-stakes internal service end to end, including an on-call runbook and a rehearsed rollback drill under synthetic load.
  • Wave 3, customer-facing stateless. Move stateless services with weighted traffic shifting starting at 1 to 5 percent, using the routing layer from the tool map, and increase only when the exit criteria hold.
  • Wave 4, data. Replicate with change data capture via AWS DMS, Google Database Migration Service, or Azure Database Migration Service, dual-read to validate, then flip writes in a low-traffic window behind a short read-only freeze.
  • Wave 5, decommission. Only after one full billing cycle on the new stack and one real incident survived on it. Not before.

Copy this per-wave exit gate template into the wave plan: metric, threshold, owner, rollback trigger, and time-to-rollback target. For wave 3 that might read: p95 latency, under 250 ms, owned by the service team, roll back if it holds above threshold for 10 minutes, target rollback under 5 minutes by shifting weighted traffic back. When the trigger and the target are written down before the wave, the decision to roll back is boring instead of heroic.

What does a phased cloud migration cost, and how do you avoid the parallel-run bill surprise?

Budget for 2 to 4 months of double-running plus engineering time, and instrument cost per environment from wave 0 so the finance conversation is data rather than argument. The overrun almost always comes from idle non-production environments, oversized clusters, and cross-cloud egress, not from production traffic.

Model the cost buckets before wave 1: parallel infrastructure, cross-cloud and inter-region data egress, engineering hours, tooling licences, and any temporary consulting. Egress is a real line item during a parallel run, not a rounding error. AWS bills the first 10 TB of monthly internet egress at $0.09 per GB after a 100 GB free allowance (AWS), and Google Cloud (Google Cloud) and Azure (Microsoft) publish comparable per-GB rates. Replication traffic runs continuously for the length of wave 4, so that meter never stops during the data move.

The waste is well documented. Organizations self-report about 27% of cloud spend as wasted and run roughly 17% over budget on average (Flexera), and workload optimization and waste reduction is the number-one priority for FinOps practitioners (FinOps Foundation). On Kubernetes specifically, large production clusters use only about 13% of provisioned CPU and 20% of memory on average (Cast AI). That is the case for environment auto-stop and scale-to-zero on preview and staging.

Right-size nodes after wave 2, when workloads are steady, never before, and buy reserved or committed capacity only after a month of steady-state running. Keep your discounts intact: with BYOC, the cloud contract, committed-use discounts, and Savings Plans stay in your name, unlike resold-capacity PaaS pricing. And track cost per environment and cost per service, not one monthly total, or you will never find the idle staging cluster.

ItemWhich wave it appears inTypical driverHow to contain itWho owns it
Parallel infrastructureWaves 1 through 5, the whole double-runTwo full stacks running side by sideTime-box the parallel run to 2 to 4 months and decommission promptlyPlatform team and finance
Cross-cloud and inter-region egressWave 4 mostly, whenever data crosses a boundaryContinuous replication and chatty cross-stack callsCo-locate replication endpoints and watch the per-GB meterData and networking owners
Idle non-production environmentsWaves 1 through 3, as previews multiplyPreview and staging clusters left running overnightEnvironment auto-stop and scale-to-zero off working hoursPlatform team, per team budget
Oversized clustersWaves 2 and 3, before workloads settleGuessing node sizes before real load existsRight-size after wave 2 and buy commitments after a steady monthPlatform team
Engineering hours and consultingWaves 0 through 5People are the largest and least-tracked costScope waves tightly and reuse a self-service platformEngineering leadership

What are the failure modes that break reliability during a phased migration?

Migration reliability failures are predictable and few in number: big-bang cutovers with no traffic-shifting layer, rollbacks nobody rehearsed, configuration drift between the two stacks, dual-write data inconsistency, long DNS TTLs, and lost institutional knowledge about the old platform. Each has a known countermeasure that belongs in the wave plan before wave 1 starts.

  • Big-bang cutover with no routing layer. Countermeasure: weighted traffic shifting from wave 3 onward, starting at 1 to 5 percent, so a bad wave affects a sliver of users and rolls back in minutes.
  • Rollback never rehearsed under load. Countermeasure: a game day per wave, executed before customer traffic touches the new stack, so the runbook is proven, not theoretical.
  • Configuration drift. Manual changes on the old platform that never reached code. Reconcile with OpenTofu or Terraform plan output and Argo CD sync status on a schedule, and treat drift as an incident.
  • Dual-write inconsistency. Countermeasure: change data capture plus a short read-only freeze at the write flip, followed by a reconciliation query that proves both databases agree.
  • DNS TTLs left long. A 24-hour TTL turns a "minutes" rollback into an hours-long one. Lower TTLs a full week before the wave and verify resolver behaviour with a real client.
  • Lost institutional knowledge. Undocumented cron jobs, environment variables, and one-off add-ons on the old platform that nobody inventoried. Do the inventory in wave 0, while the old platform still runs.
  • On-call fatigue. Two stacks means two rotations unless alerting is consolidated in wave 1. Merge the alerting before you add the second stack, not after.

FAQs

What services can help us execute a phased cloud migration without losing deployment velocity?

You need one tool per layer across provisioning (OpenTofu or Terraform), delivery (Argo CD or Flux with GitHub Actions), traffic cutover (Route 53 weighted routing, Google Cloud Load Balancing, or Azure Traffic Manager), data replication (AWS DMS, Google Database Migration Service, or Azure Database Migration Service), and developer self-service (an internal developer platform such as Qovery, or one you build). The first four keep reliability high; the fifth is what keeps velocity high. Track DORA deployment frequency and lead time for change from wave 0 so you catch a velocity drop the moment it starts.

How do we keep reliability and uptime high while migrating in phases off our current platform provider?

Put a routing layer in front of both stacks and shift traffic in small weighted increments, using Route 53 weighted routing, Google Cloud Load Balancing traffic splitting, Azure Traffic Manager, or Argo Rollouts for canary and blue/green. Run the old and new stacks in parallel, replicate data with change data capture, and make rollback a traffic change rather than a redeploy. This is the strangler-fig pattern that AWS, Google Cloud, and Microsoft all document as the safe way to migrate incrementally.

How do we measure whether a phased migration is hurting developer productivity?

Use the DORA four keys - deployment frequency, lead time for changes, change failure rate, and failed deployment recovery time - and baseline them in wave 0 on the old platform (DORA). If deployment frequency or lead time gets worse during wave 1 or wave 3, the migration is costing you velocity, and the usual cause is that developer self-service did not come along with the workloads. Watch time-to-first-deploy for a new service too, since that is where the ticket-queue tax shows up first.

Should we use OpenTofu or Terraform for a cloud migration in 2026?

Both work, and both are drop-in compatible with the same HCL and state model, so pick on licensing and governance rather than features. OpenTofu is the Linux Foundation fork created after HashiCorp moved Terraform to the source-available BUSL 1.1 license, and it stays open source under the MPL (OpenTofu). If BUSL restrictions are a concern for your organization, use OpenTofu; if you are already deep in HashiCorp tooling and licensing is a non-issue, Terraform is a fine choice.

Do we still need Argo CD or Flux if we already run an internal developer platform?

Often not as a separate thing your developers touch, because a good internal developer platform gives them the git-push-to-deploy workflow directly, while GitOps reconciliation runs underneath. Argo CD and Flux are the right answer when your platform team wants to manage cluster and infrastructure manifests declaratively, and many internal developer platforms use GitOps internally anyway. The distinction is who authors the manifests: GitOps assumes someone already did, and a developer platform is what removes that assumption for app teams.

How long should we run our old platform and the new cloud in parallel before decommissioning?

Plan for 2 to 4 months of double-running and at least one full billing cycle of steady-state operation on the new stack before you turn anything off, and only decommission after you have survived one real incident on the new cloud. The parallel run is what makes rollback cheap, so cutting it short to save money is usually a false economy. Instrument cost per environment during the parallel run so you can prove when the old stack is genuinely idle.

Can we migrate to AWS, GCP, Azure, or Scaleway without hiring a platform team first?

Yes, if you use an internal developer platform to cover the self-service layer while a small team owns provisioning and delivery. Qovery, for example, runs in your own AWS, GCP, Azure, or Scaleway account or your existing Kubernetes cluster and gives developers git-push deploys, preview environments, and per-environment RBAC without a hand-built platform behind them. You still need someone accountable for the cloud account and the network, but you do not need a ten-person platform team on day one.

Cutover should be a traffic decision, not a deployment decision, and velocity should survive the move as intact as your uptime. Get the fifth layer in place in wave 1 and the rest of the migration gets a lot less dramatic.

Try Qovery free and give your team self-service deployments on infrastructure you already control.

Romaric Philogene
About the author
Romaric Philogene

Romaric founded Qovery to make Kubernetes accessible to every engineering team. He writes about platform strategy, developer experience, and the future of cloud infrastructure.

Next step

Ship faster on infrastructure you control.

Qovery gives your team self-service deployments on your own AWS, GCP, Azure, or Scaleway account - or your existing Kubernetes cluster. Start deploying in under 10 minutes.