The Cloud Migration Checklist I Wish I Had: 12 Steps, 6 Phases, and the Mistakes That Cost Money
A practical cloud migration checklist in 12 steps across 6 phases: discovery and dependency mapping, business case, landing zone, the 7 Rs, waves and cutover, then post-migration FinOps and day-2 ownership - with the traps that blow up budgets and the timelines to plan for.
The cloud migration checklist has 6 phases and 12 steps: (1) inventory assets, (2) map dependencies, (3) baseline cost and performance, (4) build the business case and KPIs, (5) pick a migration pattern per app using the 7 Rs, (6) sequence waves, (7) build the landing zone as code, (8) enforce tagging and guardrails, (9) run a pilot wave of 2-3 low-risk apps, (10) migrate data and validate against baseline, (11) cut over with a written rollback and decommission the source, (12) rightsize and set day-2 ownership.
Most migrations slip before any workload moves. Incomplete application dependency mapping is the most common cause, because you cannot migrate, test, or roll back what you never inventoried.
Decide rehost vs replatform vs refactor per application, not per portfolio: rehost when a datacenter lease is the deadline, replatform anything you will still run in three years, refactor only the small share of apps that differentiate the business.
Migrate in waves. A pilot of 2-3 low-dependency apps proves the landing zone, CI/CD, data replication, and rollback path before any revenue-critical system moves.
Budget for post-migration optimization from day one. Lift-and-shift without rightsizing, non-prod auto-stop, and cost-allocation tags routinely produces a cloud bill higher than the on-prem baseline, and managing cloud spend is the challenge organizations report most often in Flexera's annual State of the Cloud survey.
The checklist does not end at cutover. Someone must own deployments, environments, cluster upgrades, access control, and cost hygiene, and the four realistic options are an in-house platform, hyperscaler-native tooling, a managed PaaS, or an internal developer platform like Qovery running in your own AWS, GCP, Azure, or Scaleway account or your existing Kubernetes cluster.
We have talked to hundreds of engineering leaders at Qovery who have been through a migration, and the pattern is consistent. The projects that go sideways almost never fail during the move itself. They fail because a step earlier in the checklist got skipped. So here is the whole checklist, the order that matters, and the specific traps that cost real money.
What is the cloud migration checklist, step by step?
The cloud migration checklist is 12 steps grouped into 6 phases: discover, decide, design, move, cut over, and operate. Run them in order, and treat the first three phases as the real work, because planning and landing-zone build usually eat more calendar time than the migrations themselves.
Here are all 12 steps, one sentence each:
Phase 1 - Discover (steps 1-3): (1) inventory every asset and application, (2) map dependencies between them, (3) baseline cost, performance, and data classification so you have a reference to prove the migration worked.
Phase 2 - Decide (steps 4-6): (4) build the business case with target KPIs, (5) pick a migration pattern per app using the 7 Rs, (6) sequence the moves into waves by dependency cluster.
Phase 3 - Design (steps 7-8): (7) build the landing zone as code (accounts, network, identity), (8) enforce tagging, cost-allocation, and security guardrails, with CI/CD and preview environments ready before wave one.
Phase 4 - Move (steps 9-10): (9) run a pilot wave of 2-3 low-risk apps, (10) migrate the data and validate every app against the pre-migration baseline from step 3.
Phase 5 - Cut over (step 11): (11) cut over against written go/no-go criteria with a rollback runbook, keep the source warm, then decommission it deliberately.
Phase 6 - Operate (step 12): (12) rightsize, auto-stop non-production, commit to discounts once usage stabilizes, and assign a named day-2 owner with a recurring cost review.
This is a synthesis of the three published vendor frameworks, not one vendor's opinion. AWS runs its Migration Acceleration Program on three phases (assess, mobilize, migrate and modernize). Microsoft's Cloud Adoption Framework organizes adoption into phases (strategy, plan, ready, adopt, and onward) with migration living inside the adopt phase. Google Cloud defines four migration phases (assess, plan, deploy, optimize). Different labels, same shape.
#
Step
Phase
Owner
Artifact that proves it is done
Typical duration (20-50 apps)
1
Inventory assets and apps
Discover
Cloud architect
Inventory export
1-2 weeks
2
Map dependencies
Discover
Cloud architect + app teams
Dependency map
1-2 weeks (overlaps)
3
Baseline cost + performance
Discover
Platform + app teams
Cost and performance baseline
~1 week (overlaps)
4
Business case + KPIs
Decide
Finance + cloud architect
Signed business case
~1 week
5
Pick a pattern per app (7 Rs)
Decide
Cloud architect + app teams
Per-app R decision in the inventory
1-2 weeks
6
Sequence waves
Decide
Cloud architect
Wave plan
2-4 days
7
Landing zone as code
Design
Platform team
Landing zone IaC
3-5 weeks
8
Tagging + guardrails
Design
Platform team
Tagging policy + policy-as-code checks
Within landing zone
9
Pilot wave (2-3 apps)
Move
Platform + app teams
Pilot report
2-4 weeks
10
Migrate data + validate
Move
App + platform teams
Validation report vs baseline
Per wave
11
Cut over + decommission
Cut over
Platform + app teams
Rollback runbook + decommission ticket
Hours per wave, planned over days
12
Rightsize + day-2 ownership
Operate
Platform team + finance
Rightsizing report + named owner
Continuous, first pass day 30-90
You are ready for wave one when five things are true: the inventory is complete, the dependency map is signed off, the baseline is published, the landing zone is in IaC, and the rollback runbook is written. If any one of those is missing, you are not ready, whatever the calendar says.
What must you do before you move a single workload?
Before any workload moves you need three artifacts: a complete asset and application inventory, a validated dependency map, and a cost plus performance baseline. Without them the timeline slips, and the post-migration argument about whether the cloud bill is good or bad becomes unwinnable because there is no reference point.
Map the awkward dependencies, because those are the ones that break cutover: shared file shares, cron and batch windows, hardcoded IPs, license servers, internal DNS names, and the VM nobody remembers standing up. Baseline both cost and performance while you are there - p95 latency, throughput, peak and average CPU and memory, and storage IOPS. Classify data first, because residency, PII, retention, and encryption requirements drive region and service selection, and GDPR or HIPAA scope changes the whole design.
Define success KPIs up front too. DORA's four keys - deployment frequency, lead time for changes, change failure rate, and failed deployment recovery time - are the cleanest measure of delivery health, and Google's DORA research program tracks them every year. Add cost per environment and cost per team so finance and engineering are reading the same scoreboard.
Three traps sink this phase:
Skipping the run-cost baseline. You then spend a year arguing about whether the cloud bill is reasonable with nothing to compare it to.
Treating discovery as one-off. The estate keeps changing, so re-run discovery before each wave, not just once at kickoff.
Trusting a stale CMDB. If nobody has updated it in two years, agent-based or flow-based discovery beats institutional memory every time.
Tool
What it inventories
Agent vs agentless
Dependency mapping
Target cloud
Cost
Best fit
AWS Application Discovery Service + Migration Hub
Servers, VMs, config, utilization
Both (agent + agentless connector)
Yes, network-based
AWS
Free for discovery (pricing); folded into AWS Transform for new customers
How do you choose between rehost, replatform, and refactor for each application?
Choose per application using the 7 Rs, and default to replatform for anything you will still be running in three years. Rehost when a datacenter lease or hardware refresh sets a hard deadline, and refactor only the minority of apps that carry real business differentiation. Deciding this per portfolio instead of per app is how you end up either over-engineering commodity systems or dragging technical debt straight into the cloud.
AWS defines seven strategies, officially called the 7 Rs: retire, retain, rehost, relocate, repurchase, replatform, and refactor or re-architect. Google Cloud uses parallel language in its migration guidance - "lift and shift" for rehost, "move and improve" for refactor, "remove and replace" for a rebuild.
The heuristics I would actually apply:
Retire anything with no active users in the last 90 days. Every app you retire is one you never have to migrate, test, or pay for.
Rehost under a hard datacenter exit date, accepting that you will optimize later.
Replatform onto managed databases and container runtimes for the long-lived workhorses. This is the default for a reason.
Repurchase when a SaaS product already does the job better than the thing you are maintaining.
Pure lift-and-shift is where budgets quietly break. You move peak-sized VMs running 24/7, with no autoscaling, no managed services, and no rightsizing, and you pay for both estates during the overlap. The bill goes up, and someone concludes "the cloud is expensive" when the real problem was the strategy.
Sequence the moves into waves. The pilot wave (step 9) takes low-risk, low-dependency apps. After that, migrate dependency clusters together so tightly coupled systems move as a unit, and save the highest-revenue systems for last when the landing zone and the runbooks are proven.
The runtime decision belongs here too. VMs, serverless, or Kubernetes. Kubernetes is the common landing spot for replatformed apps because it behaves the same way on AWS, GCP, Azure, and Scaleway, which is the practical hedge against lock-in - and 82% of container users now run Kubernetes in production according to CNCF's 2025 Annual Survey. Say plainly when not to containerize, though: Windows-heavy estates, appliance-style software, license-bound workloads, and anything with a kernel or hardware dependency are better left on VMs.
Record the chosen R per app in the inventory. That column becomes the direct input to the business case in step 4.
Strategy (R)
What it means
When to choose it
Typical effort
12-month cost outcome
Migration speed
Example workload
Retire
Decommission it
No active users in 90 days
Very low
Pure saving
Immediate
Duplicate internal tools
Retain
Leave it where it is
Not ready, or no cloud case
None now
Unchanged
n/a
Mainframe, compliance-locked app
Relocate
Move the platform as-is (e.g. VMware)
Datacenter exit, keep hypervisor
Low
Roughly flat
Fast
Large VMware farm
Rehost
Lift and shift, no code change
Hard lease or hardware deadline
Low
Often higher without rightsizing
Fast
Legacy line-of-business app
Replatform
Move with targeted optimization
Long-lived workhorses
Medium
Lower after rightsizing
Medium
App onto managed DB + Kubernetes
Repurchase
Swap for SaaS
A SaaS already does the job
Low-medium
Predictable subscription
Medium
Self-hosted CRM to SaaS
Refactor / re-architect
Rewrite for cloud-native
Real business differentiation
High
Best long-term, high upfront
Slow
Core revenue platform
What belongs in the landing zone before the first migration wave?
The landing zone - account structure, network, identity, guardrails, tagging, and a working deployment pipeline - must exist, be codified in infrastructure as code, and be tested before wave one. Retrofitting it after hundreds of resources already exist is the expensive path, and it is the one most teams accidentally take.
Start with account structure and hard prod versus non-prod isolation. The vendors publish the starting points: AWS Control Tower, Azure landing zones (Microsoft breaks these into eight design areas covering identity, network, security, governance, and platform automation), and Google's landing zone design guidance. Then design the network before cutover week: VPC or VNet layout, private connectivity back to the datacenter, egress control, and a DNS and TTL plan agreed in advance.
The pieces that separate a clean wave two from a painful one:
Identity and least-privilege access, with per-environment RBAC so developers get self-service without ever holding production credentials.
Guardrails as code - encryption defaults, centralized logging, backup and retention policy, and policy-as-code checks in CI (OPA/Conftest, AWS Config, Azure Policy).
A tagging and cost-allocation standard enforced on day one. Untagged resources are unowned resources, and cost allocation is one of the hardest FinOps practices to retrofit once the estate is live.
Everything in Terraform, OpenTofu, or provider-native IaC, so wave two is a repeat of a known-good template rather than a rebuild.
CI/CD and preview environments live before the first app lands. Migrate an application nobody can redeploy and you have moved a problem, not solved one.
None of this is cloud-specific. It applies the same on AWS, GCP, Azure, Scaleway, or an existing Kubernetes cluster. The artifacts change name, the checklist does not.
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 migrate the data and cut over without downtime you cannot afford?
Pick the cutover model from the downtime you can actually tolerate: an offline bulk move for multi-hour windows, continuous replication then flip for sub-hour, and replication plus weighted traffic shift for sub-minute. Then rehearse the rollback before you rehearse the cutover, because the rollback is the part everyone skips and later needs.
There are three data patterns worth knowing. An offline bulk move is simplest when you can afford a window. Continuous replication then flip uses change data capture through a managed service - AWS DMS, Azure Database Migration Service, or Google Database Migration Service - and keeps downtime to the length of the final flip. Dual-write with reconciliation is the highest-complexity option, and I would use it rarely and only when sub-minute cutover is non-negotiable.
Validate every migrated app against the baseline from step 3: row counts and checksums, schema parity, a load test against the pre-migration p95, a security scan, a restore-from-backup test, and a DR drill. Cutover mechanics are boring on purpose - lower the DNS TTL days in advance, freeze changes, shift traffic with a canary or weighted split, run a comms plan, and write go/no-go criteria with one named decision owner.
Rollback deserves the same rigor. Define the point of no return, keep the source warm until the exit criteria are met, and time-box the decision so nobody debates it live at 2 a.m. Then decommission deliberately. Unretired source infrastructure is the quiet double-cost of most migrations, and it needs a ticket with a date, not a vague intention.
Downtime tolerance
Data movement method
Named tooling
Rollback mechanism
Complexity
Typical rehearsals
Sub-minute
Continuous replication + weighted traffic shift
CDC, DMS + load balancer / DNS weights
Shift traffic back to source
High
3+
Sub-hour
Continuous replication, then flip
AWS DMS, Azure DMS, Google DMS
Re-point to still-running source
Medium-high
2-3
Multi-hour
Offline bulk move during a window
Native dump/restore, storage sync
Restore source from snapshot
Medium
1-2
Weekend window
Offline bulk or physical appliance
Azure Data Box, Google Transfer Appliance
Source untouched until sign-off
Low-medium
1
Why do cloud migrations go over budget, and how do you prevent it?
Migrations go over budget for four predictable reasons: no rightsizing after lift-and-shift, non-production running 24/7, no tagging or cost ownership, and architecture surprises like egress and cross-AZ traffic. Each one maps to a fix that is already a step in this checklist. Managing cloud spend is the top challenge organizations report in Flexera's 2026 State of the Cloud Report - cited by 85% of respondents, the top concern for the third year running - so this is the normal case, not the exception.
The four causes, and the fix for each:
No rightsizing after lift-and-shift. VMs sized for on-prem peak keep running 24/7 in the cloud. Fix: a day-30 rightsizing pass using AWS Compute Optimizer, Azure Advisor, or GCP Recommender (part of step 12).
Non-production running nights, weekends, and holidays. This is often the single largest line of avoidable spend. Fix: auto-stop for non-prod environments.
No tagging or cost allocation. Nobody owns the line items, so nothing gets cut. Fix: the tagging standard from step 8 plus tag-based showback per team.
Architecture surprises. Cross-AZ and internet egress traffic, over-provisioned managed services, orphaned volumes and snapshots, and duplicate observability tooling. Fix: watch the network line item early - AWS lists internet egress at $0.09/GB for the first 10 TB and cross-AZ transfer at $0.01/GB each way (list price at time of writing), and those pennies compound fast at scale.
Flexera's 2026 report also estimates 29% of cloud spend is wasted, and 17% of organizations exceeded their public cloud budget in the past year. The FinOps Foundation's 2025 State of FinOps puts workload optimization and waste reduction as the number-one practitioner priority, ahead of managing commitment-based discounts. The sequencing there is deliberate: fix waste first, commit second.
On commitments, wait for the data. AWS Savings Plans advertise up to 72% off on-demand (66% for the flexible Compute plan), Google Cloud CUDs go up to 70% for memory-optimized and 55% for other machine series, and Azure Reservations advertise up to 72% versus pay-as-you-go in best-case scenarios. Those are real, but only commit once usage has stabilized, usually after 60-90 days of steady-state data. Commit to a peak-sized, un-rightsized workload and you have locked in the waste for one to three years.
Put the parallel-run overlap in the business case explicitly. Running both estates at once is real budget, and the length of the overlap is a risk decision you make on purpose, not an accident you discover on the invoice.
One more point that belongs here. When workloads run in your own cloud account, the bill, the negotiated rates, and the committed-use discounts stay in your name. That is not true when you rent capacity inside a managed platform's account, where the discounts accrue to the vendor and you pay their retail rate. It is a cost-ownership decision as much as a technical one, and it sets up the day-2 question in the next section.
Who owns the platform after the migration, and where does Qovery fit?
The migration creates a permanent day-2 job - deployments, environments, cluster upgrades, access control, and cost hygiene - and there are four realistic ways to staff it: build in-house, use hyperscaler-native tooling, rent a managed PaaS, or run an internal developer platform inside your own cloud account. Step 12 is not complete until a named team or platform owns all five of those.
The gap is real. Your cloud provider hands you primitives - compute, networking, a managed Kubernetes control plane. Developers need a deploy path, an environment per branch, and guardrails. Somebody has to build the bridge, and once the migration team disbands, what we hear from CTOs at Qovery is that the bridge quietly becomes one senior engineer's unpaid second job.
Option B - Hyperscaler-native. AWS Elastic Beanstalk or ECS, Azure Container Apps, Google Cloud Run. Solid and cheap to start, and the workloads run in your account. The developer experience is bound to one provider, which is fine until you go multi-cloud.
Option D - Qovery. An internal developer platform that deploys into your own AWS, GCP, Azure, or Scaleway account, or your existing Kubernetes cluster. Verified capabilities: 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.
When Qovery is not the right fit, and I would rather say so than pretend otherwise: heavy Windows or VM estates, a pure datacenter-exit rehost with no containerization, workloads that are staying on VMs, or a team with a funded platform team they are already happy with. Qovery is for teams that landed on containers and Kubernetes and do not want to build the deployment layer by hand.
Option
Where workloads run
Owns bill + discounts
Multi-cloud / BYO-Kubernetes
Developer self-service
Preview envs per PR
Non-prod auto-stop
Cluster upgrades
Time to first deploy
Headcount
Build in-house
Your account
Yes
You build it
You build it
You build it
You build it
You own them
Weeks to months
High (platform team)
Hyperscaler-native
Your account
Yes
No (one provider)
Partial
Partial / DIY
DIY
Managed for the service
Days
Moderate
Managed PaaS (Heroku, Render, Fly.io)
Vendor account
No (vendor's rates)
No
Yes
Yes (review apps)
Partial (some sleep idle apps)
n/a (fully managed)
Minutes
Low
Qovery
Your own AWS/GCP/Azure/Scaleway or K8s
Yes
Yes
Yes
Yes
Yes
Managed
Under ~15 minutes
Low
How long does a cloud migration take, and what does a realistic timeline look like?
For a 20-50 application portfolio, plan roughly 4 weeks of discovery and business case, 4-6 weeks of landing-zone work (overlapping), a pilot wave around weeks 6-10, then rolling waves after that. Expect discovery plus landing zone to take longer than the moves themselves, and treat any plan that front-loads the moves as a warning sign.
A realistic calendar looks like this:
Weeks 1-4: discovery and business case (steps 1-6).
Weeks 3-8: landing zone as code, overlapping discovery (steps 7-8).
Weeks 6-10: pilot wave of 2-3 low-risk apps (step 9).
Day 30-90 after each cutover: post-migration optimization (step 12).
What moves the number: portfolio size, dependency density, data volume, compliance scope, and how much refactoring you signed up for in step 5. A portfolio that is 80% rehost moves far faster than one with three refactors in it.
The signals you are going too fast are specific and worth watching for: no dependency map, no rollback runbook, no cost baseline, the pilot skipped "to save time," and tagging deferred to "later." Every one of those trades a week now for a much larger bill or outage later.
The first 30 days after cutover are their own checklist: rightsizing pass, auto-stop non-prod, tag audit, DR test, decommission the source, and publish the KPI delta against the baseline from step 3. That last one is how you prove the migration worked instead of hoping it did.
Phase 6 is a loop, not a finish line. Cluster upgrades and cost reviews recur on the cloud provider's schedule, not yours, and someone owns that schedule forever. That is the honest shape of a migration: the move ends, the operating does not.
What is the cloud migration best practices checklist in short?
Twelve steps in six phases: discover (inventory, dependency map, baseline), decide (business case, per-app 7 Rs, wave plan), design (landing zone as code, tagging and guardrails), move (pilot wave, migrate and validate data), cut over (go/no-go, rollback, decommission), and operate (rightsize, auto-stop, day-2 owner). Run them in order. The first three phases usually take longer than the moves, and skipping them is the most reliable way to blow the budget.
What are the 7 Rs of cloud migration?
The 7 Rs are AWS's seven migration strategies: retire, retain, rehost, relocate, repurchase, replatform, and refactor or re-architect. You choose one per application, not one for the whole portfolio. Default to replatform for long-lived apps, rehost under a hard deadline, retire anything unused, and refactor only the systems that differentiate your business.
How long does a cloud migration take?
For a 20-50 application portfolio, plan roughly 4 weeks of discovery and business case, 4-6 weeks of landing-zone work, a pilot wave around weeks 6-10, then rolling waves. The total depends most on portfolio size, dependency density, data volume, compliance scope, and how much refactoring you took on. Discovery and landing zone reliably take longer than the actual moves.
What is the most common mistake in cloud migration?
Incomplete application dependency mapping. You cannot migrate, test, or roll back what you never inventoried, so a missed dependency surfaces at cutover as a broken integration or an app that will not start. The fix is automated discovery re-run before every wave (step 2), not a spreadsheet filled in from memory.
Should we lift-and-shift or replatform to Kubernetes?
Replatform to Kubernetes for anything you will still run in three years, and lift-and-shift only when a hard deadline like a datacenter exit forces speed over optimization. Kubernetes behaves the same on AWS, GCP, Azure, and Scaleway, which is the practical hedge against lock-in, and 82% of container users run it in production per CNCF's 2025 survey. Skip containerization for Windows-heavy, appliance-style, or license-bound workloads.
How do we keep cloud costs under control after migrating to AWS, GCP, Azure, or Scaleway?
Rightsize within 30 days, auto-stop non-production, enforce cost-allocation tags from day one, and watch the network line item for egress and cross-AZ surprises. Commit to Savings Plans, CUDs, or reservations only after 60-90 days of steady-state usage, so you discount a rightsized workload rather than a wasteful one. Flexera's 2026 report estimates 29% of cloud spend is wasted, and almost all of it traces back to these four habits.
The move is the easy part to schedule and the hard part to survive. Get discovery, the landing zone, and a written rollback right, and the cutover becomes boring, which is exactly what you want. When you are ready for the day-2 layer, try Qovery free or book a demo to see git-push deployments, preview environments, and auto-stop running in your own cloud account.
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.