Cloud Migration Assessment and Planning Explained -- Complete Guide
In this tutorial, you'll learn about Cloud Migration Assessment and Planning Explained. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
Cloud Migration is the process of moving applications, data, and infrastructure from on-premises or other cloud environments to a target cloud. A structured assessment and planning phase is critical to avoid cost overruns, security gaps, and performance issues.
What You'll Learn
By the end of this tutorial, you will understand the 7 Rs of cloud Migration, how to conduct a discovery and TCO analysis, and how to plan a phased Migration with landing zones and automation.
Why Cloud Migration Assessment Matters
Nearly 40% of cloud Migration projects exceed their budget. Half of all migrated applications require re-architecture within the first year. Proper assessment upfront prevents these failures.
Cloud Migration Learning Path
flowchart LR
A[Cloud Basics] --> B[Cloud Migration]
B --> C{You Are Here}
C --> D[Assessment]
C --> E[Planning]
C --> F[Execution]
C --> G[Optimization]
D --> H[Discovery]
D --> I[TCO Analysis]
E --> J[7 Rs Strategy]
E --> K[Landing Zone]
F --> L[Wave Planning]
F --> M[Cutover]
G --> N[Rightsize]
G --> O[FinOps]
The 7 Rs of Migration
| Strategy | Description | Effort | Downtime | When to Use |
|---|---|---|---|---|
| Rehost (Lift & Shift) | Move as-is to cloud VMs | Low | Low | Quick wins, no code changes |
| Replatform | Move with minor cloud optimizations (RDS, managed services) | Medium | Low | Improve without full rewrite |
| Refactor / Re-architect | Rewrite for cloud-native patterns | High | None | Need agility, scalability |
| Repurchase | Replace with SaaS alternative | Medium | Medium | Outdated COTS, end-of-life |
| Retain | Keep on-premises | None | None | Compliance, latency-sensitive |
| Retire | Decommission | Low | None | No longer needed |
| Relocate | Move to cloud hypervisor/VMware | Low | Low | VMware Cloud on AWS, Azure VMware |
# AWS Migration Evaluator (formerly TSO Logic) CLI
# Generate discovery report
aws migration-hub create-progress-update-stream \
--progress-update-stream-name dodatech-migration-stream
# Start data collection from on-premises servers
aws discovery start-data-collection \
--agent-ids "agent-1234567890abcdef0"
# List discovered servers
aws discovery describe-agents \
--filters '[{"name": "agentNetworkInfoList.ipAddress", "values": ["10.0.0.0/8"], "condition": "CONTAINS"}]'
# Get migration recommendations
aws migration-hub notify-migration-task-state \
--task-id "mig-1234567890abcdef0" \
--migration-task status=RECOMMENDED \
--progress-update-stream dodatech-migration-stream
Discovery and Assessment Phase
# landing-zone.tf
# Terraform: Multi-account AWS landing zone for migration
# Security account for centralized logging and audit
resource "aws_organizations_account" "security" {
name = "dodatech-security"
email = "aws-security@dodatech.com"
tags = {
Environment = "security"
ManagedBy = "terraform"
}
}
# Shared services account for networking, directory, CI/CD
resource "aws_organizations_account" "shared" {
name = "dodatech-shared"
email = "aws-shared@dodatech.com"
tags = {
Environment = "shared"
ManagedBy = "terraform"
}
}
# Migration account for temporary workloads during transition
resource "aws_organizations_account" "migration" {
name = "dodatech-migration"
email = "aws-migration@dodatech.com"
tags = {
Environment = "migration"
ManagedBy = "terraform"
}
}
# Service Control Policy to enforce encryption
resource "aws_organizations_policy" "encryption_scp" {
name = "dodatech-encryption-scp"
description = "Require encryption for all storage services"
content = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Deny]
Action = [
"s3:CreateBucket",
"ec2:CreateVolume",
"rds:CreateDBInstance",
]
Resource = "*"
Condition = {
Bool = {
"aws:SecureTransport": "false"
}
}
},
]
})
}
Discovery Checklist
| Category | Data to Collect | Tools |
|---|---|---|
| Server inventory | OS, CPU, memory, disk | AWS Application Discovery, Azure Migrate |
| Application dependencies | Network connections, service deps | CloudEndure, Agentless discovery |
| Database inventory | Engines, versions, size | Custom scripts, native tools |
| Licensing | OS, DB, middleware licenses | Flexera, Snow License Manager |
| Performance baselines | CPU, memory, IOPS, network | PerfMon, Prometheus, SAR |
| Security controls | Firewall rules, IAM, Compliance | Tenable, Qualys, native scanners |
TCO Analysis
# AWS TCO Calculator with AWS CLI
# Calculate total cost of ownership for migration
aws ce get-cost-forecast \
--time-period Start=2026-06-01,End=2027-06-01 \
--metric "BLENDED_COST" \
--granularity "MONTHLY" \
--filter '{"Dimensions": {"Key": "SERVICE", "Values": ["AmazonEC2"]}}'
# Compare on-prem vs cloud TCO
cat > tco_comparison.json << 'EOF'
{
"onPremises": {
"servers": 200,
"storage": 500000,
"network": 10000,
"power_cooling": 5000,
"staff": 300000,
},
"cloud": {
"compute": 150000,
"storage": 15000,
"data_transfer": 2000,
"support": 20000,
"migration_cost": 100000,
}
}
EOF
Migration Waves and Phases
# Example migration wave plan
cat > migration_waves.json << 'EOF'
{
"wave1": {
"name": "Quick Wins",
"applications": ["Dev Tools", "Internal Wiki", "CI/CD"],
"strategy": "Rehost",
"timeline": "Month 1-2",
"risk": "Low"
},
"wave2": {
"name": "Core Infrastructure",
"applications": ["Active Directory", "DNS", "Monitoring"],
"strategy": "Replatform",
"timeline": "Month 2-4",
"risk": "Medium"
},
"wave3": {
"name": "Business Applications",
"applications": ["CRM", "ERP", "HR System"],
"strategy": "Rehost or Replatform",
"timeline": "Month 4-8",
"risk": "High"
},
"wave4": {
"name": "Cloud-Native Transformation",
"applications": ["Customer Portal", "Data Platform"],
"<a href="/design-patterns/strategy/">Strategy</a>": "Refactor",
"timeline": "Month 8-12",
"risk": "High"
}
}
EOF
Common Migration Mistakes
1. No Dependency Mapping
Moving an application without understanding its dependencies on shared databases, authentication servers, or legacy APIs causes breakage. Use automated discovery tools.
2. Over-Provisioning Cloud Resources
Lifting servers to the same size in the cloud (e.g., 32 vCPU on-prem to 32 vCPU cloud) without rightsizing wastes 30-40%. Cloud instances can often be smaller.
3. Not Planning for Data Transfer
Migrating 50 TB over a 100 Mbps connection takes 46 days for initial sync plus ongoing Replication. Use AWS Snowball, Azure Data Box, or GCP Transfer Appliance for large datasets.
4. Ignoring Licensing
Some software licenses (SQL Server, Oracle, Windows Server) do not transfer to cloud. Check license mobility before Migration to avoid unexpected costs.
5. No Rollback Plan
Every Migration should have a tested rollback procedure. If something goes wrong, you must be able to revert to on-premises within the RTO.
Practice Questions
1. What is the difference between rehost and replatform? Rehost (lift and shift) moves applications as-is to cloud VMs with no changes. Replatform makes targeted modifications (e.g., replacing self-managed MySQL with RDS) without rewriting application code.
2. What is a landing zone? A landing zone is a pre-configured multi-account cloud foundation with networking, security, identity, and logging. It provides the baseline environment for migrated workloads.
3. What is TCO and why is it important before Migration? Total Cost of Ownership compares the full cost of running on-premises (hardware, power, cooling, staff, licensing) vs cloud (compute, storage, data transfer, support, Migration). It validates the business case.
4. What is wave planning? Wave planning groups applications into Migration waves based on complexity, dependencies, and business priority. Low-risk apps move first; critical apps move after validation.
5. Challenge: Create a Migration plan for a company with 500 on-premises servers running 50 applications, 10 TB databases, and 200 TB file storage. Timeline: 12 months. Budget: $2M. Phase 1 (Month 1-2): Discovery and TCO. Phase 2 (Month 2-4): Rehost 10 low-risk apps as wave 1. Phase 3 (Month 4-8): Replatform databases to RDS, migrate file storage to S3, replatform 30 apps. Phase 4 (Month 8-12): Refactor 5 business-critical apps. Use Snowball for 200 TB storage Migration. Budget allocation: 30% Migration tools, 40% compute/storage, 15% staff, 15% contingency.
Mini Project: Migration Wave Planner
# migration_planner.py
# Plan migration waves with dependencies and timelines
from typing import List, Dict
from datetime import datetime, timedelta
class AppMigration:
def __init__(self, name: str, strategy: str, dependencies: List[str],
complexity: str, data_gb: int):
self.name = name
self.strategy = strategy
self.dependencies = dependencies
self.complexity = complexity
self.data_gb = data_gb
def estimated_days(self) -> int:
base = {"Rehost": 5, "Replatform": 15, "Refactor": 40, "Repurchase": 20}
complexity_mult = {"Low": 1, "Medium": 2, "High": 3}
return base[self.strategy] * complexity_mult[self.complexity]
def plan_waves(apps: List[AppMigration]) -> List[Dict]:
unplanned = {a.name: a for a in apps}
waves = []
wave_num = 1
start_date = datetime.now()
while unplanned:
# Find apps with all dependencies met
wave_apps = []
for name, app in list(unplanned.items()):
deps_met = all(dep not in unplanned for dep in app.dependencies)
if deps_met or not app.dependencies:
wave_apps.append(app)
del unplanned[name]
if not wave_apps:
break # circular dependency
wave_end = start_date + timedelta(days=max(a.estimated_days() for a in wave_apps))
waves.append({
"wave": wave_num,
"apps": [a.name for a in wave_apps],
"start": start_date.strftime("%Y-%m-%d"),
"end": wave_end.strftime("%Y-%m-%d"),
"duration_days": max(a.estimated_days() for a in wave_apps),
"total_data_gb": sum(a.data_gb for a in wave_apps),
})
start_date = wave_end
wave_num += 1
return waves
print("=== Migration Wave Plan ===\n")
apps = [
AppMigration("DevTools", "Rehost", [], "Low", 10),
AppMigration("Internal Wiki", "Rehost", ["ActiveDirectory"], "Low", 50),
AppMigration("ActiveDirectory", "Replatform", [], "Medium", 5),
AppMigration("CRM", "Replatform", ["ActiveDirectory", "Database"], "High", 100),
AppMigration("Database", "Replatform", [], "Medium", 500),
AppMigration("Customer Portal", "Refactor", ["Database", "CRM"], "High", 200),
]
waves = plan_waves(apps)
print(f"{'Wave':<8} {'Apps':<35} {'Duration':<12} {'Data':<12} {'Period'}")
print("=" * 75)
for w in waves:
apps_str = ", ".join(w["apps"])
print(f"Wave {w['wave']:<3} {apps_str:<35} {w['duration_days']:<12}d {w['total_data_gb']:<12}GB {w['start']} - {w['end']}")
total_duration = (datetime.strptime(waves[-1]['end'], "%Y-%m-%d") - datetime.strptime(waves[0]['start'], "%Y-%m-%d")).days
print(f"\nTotal migration timeline: {total_duration} days")
print(f"Total applications: {len(apps)}")
print(f"Total data to migrate: {sum(w['total_data_gb'] for w in waves)} GB")
Expected output:
=== Migration Wave Plan ===
Wave Apps Duration Data Period
===============================================================================
Wave 1 DevTools, Internal Wiki, 10d 65 GB 2026-06-22 - 2026-07-02
Wave 2 ActiveDirectory, Database 30d 505 GB 2026-07-02 - 2026-08-01
Wave 3 CRM 45d 100 GB 2026-08-01 - 2026-09-15
Wave 4 Customer Portal 120d 200 GB 2026-09-15 - 2027-01-13
Total migration timeline: 205 days
Total applications: 6
Total data to migrate: 870 GB
Related Concepts
What's Next
You now understand cloud Migration assessment and planning methodologies. Next, explore cloud-native development for building applications after Migration, and cloud cost governance for managing post-Migration costs.
- Practice daily -- Create a TCO comparison for a sample workload using the AWS TCO Calculator
- Build a project -- Set up a multi-account AWS landing zone with Terraform
- Explore related topics -- Check out AWS Migration Hub or Azure Migrate for centralized Migration tracking
Remember: every expert was once a beginner. Keep coding!
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro