Search Tech Journey

Find topics, journeys and posts

6-month learning plan68 / 130
back to blog
systemsintermediate 55m read

S068 · Azure Cloud — Identity, Storage, Networking, App Service

The four pillars of every real Azure workload — Entra ID + RBAC, Storage & Cosmos, VNets & Private Endpoints, App Service & Container Apps. What to pick and why.

⚙️SystemsM07 · Systems & Infrastructure· Session 068 of 130 90 min

🎯 Understand the four Azure pillars — Identity, Storage, Networking, Compute — well enough to design a small three-tier app on Azure without reaching for a tutorial.

Why this session exists

Azure is one of the top-3 clouds (with AWS and GCP) and, if you work in enterprise or Microsoft-shop territory, likely the one you'll ship on. It has ~200 services; you'll actually use ~10 daily. This session covers those ten under four crisp pillars so the console (and the Terraform) stops feeling like a wall of icons.

You will be able to
  • Name the four Azure pillars and one flagship service in each.
  • Explain the difference between Entra ID, Azure AD B2C, and RBAC assignments.
  • Choose between Blob, Table, Cosmos DB, Azure SQL for a given workload.
  • Design a VNet with subnets, NSGs, and a Private Endpoint to a PaaS service without asking Copilot.

Prerequisites

  • S065 · Docker — you know what an image + registry are.
  • S066 · Kubernetes basics — helpful when we cover AKS.
  • S060 · Linux fundamentals — cloud VMs are just Linux boxes with cloud metadata.


(a) Intuition · 5 min

A modern office building
🌍 Real world

A large office building has four fundamental systems: security desk (who are you, where can you go), storage rooms (files, warehousing, cold storage), plumbing + wiring (the network that connects everything, plus firewalls between floors), and meeting rooms + offices (compute — where actual work happens).

Every tenant of the building needs all four. Getting them wrong costs you evenings; getting them right lets everyone do their job without thinking about the building.

💻 Code world

Azure's four pillars map exactly: Identity (Entra ID + RBAC), Storage (Blob, Files, Cosmos, SQL), Networking (VNets, NSGs, Private Endpoints, Front Door), and Compute (VMs, App Service, AKS, Functions, Container Apps).

Every Azure architecture is some mix of these four. The 200 services are variations and specialisations — Azure ML is compute + storage + identity; Azure API Management is compute + networking + identity; Azure DevOps is identity + storage + compute.

The four pillars in one sentence each

One flagship service per pillar to anchor your mental model
  • Identity — Microsoft Entra ID (formerly Azure AD). Every request in Azure is authenticated as some principal (user, service principal, managed identity) with role assignments controlling what it can do.
  • Storage — Azure Storage Account (Blob is the flagship). Also Cosmos DB (globally distributed NoSQL), Azure SQL (managed OLTP), Data Lake Gen2 (hierarchical Blob for analytics).
  • Networking — Virtual Network (VNet). Subnets carve up private IP space; NSGs are stateful firewalls; Private Endpoints let PaaS services (Storage, Cosmos) live inside your VNet.
  • Compute — App Service (managed web hosting) for most CRUD apps; AKS (managed K8s) for microservice fleets; Functions for serverless events; Container Apps for ‘K8s without the K8s’.

A quick history so the naming makes sense

  1. 2008
    Windows Azure launches at PDC
    Originally a PaaS-only offering (Web + Worker roles). Renamed ‘Microsoft Azure’ in 2014.
  2. 2013
    IaaS + VMs GA
    Azure catches up with EC2. Linux VMs become first-class.
  3. 2014
    Satya Nadella era + open source push
    ‘Microsoft loves Linux’. Kubernetes-first cloud strategy from ~2017.
  4. 2019
    Azure Arc + hybrid strategy
    Manage on-prem and multi-cloud resources through Azure's control plane.
  5. 2023
    Azure AD renamed Microsoft Entra ID
    Identity becomes its own brand family (Entra ID, Entra Verified ID, Entra Permissions Management).
  6. 2024
    Azure Container Apps + Fabric
    ‘K8s without the ops’ (ACA) and unified data platform (Fabric = Synapse + Data Factory + Power BI).

(b) Visual walkthrough · 15 min

A reference three-tier app on Azure — what talks to what

The storage-service decision tree

Blob Storage

Big flat object store · pennies/GB

  • Anything unstructured: images, PDFs, backups, logs
  • Hot / Cool / Cold / Archive access tiers
  • Global reads via read-access geo-redundant (RA-GZRS)
  • Not for OLTP — no transactions, no indexes
Cosmos DB

Global NoSQL · single-digit ms

  • Multi-region writes, tunable consistency (5 levels)
  • APIs: SQL/NoSQL, MongoDB, Cassandra, Gremlin
  • Priced per RU/s + storage — expensive at scale
  • Fit: session store, product catalogue, user profiles, IoT ingest
Azure SQL

Managed relational OLTP

  • T-SQL you already know · zero patching
  • Elastic Pools for many small DBs sharing capacity
  • Serverless tier for spiky workloads (auto-pause)
  • Fit: existing SQL Server workloads, complex joins, ACID
Data Lake Gen2 + Fabric

Petabyte-scale analytics

  • Hierarchical namespace on top of Blob
  • Read directly from Spark, Synapse, Databricks
  • Delta / Iceberg tables for ACID on parquet
  • Fit: warehouse, ML feature stores, event lakes

The Identity model — what is a Managed Identity, and why do you care?

Three principal types in Entra ID

User
A human. Signs in via browser + MFA. Gets an access token that carries role claims. RBAC assignments say what the user can do on a scope (subscription, resource group, resource).
human
Service Principal (SP) + Client Secret
An app identity. The app knows a client ID + secret and calls the /token endpoint. Secrets rotate; secrets leak. Legacy pattern kept for on-prem apps.
app
Managed Identity (MI)
Azure-managed SP with no secret. The VM/App Service/AKS pod has an identity Azure manages; the SDK grabs a token from the metadata endpoint (169.254.169.254). ZERO secrets in your code. Use this always where possible.
modern

Networking — the five pieces you'll wire up

1
VNet · 10.0.0.0/16

Your private IP space in a region. Non-overlapping with other VNets you might peer to.

2
Subnets

Slice the VNet into logical zones — /24 for AKS, /26 for App Service, /28 for the DB, /27 for the private endpoints.

3
Network Security Groups (NSGs)

Stateful firewall rules attached to a subnet or NIC. Default deny-inbound-from-internet is applied unless you allow.

4
Private Endpoints

Give a PaaS service (Cosmos, Blob) a private IP inside YOUR subnet. Traffic never touches the public internet.

5
Front Door / Application Gateway

L7 public entry point. Front Door is global anycast + CDN + WAF; App Gateway is regional. Pick Front Door for user-facing apps.

Compute — pick one; don't shop

App Service

‘Managed web hosting’

  • Deploy a container OR a git push, auto-provisioned
  • Slots for blue/green (staging + prod swap in 5 s)
  • Auto-scale on CPU/queue, SSL managed
  • Fit: most CRUD web apps, APIs — starts here
Azure Container Apps

‘K8s without the K8s’

  • Serverless containers, scale to zero
  • KEDA-driven autoscaling (Kafka, HTTP, cron)
  • Dapr sidecar integration
  • Fit: microservices, event handlers, replacement for App Service for containers
AKS (Managed K8s)

Full Kubernetes if you need it

  • Everything from S066/S067 applies
  • Control plane free; you pay for nodes
  • Deep integration with Entra ID, Azure Policy, ACR
  • Fit: existing K8s workloads, multi-tenant fleets
Functions

Serverless events

  • One function per file/handler, triggers = HTTP, Queue, Blob, Timer
  • Consumption plan = pay-per-execution
  • Cold starts + short max duration (10 min consumption)
  • Fit: cron jobs, small event processors

Common misconception
✗ What most people think

"Azure regions are independent datacenters, and a region is a failure domain. If I deploy across two availability zones I'm protected from anything short of losing the whole region."

✓ What is actually true

Zones protect against datacenter-level failures — power, cooling, a network fabric fault in one building. They do not protect against a regional control-plane issue, a bad configuration deployed region-wide, a subscription-level quota exhaustion, or a dependency your service has on a single-region resource. Zone redundancy is necessary and it is not sufficient, and the failures that actually cause multi-hour outages are usually control-plane or configuration failures rather than physical ones.

Why the myth is so sticky

The myth is sticky because zone redundancy is the thing you can configure and see in a checkbox, so it becomes the mental summary of "we are highly available". Physical redundancy is also the failure mode that is easiest to reason about. The failures that get missed are the ones with no checkbox: a Key Vault in one region that every region depends on, a resource-group-scoped policy, a DNS record with a single origin.

Prove it to yourself

Find your true single points of failure by tracing dependencies rather than trusting your topology diagram:

# every resource and its actual location
az resource list --query "[].{n:name, loc:location, t:type}" -o table

# which of these are referenced by services in OTHER regions?
# key vaults, storage accounts, private DNS zones and
# container registries are the usual hidden singletons

az account list-locations --query "[?metadata.regionType=='Physical'].{name:name, pair:metadata.pairedRegion[0].name}" -o table
From first principles
Start with the question

Why does every cloud provider organise resources into a hierarchy — management group, subscription, resource group — instead of one flat pool you tag?

  1. 1
    A cloud platform must enforce access control, quotas, billing separation and policy across millions of resources belonging to mutually distrusting tenants.
    forced by · multi-tenancy means isolation is a correctness requirement, not a convenience
  2. 2
    Evaluating any of those against a flat set requires a predicate over every resource, and predicates over tags are mutable by whoever can edit tags.
    forced by · if a permission boundary depends on a tag, then editing a tag is a privilege escalation
  3. 3
    Therefore the boundary must be structural and immutable-ish — something a resource belongs to at creation and cannot silently change.
    forced by · an access boundary that can be altered by the thing it constrains is not a boundary
  4. 4
    A hierarchy additionally allows policy to be inherited, so a rule set at the top applies to everything below without enumerating it, and cannot be removed by someone lower down.
    forced by · containment gives you a natural, cheap "applies to all descendants" semantics with a clear precedence order
  5. 5
    Quotas and billing then attach naturally to levels of that hierarchy, because a level is a set with a known owner.
    forced by · a limit needs an entity to be enforced against, and containment defines exactly such entities
⇒ Therefore

Therefore the hierarchy is the enforcement substrate for isolation, policy inheritance, quota and billing simultaneously. Tags complement it for reporting; they cannot replace it for enforcement.

And note what this predicts: quotas are enforced per subscription per region, so a workload that grows will hit a limit that is invisible until it blocks a deployment — and the fix is a support request with lead time, not a code change. It also predicts that the subscription is your real blast radius boundary: an error affecting a subscription affects everything in it, which is exactly why separating production from non-production at the subscription level matters far more than separating them by resource group or naming convention.

Mental modelControl plane and data plane are different systems

Every cloud resource has two halves. The control plane creates, configures and deletes it — that is ARM, the portal, the CLI, Terraform. The data plane is the resource actually doing its job: serving queries, storing blobs, running containers. They have separate endpoints, separate authentication, separate SLAs and separate failure modes.

An outage in one does not imply an outage in the other. Your VMs keep running while ARM is degraded — you just cannot create new ones.

  • Design so that a control-plane outage does not become a data-plane outage. Anything that requires creating a resource to recover — scaling out, failing over by reconfiguration, provisioning a replacement — is unavailable exactly when you need it most. Pre-provision your recovery capacity.
  • Managed identity over secrets, everywhere it is supported. The identity is issued and rotated by the platform, so there is no credential to leak, expire unnoticed, or check into a repository. A connection string in configuration is a future incident with a long fuse.
  • Understand each service's scaling and pricing unit, because it determines both cost and failure behaviour: request units in Cosmos DB, DTUs or vCores in SQL, DWUs in Synapse. Throttling at the limit produces retriable errors that look like transient network faults until you correlate them with the limit.
  • Private endpoints change DNS resolution, not just routing. This is why a service works from one network and fails from another with a confusing name-resolution error — the private DNS zone must be linked to every virtual network that needs to resolve it.
🔔 Fires when you see

Fire this model when you see: a deployment failing while running workloads are fine · intermittent 429s under load · a service that resolves to a public IP from inside the VNet · a failover plan that depends on provisioning something · a subscription quota discovered during an incident.

The tradeoff

How do you carve up subscriptions and resource groups for a platform with multiple teams and environments?

One subscription per environment
+ you gain the strongest possible separation between production and everything else: distinct quotas, distinct policy, distinct RBAC, and a billing split that requires no tagging discipline. A mistake in dev cannot consume production's quota or trigger production's policy.
− you pay shared services used across environments become awkward, cross-subscription networking needs explicit peering, and every team operates in the same production subscription — so one team's quota consumption affects another's.
pick when small to mid-size organisations where the primary risk is a non-production change reaching production
One subscription per team per environment
+ you gain quota, blast radius and cost are all isolated per team, so a team can be given genuine autonomy inside its subscription without endangering anyone else. Cost attribution is exact with no tagging required.
− you pay subscription sprawl: dozens of subscriptions to keep consistently configured, with policy, networking and identity to manage across all of them. Without automation this becomes unmanageable within a year.
pick when when teams have genuinely independent workloads and you have platform engineering capacity to automate subscription provisioning (landing zones)
Resource groups as the boundary within few subscriptions
+ you gain the simplest model: fewer subscriptions to manage, lifecycle grouping is natural since a resource group can be deleted as a unit, and RBAC at group level is straightforward.
− you pay quotas are shared across everything in the subscription, so one team's scale event blocks another team's deployment. Blast radius for subscription-level mistakes covers everyone, and cost attribution depends entirely on tagging discipline that will decay.
pick when a single team or a small organisation where the coordination overhead of many subscriptions exceeds the isolation benefit
What a senior engineer actually does

Separate production into its own subscription on day one — that boundary is nearly free to establish early and extremely expensive to retrofit, because moving resources between subscriptions ranges from disruptive to impossible depending on the service.

Split further by team only when you feel a specific pain: quota contention, cost attribution arguments, or blast radius concerns. Each new subscription is a recurring management cost, so add them in response to evidence rather than in anticipation. The one thing worth doing before you have any pain at all is enforcing ownership and environment tags at creation time via policy — that is the metadata you cannot retrofit, and everything else can be reorganised later.


(c) Hands-on · 25 min

Deploy a Container Apps app that uses a Managed Identity to read a secret from Key Vault — no secrets in code, no client IDs floating around. Everything via Azure CLI so you see the exact primitives.

#!/usr/bin/env bash# s068-azure-demo.sh Container Apps + Managed Identity + Key Vault.# Requires: az CLI (>= 2.60), an Azure subscription you can create resources in.# COST: ~$0 in the free tier for an hour; delete the RG afterward.set -euo pipefail RG="rg-s068-$RANDOM"LOC="eastus"ACR="acrs068$RANDOM"KV="kvs068$RANDOM"ENV="cae-s068"APP="app-s068" log() { printf "\033[1;36m %s\033[0m\n" "

What each block does

Anatomy of the deployment

az group create · resource group
The unit of billing + lifecycle in Azure. Everything lives in a resource group. Delete the RG = everything inside dies.
org
az acr create · Azure Container Registry
Your private image registry. Same purpose as Docker Hub, but inside your subscription and reachable via Managed Identity.
registry
az acr build · in-cloud build
Skips your laptop — ACR builds the image on its own agents. Push happens automatically. Handy on ARM Macs shipping to x86.
build
az keyvault create · RBAC mode
New Key Vaults should use RBAC (not access-policy). Roles: Secrets Officer (rw), Secrets User (r). Composes with Entra role assignments — one auth model.
kv
--system-assigned Managed Identity
The Container Apps runtime creates an Entra service principal tied to the app's lifecycle. Delete the app = identity gone. No secret ever exists.
auth
DefaultAzureCredential in the app
The SDK auto-detects the running environment (Managed Identity in Azure, az login on laptop, GitHub OIDC in CI). Same code everywhere.
sdk
Try itAttach a Private Endpoint to Key Vault so it's unreachable from the public internet
# Rough outline — expand per Azure docs
az network vnet create -g $RG -n vnet-s068 --address-prefix 10.10.0.0/16 --subnet-name snet-pe --subnet-prefix 10.10.1.0/24
az network private-endpoint create -g $RG -n pe-kv -v vnet-s068 --subnet snet-pe \
  --private-connection-resource-id $(az keyvault show -n $KV --query id -o tsv) \
  --group-id vault --connection-name pe-kv-conn
az keyvault update -n $KV --public-network-access Disabled
# Container Apps in the same VNet still reach KV; the world doesn't.

You've just moved from "public with a firewall" to "no public surface at all". This is the standard enterprise posture on Azure.

💡 Hint · Create a VNet, subnet, and Private Endpoint. Then set the Key Vault firewall to public-network-access disabled. Your app still works (via the private IP); external attacker can't even reach the vault URL.

(d) Production reality · 15 min

War story Microsoft· 202014-hour partial Azure AD outage · March 15
🔥 What broke

An Azure AD (now Entra ID) rollout deployed a change to the token service in one region. A latent bug caused key material to be inaccessible; token issuance failed. Cascading impact: every Azure service that authenticates via AAD started returning 401 — Office 365, Xbox Live, Teams, and thousands of customer apps.

Because AAD is a global control plane, the blast radius was near-universal.

🧯 The fix
Rolled back the change; recovered over ~14 hours. Microsoft published a post-mortem committing to safe deployment (SDP) improvements — staged, cell-based rollouts with kill-switches for identity control-plane changes.
🎓 Lesson to steal
Identity is the single most critical shared service in a cloud. Design for auth-service degradation: use cached tokens, exponential backoff on 401, and consider fallback paths for critical endpoints. Don't assume ‘Entra is always up’.
Post-mortem
War story Microsoft· 2023Storm-0558 · signing key theft
🔥 What broke

A state-affiliated actor stole a Microsoft consumer signing key and used a validation bug to forge tokens for enterprise Exchange Online mailboxes — including US government tenants. Attackers read emails for ~a month before detection.

🧯 The fix
Rotated the key, patched the validation logic, added mandatory ‘Secure Future Initiative’ hardening — signing keys now live in HSM-backed vaults with strict rotation. Federal reviews accelerated cloud-security legislation.
🎓 Lesson to steal
Even Microsoft's key material can leak. Your defence: don't rely on any single identity provider layer alone. Use Conditional Access + device compliance + short token lifetimes. Assume tokens can be forged and design for containment.
Post-mortem
War story Common failure mode · missing NSG on database subnet· 2024daily on Azure
🔥 What broke
A team creates a VNet with an Azure SQL private endpoint but doesn't add an NSG restricting inbound traffic. Any pod anywhere in the VNet can reach the DB. A compromised container spider-crawls into it.
🧯 The fix
NSG on the DB subnet: allow ONLY the app subnet inbound on port 1433, deny everything else. Enable Defender for Cloud recommendations — it flags open lateral paths automatically.
🎓 Lesson to steal
‘Private endpoint’ means ‘not public’ — it does NOT mean ‘firewalled from other things in the same VNet’. Add explicit NSGs. Zero-trust starts with least-privilege networking, not just IAM.

Common footguns you'll hit

  • Confusion of subscriptions, resource groups, tenants — a tenant is your Entra ID directory; subscriptions live inside; resource groups organise resources within a subscription. Get the hierarchy wrong and you make a resource nobody has access to.
  • Role assignment propagation delay — RBAC changes take up to ~5 min to propagate. Add a sleep in scripts; expect the first call after a change to sometimes 403.
  • Public endpoints on Storage / Cosmos by default — new accounts are public-network-enabled. Turn it off; add Private Endpoints or firewall rules.
  • Az CLI logged in as the wrong subscriptionaz account set --subscription "your-sub". Add this to every script; don't rely on default context.

Where this shows up in the rest of the plan

Azure primitives feed the ops stack
S069 · IaC · Terraform
Bicep and Terraform provision every service you touched here. Same primitives, declarative.
S066 · Kubernetes basics
AKS is where the K8s objects from S066/S067 actually run in Azure.
S064 · CDN
Azure Front Door + Azure CDN — the Azure implementation of the CDN patterns you learned.
S078 · SRE · observability
Azure Monitor + Log Analytics + App Insights. Kusto queries against them.
S085 · Security
Entra ID + Managed Identity + Key Vault is the Azure identity story. Conditional Access, PIM, Defender.
S095 · System design · multi-region
Cosmos DB + Front Door + Traffic Manager = Azure's multi-region toolkit.

(e) Recall + stretch · 10 min

Recall — click each to reveal · click to reveal
★ = stretch question

Explain-out-loud test

  1. What are the four Azure pillars and which service anchors each?
  2. Why is Managed Identity better than a Service Principal with a secret?
  3. When would you pick App Service over AKS, and vice versa?

What comes next

Hub: The 6-Month Learning Plan


Part of a 130-session evergreen learning series. Session structure: intuition → visual → hands-on → production war stories → recall. Duration: 90 minutes.