The Compute Mapping
Azure gives you a few primary compute options for .NET. Each maps to one or more AWS services depending on your workload:
| Azure | AWS Options | Best fit |
|---|---|---|
| App Service | ECS/Fargate | Long-running HTTP APIs |
| Azure Functions (Consumption) | Lambda | Event-driven, per-invocation billing |
| Azure Functions (Premium/Dedicated) | Lambda Managed Instances | Steady traffic, cost optimization |
| Azure Container Apps | ECS/Fargate | Containerized microservices |
| Azure Kubernetes Service (AKS) | EKS | Teams committed to Kubernetes |
| Azure VMs | EC2 | Lift-and-shift, legacy workloads |
App Service β ECS/Fargate
Azure App Service is the default for .NET web apps on Azure. It's a managed platform. Push a container or code package, get a URL. On AWS, ECS with Fargate is the production-grade equivalent:
ECS/Fargate (recommended)
- Task definitions, ALB, security groups. More configuration than App Service
- Full control over networking, scaling, deployment strategy
- Sidecar containers, service mesh, blue/green deployments
- Good for: production microservices, anything beyond a simple API
- ECS Express Mode (new) offers a simplified setup experience closer to App Service
Key differences from App Service
- No "always free" tier: App Service has a free F1 tier. AWS doesn't give you free compute (Lambda's free tier is the closest).
- Deployment slots: App Service has blue/green via deployment slots. On AWS, use CodeDeploy with ECS for the same pattern.
- Built-in auth: App Service has Easy Auth (one-click Azure AD integration). On AWS, put Cognito or a JWT authorizer on API Gateway in front of your service.
- Pricing model: App Service charges per App Service Plan (fixed instance). Fargate charges per-task per-second. Fargate is cheaper when you right-size; App Service is cheaper if you bin-pack many apps onto one plan.
Azure Functions β Lambda
The concepts are almost identical: event-triggered, per-invocation billing, auto-scaling, managed runtime. The differences:
What's better on Lambda
- Graviton (ARM64): 20% cheaper. Azure Functions doesn't run on ARM in the cloud
- Lambda Managed Instances: Run on EC2 with multi-concurrency for steady workloads (no Azure equivalent)
- Broader event sources: Lambda integrates with more AWS services natively
- Durable Functions built-in: AWS now has native durable execution (Azure had this first with Azure Durable Functions; AWS's version launched Dec 2025)
What's better on Azure Functions
- Visual Studio integration: Deploy from the IDE with one click (AWS tooling exists but is less polished)
- Durable Functions maturity: Azure's had Durable Functions for years; AWS's version is newer and supports fewer languages
- In-process hosting model: Azure lets you run functions in the ASP.NET host process (Lambda doesn't)
- Native AoT: Works on both platforms (it's a .NET feature), but Azure's tooling integration is more polished since Microsoft owns both
What to watch for in migration
- Trigger mapping: Azure's Service Bus trigger β Lambda's SQS event source. Blob trigger β S3 event notification. Timer trigger β EventBridge Schedule.
- Bindings don't exist: Azure Functions "bindings" (declarative input/output) have no Lambda equivalent. You write explicit SDK calls instead. More code, more control.
- Cold starts: Both platforms support Native AoT for ~200-400ms cold starts. Without AoT, both have similar 1.5-3s cold starts for .NET managed runtime. Lambda Managed Instances eliminate cold starts entirely for steady workloads. Azure Functions Premium does something similar with pre-warmed instances but at higher cost.
Azure Container Apps β ECS/Fargate
Container Apps is Azure's "simpler than AKS" container platform. It maps closest to ECS with Fargate:
| Azure Container Apps | AWS (ECS/Fargate) |
|---|---|
| Container environments | ECS Clusters |
| Revisions | Task definition versions |
| Scale rules (KEDA) | Auto-scaling policies (target tracking, step scaling) |
| Dapr integration | No built-in equivalent (use App Mesh or roll your own) |
| Built-in service discovery | Cloud Map / ECS Service Connect |
The transition is reasonable. Dockerfiles stay the same. The orchestration configuration changes.
Cost Comparison
For a typical .NET API handling 5M requests/month with 200ms average response time:
| Azure | Monthly | AWS | Monthly |
|---|---|---|---|
| App Service (B2) | ~$55 | Fargate (0.5 vCPU / 1GB) | ~$30 |
| Azure Functions (Consumption) | ~$8 | Lambda (256MB, ARM64) | ~$5 |
| Azure Functions (Premium EP1) | ~$160 | Lambda Managed Instances (w/ SP) | ~$40-60 |
| Container Apps (1 vCPU / 2GB) | ~$45 | Fargate (1 vCPU / 2GB) | ~$35 |
AWS is generally 20-40% cheaper for equivalent compute, before Savings Plans. With a 1-year Compute Savings Plan, the gap widens to 40-60%.
The Graviton advantage is unique to AWS. 20% cheaper for the same performance with no equivalent on Azure.
Migration Path
- Containerize first (if not already). Docker works identically on both clouds. This is the portable abstraction.
- Pick your AWS compute target based on workload characteristics (see table above).
- Rebuild the deployment pipeline. This is where the work is.
- Migrate one service at a time. Run both clouds in parallel during transition.
Don't try to migrate compute and data simultaneously. Move the stateless compute layer first (it's lower risk), then migrate data stores once the compute layer is stable on AWS.
Further Reading
- AWS Lambda overview: scaling model, pricing, concurrency
- ECS/Fargate overview: when to use containers vs Lambda
- .NET on Lambda: handlers, DI, AoT patterns
- .NET on ECS: Dockerfiles, health checks, CDK
Looking for hands-on help? View my modernization services β