CH04-01: Compute Selection Mental Model
Goal
Part 1 gave you the Azure foundation: hierarchy, governance, networking, access, and guardrails. Once those boundaries exist, the next practical question is where application code should run.
Compute selection is the architecture decision that chooses an execution model and an operating boundary. It decides whether the team runs code as a web application, an event-driven function, a containerized service, a Kubernetes workload, or a virtual machine. That choice affects deployment, scaling, monitoring, incident response, security hardening, and cost long after the first release.
The durable idea for this chapter is:
The best compute choice is the one whose operating model matches the workload and the team that must run it.
The Short Version
Compute is where code runs. In Azure, that might mean a managed web hosting service, a serverless function, a managed container environment, a Kubernetes cluster, or a virtual machine.
The easy question is:
Which service can run my code?
The better architecture question is:
Which service gives this component the right amount of control, scaling behavior, operational responsibility, and cost predictability?
Many Azure compute services can run similar application code. That does not make them interchangeable. A web API can sometimes run on App Service, Container Apps, AKS, Functions, or a VM. The service choice should come from the workload shape and the operating model, not only from whether the code technically starts.
Do not worry if several service names appear in this chapter. Azure App Service, Azure Functions, Azure Container Apps, Azure Kubernetes Service, and Azure Virtual Machines will each get their own explanation. For now, focus on the responsibility each option moves toward Azure or leaves with your team.
The Responsibility Ladder
A useful first model is a ladder from more managed to more controlled:
More managed More control
Azure Functions -> Azure App Service -> Azure Container Apps -> AKS -> Azure Virtual Machines
This is a simplified mental model, not a law of physics. Real services have hosting plans, networking options, scaling settings, security controls, and edge cases. But the ladder helps you ask the right first question: how much of the runtime and platform should the team operate directly?
| Compute Option | Plain-Language Job | Responsibility Signal |
|---|---|---|
| Azure Functions | Run small pieces of code in response to triggers. | Let Azure manage most runtime concerns, but design events, state, retries, and observability carefully. |
| Azure App Service | Host web apps and APIs on a managed platform. | Let Azure manage much of the web hosting infrastructure while the team owns application design and configuration. |
| Azure Container Apps | Run containers without managing a Kubernetes cluster directly. | Use container packaging while reducing platform operations. |
| Azure Kubernetes Service | Run containers on managed Kubernetes. | Use Kubernetes APIs and ecosystem, but operate the cluster platform responsibly. |
| Azure Virtual Machines | Run workloads with OS-level control. | Keep maximum compatibility and control while owning more patching, hardening, scaling, and recovery work. |
The more managed options reduce infrastructure work, but they do not remove architecture work. The more controlled options increase flexibility, but they also increase the amount of operating discipline required.
Decision Dimensions
When choosing compute, evaluate the component instead of starting with a product name.
Ask these questions:
| Decision Dimension | What You Are Really Asking |
|---|---|
| Workload shape | Is this a web app, API, background job, event handler, containerized service, batch task, or legacy runtime? |
| Runtime control | Does the team need OS access, custom installed software, special networking, specific libraries, or a particular orchestration model? |
| Deployment model | Does the team deploy application packages, containers, Kubernetes manifests, VM images, or configuration scripts? |
| Scaling behavior | Does demand follow requests, events, queue depth, schedules, CPU, memory, or planned capacity? |
| Operational overhead | Who patches, monitors, scales, secures, backs up, and recovers the runtime? |
| Team skill | Does the team already know web hosting, serverless patterns, containers, Kubernetes, or VM operations? |
| Reliability needs | How will the component handle restarts, failures, regional design, dependency outages, and deployments? |
| Cost pattern | Is the workload steady, bursty, unpredictable, latency-sensitive, or tied to reserved capacity? |
These dimensions matter because compute choice is rarely isolated. It touches the networking choices from Chapter 3, the governance boundaries from Chapter 2, and the service-selection chapters that follow.
Component-by-Component Thinking
A common trap is choosing one compute service for an entire application too early.
Consider a customer platform with these components:
Customer platform
|
+-- Public web portal
+-- Internal API
+-- Image-processing job
+-- Containerized worker
+-- Legacy reporting component
Each component has a different runtime shape. The public web portal may fit managed web hosting. The image-processing job may fit an event-driven function. The containerized worker may fit managed container hosting. The legacy reporting component may need a virtual machine because it depends on installed Windows components.
The architecture does not become weaker because it uses more than one compute service. It becomes weaker when every component is forced into the same service even though the responsibilities differ.
Control Is Not Automatically Better
Control is useful when the workload needs it.
Control lets you install custom agents, tune the OS, run specialized software, manage cluster-level policies, or match a legacy runtime exactly. But control also means someone must manage the consequences. Patching, image management, scaling rules, capacity planning, backup, security hardening, and incident response all become part of the architecture.
This is why "we know VMs" or "we use Kubernetes everywhere" is not enough. Familiarity helps, but it should not hide the operating cost of the choice. A team that can deliver safely on App Service may not yet be ready to run a shared AKS platform. A team that needs a legacy Windows dependency may still choose a VM, but it should do so deliberately.
Example: One Platform, Several Compute Answers
Imagine a SaaS team modernizing a customer platform. The team needs a web portal, an API, background processing for uploaded documents, a containerized notification worker, and a legacy reporting engine.
A first-pass compute model might look like this:
| Component | Likely Compute Direction | Why |
|---|---|---|
| Customer portal | Azure App Service | It is a request-driven web application that benefits from managed web hosting. |
| API | Azure App Service or Azure Container Apps | The answer depends on whether the team deploys as application code or containers. |
| Document processing | Azure Functions | The work starts from events such as uploads or queue messages. |
| Notification worker | Azure Container Apps | The worker is already containerized and does not need direct Kubernetes control. |
| Legacy reporting engine | Azure Virtual Machine | It needs installed components or OS-level compatibility that managed services may not support. |
This is not the final architecture. It is a responsibility map. The next sections explain how to refine each option.
Common Mistakes
Choosing the most familiar compute service without checking the operating model.
Treating Kubernetes as required for every container.
Assuming serverless means there are no architecture decisions.
Selecting virtual machines by default because they resemble the old environment.
Comparing compute services without considering monitoring, deployment, incident response, security, and cost controls.
Choosing a compute service for the whole application instead of evaluating distinct components.
If Someone Asks You
How do you choose an Azure compute service?
A good answer is:
I start with the workload shape and operating responsibility. I ask what kind of code is running, how it should scale, how much runtime control the team needs, who will operate it, and what cost pattern is acceptable. Then I choose the Azure compute service whose managed boundary fits that component. One application may use several compute services if its components have different jobs.
What You Should Remember
Choose compute by matching workload shape to operating responsibility.
Questions to Check Your Understanding
What changes when a compute service is more managed?
Why might one application use more than one compute service?
Which compute decision dimensions affect operations after deployment?