Cloud Tech by Victor
DevOpsIntermediate

Azure Compute

How Virtual Machines, App Service, and AKS trade control for convenience differently, and how to actually pick between them instead of defaulting to whichever one you already know.

Updated 2026-07-223 min read

Overview

Azure offers compute at multiple points on the same control-versus-convenience spectrum every cloud provider does: Virtual Machines give full OS-level control, App Service gives a fully managed platform for standard web workloads, and AKS gives managed Kubernetes for teams that need container orchestration without owning the control plane themselves. Picking between them is a workload-fit decision, not a maturity ladder, a standard REST API is usually a worse fit for a hand-managed VM than for App Service, while a workload needing custom OS-level tuning or unsupported dependencies genuinely needs a VM regardless of how "modern" the alternatives look.

Quick Reference

ServiceModelYou manageBest fit
Virtual MachineIaaSOS, runtime, scaling, patchingCustom OS/runtime needs, full control
VM Scale SetIaaS, fleet-managedSame as VM, but as a scalable groupIdentical VMs that need to scale with load
App ServicePaaSApp code and config onlyStandard web apps/APIs in supported runtimes
AKSManaged KubernetesWorker nodes, workloadsContainer orchestration without self-hosting the control plane

Syntax

bash
# App Service - deploy a web app without managing any VM
az webapp up --name my-api --runtime "NODE:20-lts" --sku B1
bicep
resource aks 'Microsoft.ContainerService/managedClusters@2024-01-01' = {
  name: 'aks-app'
  location: resourceGroup().location
  properties: {
    dnsPrefix: 'aksapp'
    agentPoolProfiles: [
      { name: 'default', count: 3, vmSize: 'Standard_DS2_v2', mode: 'System' }
    ]
  }
}

Examples

bash
# Deployment slots let App Service stage a new version and swap
# it into production with near-zero downtime, without a VM Scale
# Set's more involved rolling-update configuration.
az webapp deployment slot create --name my-api --resource-group rg-app --slot staging
az webapp deployment slot swap --name my-api --resource-group rg-app --slot staging

Start with the most managed option that fits

Default to App Service or AKS for standard workloads, and drop to a plain VM only when you hit a specific, genuine requirement it can't satisfy, not as a default starting point.

Visual Diagram

Common Mistakes

  • Defaulting to a Virtual Machine out of familiarity for a standard web workload that App Service would handle with far less operational burden.
  • Running Kubernetes on self-managed VMs without a specific reason, taking on control-plane operations AKS would otherwise handle.
  • Not using deployment slots on App Service, and instead deploying straight to production with real downtime during releases.
  • Undersizing a VM Scale Set's autoscale rules based on a single metric (CPU) when the actual bottleneck is something else (queue depth, memory), leaving the workload under-provisioned despite autoscaling being "on."

Performance

  • App Service's managed scaling reacts to configured rules and has some warm-up latency for new instances, very spiky, unpredictable traffic may need pre-warming or a lower scale-out threshold to stay ahead of demand.
  • AKS worker node performance is standard VM performance, choosing the right VM size for the workload matters exactly as much as it would for a plain VM.
  • VM Scale Sets scale linearly with configured limits; the ceiling is a deliberate configuration choice, not an automatic one, so it needs to be set with real peak load in mind.

Best Practices

  • Choose the most managed compute option that actually fits the workload's constraints, and only drop to more control (VM) when there's a specific, named reason.
  • Use deployment slots (App Service) or rolling updates (AKS) for zero-downtime releases rather than deploying directly to the serving instance.
  • Size AKS node pools and VM Scale Sets based on real observed load, and autoscale on the metric that actually reflects the bottleneck, not just CPU by default.
  • Revisit the compute choice as a workload matures, constraints that justified a VM early on may no longer apply once the workload stabilizes.

Interview questions

When would you choose Azure App Service over a Virtual Machine for hosting a web application?

App Service is a fully managed PaaS; it handles OS patching, runtime installation, and built-in scaling and deployment slots, so you only manage application code and configuration. A Virtual Machine is IaaS, full control over the OS and everything installed on it, but you own patching, scaling configuration, and availability yourself. Choose App Service when the workload is a standard web app/API in a supported runtime and the team wants to minimize operational burden; choose a VM when you need OS-level control, unsupported runtimes/dependencies, or specific compliance requirements that mandate managing the host directly.

What is an Azure VM Scale Set, and how does it differ from manually managing a group of VMs?

A VM Scale Set manages a group of identical, load-balanced VMs as a single logical unit, with built-in autoscaling based on metrics (CPU, custom metrics) and automated instance replacement on failure. Manually managing individual VMs means each scaling or patching action has to be repeated per instance, with no built-in mechanism to keep the fleet at a consistent size or to react automatically to load. Scale Sets are the IaaS-level building block that makes "run N identical VMs that scale with load" a supported, declarative configuration instead of a hand-rolled script.

What does AKS (Azure Kubernetes Service) manage for you compared to running Kubernetes yourself on VMs?

AKS manages the Kubernetes control plane (API server, etcd, scheduler) at no direct cost for the control plane itself; you only pay for the worker nodes, which still run as VMs you have some visibility into but don't have to manually install or upgrade Kubernetes onto. Running Kubernetes yourself on plain VMs means standing up and maintaining the entire control plane, including its high availability and upgrade process, which is a substantial and ongoing operational burden. AKS trades some control-plane visibility for removing that burden, which is why it's the default choice for running Kubernetes on Azure unless there's a specific reason to self-manage.

References

ShareXLinkedInReddit
Was this page helpful?
Suggest an improvement