Deployment Options for a Web API in Azure
App Service and AKS sit at opposite ends of a spectrum: App Service is a managed platform where you deploy code or a container and Azure runs everything else, while AKS is managed Kubernetes where you get full control of the orchestration layer and take on the operational work that comes with it. There are also middle-ground options, covered below.
App Service
A PaaS for web apps and APIs. You deploy code (zip, Git, CI/CD) or a single container, and Azure handles the OS, patching, load balancing, TLS, and scaling.
Strengths:
- Fastest path to production, with very little operational overhead
- Built-in deployment slots (Standard tier and above) for zero-downtime swaps and instant rollback
- Autoscale, custom domains, managed certificates, Easy Auth, VNet integration, and managed identity
- Native .NET support, with no Dockerfile required
- A predictable, per-plan price
Limitations:
- Less control over networking, scheduling, and the runtime environment
- Multi-container setups are limited. It's one app per container, with no real orchestration
- Not suited to complex microservice meshes, sidecars, or custom operators
- Scale is bounded by plan limits (though it's plenty for most APIs)
Deploying:
az webapp up --name my-api --resource-group my-rg --runtime "dotnet:8"
# or, in CI/CD: azure/webapps-deploy@v3 with a staging slot, then swap
AKS (Azure Kubernetes Service)
Managed Kubernetes. Azure runs the control plane, and you manage the workloads, node pools, networking, ingress, and upgrades. AKS Automatic is a newer mode that manages more for you (node provisioning, scaling, and defaults), which narrows the gap with simpler platforms.
Strengths:
- Full Kubernetes ecosystem: Helm, operators, service meshes, GitOps, custom controllers
- Fine-grained control over scheduling, networking, resource limits, and node types (including GPU or spot nodes)
- Good for many services, sidecars, and portability across clouds
- Efficient bin-packing of many workloads onto shared nodes
Limitations:
- Real operational burden: cluster upgrades, node patching, ingress, certificates, observability, and security hardening
- Needs Kubernetes expertise on the team
- You must containerize everything
- Costs include the nodes (paid whether busy or idle) plus the effort to run the platform
Deploying:
az acr build --registry myacr --image my-api:1.0.0 .
az aks get-credentials --name my-aks --resource-group my-rg
kubectl apply -f deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata: { name: my-api }
spec:
replicas: 3
selector: { matchLabels: { app: my-api } }
template:
metadata: { labels: { app: my-api } }
spec:
containers:
- name: my-api
image: myacr.azurecr.io/my-api:1.0.0
ports: [{ containerPort: 8080 }]
readinessProbe: { httpGet: { path: /health, port: 8080 } }
resources:
requests: { cpu: 250m, memory: 256Mi }
limits: { memory: 512Mi }
You'd also add a Service and an Ingress (for example, Application Gateway for Containers or NGINX), use workload identity for Azure access, and roll out with Helm or Flux/Argo CD.
Side-by-side
| App Service | AKS | |
|---|---|---|
| Model | PaaS, you deploy an app | Managed Kubernetes, you run workloads |
| Packaging | Code or container | Container (required) |
| Operational effort | Low | High |
| Learning curve | Gentle | Steep |
| Scaling | Autoscale rules, per plan | Pod autoscaling (HPA/KEDA) plus node autoscaling |
| Zero-downtime release | Deployment slots | Rolling updates, canary, blue/green via ingress or mesh |
| Networking control | Moderate (VNet integration, private endpoints) | Very high (CNI options, network policies, service mesh) |
| Multi-service / microservices | Possible, one plan hosting many apps | Native fit |
| Cost model | Pay per plan | Pay for nodes, plus platform effort |
| Best for | Typical APIs and web apps | Large, complex, multi-service platforms |
Other options worth considering
- Azure Container Apps: serverless containers built on Kubernetes (with KEDA and Dapr) but without cluster management. Supports scale-to-zero, revisions with traffic splitting, and event-driven scaling. For many teams it's the best middle ground between App Service and AKS.
- Azure Functions: for small, event-driven, or bursty APIs where per-execution billing and scale-to-zero make sense.
- App Service Environment (ASE v3): single-tenant, VNet-injected App Service for strict isolation and compliance needs.
- Azure Container Instances: simple, short-lived containers. Rarely the right choice for a production API on its own.
- Virtual Machines: only if you need OS-level control or have legacy requirements.
How to choose
- A single API or a handful, a small or mid-sized team, and you want to ship quickly → App Service
- Containerized microservices, but you don't want to run Kubernetes → Container Apps
- Spiky or event-driven workloads, minimal API surface → Functions
- Dozens of services, a platform team, a need for service mesh, operators, custom scheduling, or multi-cloud portability → AKS
- Strict network isolation or compliance requirements on a PaaS model → App Service Environment
A practical rule: start with App Service (or Container Apps) and move to AKS only when you hit a concrete limit. Teams often adopt AKS for the flexibility they imagine they'll need, then spend a lot of effort on cluster operations that App Service would have handled. Because both can run the same container image, moving later is less painful if you containerize from the start.
Cross-cutting concerns (the same on all of them)
- Use managed identity and Key Vault instead of stored credentials.
- Put APIM, Front Door, or Application Gateway in front for routing, WAF, and rate limiting.
- Send telemetry to Application Insights and define health checks and alerts.
- Deploy through CI/CD with infrastructure as code (Bicep or Terraform).