Skip to content

Cloud Migration Assessment and Planning Explained -- Complete Guide

DodaTech Updated 2026-06-22 9 min read

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
Cloud Migration
Cloud Disaster Recovery
Cloud-Native Development
Cloud Cost Governance

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