Cloud

Deploying ASP.NET Core on Azure: App Service vs Container Apps vs AKS

Deploying ASP.NET Core on Azure: App Service vs Container Apps vs AKS

Azure gives you at least five ways to run an ASP.NET Core application, and choosing the wrong one is expensive in both directions: over-engineered Kubernetes clusters for a simple web app, or a platform that can't handle the background processing and scaling your product eventually needs. In practice the choice for most .NET teams comes down to three services: Azure App Service, Azure Container Apps and Azure Kubernetes Service (AKS). Here's how they compare and how I choose between them for client projects.

The short answer

  • App Service: the default for web apps and APIs. Least operational work, mature, predictable.
  • Container Apps: the default for containerised systems with several services, background workers or event-driven scaling, including scale to zero.
  • AKS: for organisations that need full Kubernetes control and have (or will hire) the platform team to run it.

Azure App Service

App Service is a fully managed platform for web applications. You deploy code (or a container), and Azure handles the operating system, patching, load balancing and TLS certificates.

Strengths

  • Fastest path to production: deploy from Visual Studio, GitHub Actions or Azure DevOps in minutes.
  • Deployment slots for zero-downtime releases: deploy to staging, warm it up, swap.
  • Built-in custom domains, free managed certificates, authentication (Easy Auth), autoscale rules and VNet integration.
  • Linux plans are cheap and run modern .NET very efficiently.

Limitations

  • You pay for the plan even when traffic is zero; there's no scale to zero on dedicated plans.
  • Scaling is based on CPU, memory or schedules rather than queue length or events.
  • Less suited to many small services or long-running background workers (WebJobs exist, but are limited).

Choose it for: company websites, line-of-business applications, a single API plus a front end, and SaaS products in their first years.

Azure Container Apps

Container Apps runs containers on a managed Kubernetes-based platform without exposing Kubernetes itself. You get revisions, ingress, autoscaling with KEDA and optional Dapr integration, while Microsoft runs the cluster.

Strengths

  • Scale on HTTP traffic, queue length (Service Bus, Storage queues), Kafka, cron and more, including scaling to zero, so idle workers cost nothing on the consumption plan.
  • Natural home for a modular monolith plus a few satellite services: an API, a worker, a scheduled job, all in one environment with internal networking.
  • Revisions with traffic splitting for blue/green and canary releases.
  • Container Apps Jobs for batch and scheduled workloads.
  • Works very well with .NET Aspire, which can generate the deployment for you with the Azure Developer CLI (azd up).

Limitations

  • You need to build and manage container images and a registry.
  • Cold starts when scaling from zero (keep a minimum replica for latency-sensitive APIs).
  • Less low-level control than raw Kubernetes: no custom operators or arbitrary cluster add-ons.

Choose it for: event-driven systems, products with background processing, several cooperating services, and workloads with very spiky traffic.

Azure Kubernetes Service

AKS gives you a managed Kubernetes control plane; everything else (node pools, ingress controllers, networking, policies, upgrades, observability) is yours to design and operate.

Strengths

  • Full Kubernetes API: Helm charts, operators, service meshes, GitOps with Flux or Argo CD.
  • Fine-grained control over networking, node types (GPU, spot, ARM) and multi-tenancy.
  • Portable skills and manifests across clouds.

Limitations

  • Real operational cost: cluster upgrades, security patching, capacity planning and on-call. Budget for platform engineering time, not just compute.
  • Easy to over-engineer. Many teams run a handful of services on AKS that would be cheaper and simpler on Container Apps.

Choose it for: large platforms with many teams and services, strict networking or compliance requirements, or an existing Kubernetes investment.

Side-by-side comparison

App ServiceContainer AppsAKS
Unit of deploymentCode or containerContainerContainer (Kubernetes manifests)
Ops effortVery lowLowHigh
Scale to zeroNo (dedicated plans)YesPossible with KEDA, you manage it
Event-driven scalingLimitedBuilt in (KEDA)Yes, you configure it
Background workersWebJobsApps and JobsAnything
Zero-downtime releasesDeployment slotsRevisions and traffic splittingRolling updates, your tooling
Best forWeb apps and APIsMicroservices, workers, event-drivenLarge platforms, full control

Preparing an ASP.NET Core app for any of them

Whichever platform you choose, the same practices make the app cloud-ready:

Containerise without a Dockerfile

The .NET SDK can build an optimised container image directly:

dotnet publish -c Release /t:PublishContainer -p:ContainerRepository=shop-api

Add health checks

builder.Services.AddHealthChecks()
    .AddDbContextCheck<AppDbContext>();

app.MapHealthChecks("/health/live", new() { Predicate = _ => false });   // process is up
app.MapHealthChecks("/health/ready");                                       // dependencies are reachable

Point the platform's liveness and readiness probes (or App Service health check) at these endpoints so unhealthy instances are replaced automatically.

Use managed identity instead of secrets

builder.Configuration.AddAzureKeyVault(
    new Uri(builder.Configuration["KeyVault:Uri"]!),
    new DefaultAzureCredential());

With a managed identity, the app authenticates to Key Vault, Azure SQL, Storage and Service Bus without any password in configuration.

Observability from day one

Add OpenTelemetry with the Azure Monitor exporter (or the Aspire service defaults) to get distributed traces, metrics and logs in Application Insights. When something breaks at 2 am, this is what tells you where.

Automate deployments

Use GitHub Actions or Azure DevOps with infrastructure as code (Bicep or Terraform) so every environment is reproducible. Deploy to a staging slot or revision, run smoke tests, then promote.

A word on cost

For a typical SaaS MVP, a single Linux App Service plan or a Container Apps environment on the consumption plan, plus Azure SQL or PostgreSQL Flexible Server, keeps monthly hosting modest. Costs usually grow from the database, logging volume and over-provisioned plans rather than from the compute choice itself. Set budgets and alerts in Azure Cost Management from the first day.

My default recommendation

Start on App Service if you have one web app or API. Move to (or start on) Container Apps when you add background workers, multiple services or event-driven scaling. Reach for AKS only when you have requirements that Container Apps can't meet and a team ready to operate Kubernetes. Because the app is containerised and configured through environment variables and managed identity, moving between them later is a deployment change, not a rewrite.

Planning a move to Azure or reviewing your current setup? See my cloud solutions service or contact me to discuss your architecture.

Share

We use cookies to personalize content and ads to make our site easier for you to use. We also share that information with third parties for advertising and analytics. By using this site, you agree to our terms & conditions. Privacy Policy