Cross-cloud moves from Azure to AWS are driven by consolidation (often post-M&A), pricing/commitment optimization, breadth of AWS services, or strategy, rarely by the IaaS itself. Base compute rates are similar across hyperscalers, so savings come from rightsizing, committed-use discounts, and avoiding egress, not the move. Be clear on your motive first, it shapes everything. And know going in: lifting VMs is easy; untangling managed services is the real work.
The managed services carry the lock-in, not the VMs
Azure VM → EC2 is mechanical. The difficulty, and the lock-in, is in the managed services:
- Azure SQL / SQL MI → RDS / Aurora (via DMS); Cosmos DB → DynamoDB (data-model rework).
- Blob Storage → S3; Azure Files → EFS/FSx.
- Azure Functions → Lambda; Service Bus / Event Grid → SQS/SNS/EventBridge.
- Entra ID + Azure RBAC → IAM / IAM Identity Center (a different model, not a translation).
- Bicep/ARM → CloudFormation, or keep Terraform and re-target the AWS provider.
- AKS → EKS (re-platform manifests; mind ingress/identity differences).
Map each service before you move, this layer concentrates the re-architecture, testing, and surprises.
The service map is your real scope estimate
Draw the mapping table first, because it is the honest measure of scope. Azure SQL and SQL Managed Instance move to RDS or Aurora through DMS, and a matching engine keeps that clean. Blob Storage to S3 is close in shape, but re-express your lifecycle and access tiers rather than assuming they port. Cosmos DB to DynamoDB is the item to think hardest about: the partition-key and consistency models differ enough that it is a data-model exercise. Azure Functions map to Lambda with different triggers and packaging, Service Bus and Event Grid split across SQS, SNS, and EventBridge, and AKS to EKS is portable at the manifest level but the ingress and identity glue is not. Mark each row mechanical or re-architecture and assign an owner, so nothing surfaces as a surprise during cutover.
Watch the Microsoft licensing angle
A specific Azure→AWS wrinkle: Windows Server and SQL Server licensing. On Azure you may use Azure Hybrid Benefit or included licensing; on AWS you’ll run license-included instances or bring your own (BYOL) with the rules that entails. Model the Windows/SQL licensing cost on AWS explicitly, it can move the business case either way.
Stand up the landing zone before anything moves
Build the AWS landing zone first: AWS Organizations, accounts, networking (VPC, subnets, security groups), identity (IAM Identity Center), and guardrails. Establish connectivity (VPN or Direct Connect) back to Azure for replication. Inventory Azure resources tagged by application so you migrate coherent app groups.
Let MGN and DMS do the replication
- Servers: AWS Application Migration Service (MGN), block-level replication of Azure VMs into EC2 with minimal downtime.
- Databases: AWS DMS (full load + CDC) to keep targets current until cutover.
- Storage: AzCopy / DataSync to move Blob → S3 (mind egress, see below).
Re-platform IaC rather than clicking it twice.
Rebuild the AWS side in code, since Bicep won’t carry across
Recreate the AWS environment as code from the outset rather than hand-building it in the console. Keep Terraform and re-target the AWS provider, or adopt CloudFormation, whichever fits your team, but treat the IaC baseline as a first-class deliverable. Done well it gives you a reviewable definition of production, a staging copy to pilot against, and a repeatable pattern so later app groups are cheaper than the first. Encode the IAM and IAM Identity Center model in the same code so identity is designed in, not retrofitted. Bicep and ARM do not carry across, so this is a genuine rebuild, and it is worth doing carefully once.
Watch the egress, it can dominate
Moving large datasets out of Azure incurs egress fees, a one-time cost that surprises teams mid-project. Factor egress into the plan and the business case, and validate that AWS committed-use/Savings Plans pricing actually beats your Azure spend for steady-state workloads.
One egress bill, plus the licensing math
Move the data so you pay egress once. Run the bulk Blob-to-S3 copy with AzCopy or DataSync while the source is still serving traffic, then reconcile a small delta during the freeze rather than recopying the whole store. Delete stale blobs and expired snapshots first, because you are billed to move every byte regardless of whether you still need it. Keep egress on its own line in the business case: it is a one-time migration cost, not part of the steady-state per-vCPU comparison, and folding it into the ongoing figure distorts both. When AWS Savings Plans pricing only just edges out your current Azure spend, a heavy egress bill plus the Windows and SQL licensing math can decide whether the move actually pays for itself, so model all three together in the calculator above.
Cut over app group by app group
- Replicate a pilot workload + database end to end and validate before scaling.
- Per app group: final delta sync via MGN/DMS, freeze source writes, cut over DNS (Route 53), validate apps, integrations, and cost.
- Run a hypercare window with Azure as fallback; keep replication until sign-off.
Acceptance bar: functional + integration parity, performance at/above baseline, and validated cost, not just “the VMs booted.”
Our take
Azure → AWS is straightforward for VMs and decidedly hard for managed services, that layer drives the re-architecture, lock-in, egress bill, and Windows/SQL licensing math. Lead with the landing zone, use MGN + DMS, model egress and steady-state cost honestly, and cut over app group by app group with Azure as fallback. Model your per-vCPU comparison in the calculator above, and treat the figures as illustrative until your pilot proves both function and cost.