Every hyperscaler is the same skeleton wearing a different vocabulary. A global fabric of regions containing zones; an identity spine that answers "who may do what, where"; and a hierarchy root where billing and policy attach. Learn the skeleton once and the three vocabularies stop being three subjects — they become one subject with a translation table.
That is the whole thesis of this stage. Four sessions: one vendor-neutral, then one per cloud. You will finish able to draw the shared-responsibility line for any service model, translate any core concept across AWS / Azure / GCP on demand, and explain each provider's hierarchy and global fabric from memory.
The Rosetta Stone
Below is the skeleton. Nothing on it is vendor-specific — it is just the set of questions every cloud must answer. Click any layer to see how each of the three clouds names it.
Same concept, three names
This is the table to internalise. Everything else in the stage is elaboration on it. The quirk line under each cell is the part that trips people up when they move between clouds.
| Neutral concept | AWS | Azure | Google Cloud |
|---|---|---|---|
| Geographic area | RegionMinimum 3 AZs, always. AWS makes a point of this. | Region, grouped into a GeographyExtra layer: geography is the data-residency boundary. Not all regions have zones. | Region3+ zones. Plus a distinct "multi-region" concept for storage. |
| Fault domain in a region | Availability Zone (AZ)AZ names are shuffled per account — us-east-1a is a different building for you than for me. |
Availability zoneNumbered 1/2/3, also shuffled per subscription. "Zone-redundant" SKUs spread for you. | ZoneNamed region-a, -b, -c. Also shuffled. New: AI zones, e.g. us-central1-ai1a. |
| Isolation / quota boundary | AccountCheap, disposable, hard walls. The multi-account strategy is the AWS security model. | SubscriptionBilling + quota unit. Below it, resource groups add a second, softer grouping layer. | ProjectCheap, disposable, the default trust boundary. Everything you create lives in exactly one. |
| Grouping above the boundary | Organizational Unit (OU) inside AWS OrganizationsNest up to 5 levels below root. | Management groupUp to 6 levels deep, 10,000 per directory. | FolderUp to 10 levels deep, 300 direct children per parent. |
| Hierarchy root | Organization (management account)The management account should hold no workloads. Ever. | Tenant (Microsoft Entra ID directory) → root management groupIdentity root and billing root are the same tree here. | Organization resourceComes from Cloud Identity / Workspace. Billing accounts hang off to the side, not inside it. |
| Identity spine | AWS IAM + IAM Identity CenterIdentity Center is the ex-"AWS SSO". Roles, not users, for anything real. | Microsoft Entra ID (ex-Azure AD) + Azure RBACTwo planes: Entra ID authenticates, RBAC authorizes on resources. | Cloud IAM + service accountsRoles are collections of permissions; you bind them to principals at a hierarchy node. |
| Preventive guardrail | Service Control Policy (SCP) + Resource Control Policy (RCP)SCP caps what your principals may do; RCP caps who may touch your resources. | Azure PolicyDeny / audit / modify — Azure Policy can also mutate resources, which the others don't do. | Organization Policy (constraints)Constraint-based, not IAM-shaped. Separate system from IAM allow-rules. |
| Control plane / IaC native | CloudFormation (+ CDK)There is no single mandatory gateway API; services expose their own. | Azure Resource Manager (ARM) + BicepEverything goes through ARM. Truly everything — the portal is just an ARM client. | Deployment Manager (legacy) / Terraform / Config ConnectorGoogle leans hardest on third-party IaC; the CLI is the cultural default. |
| Edge / CDN presence | Edge Locations, Local Zones, Outposts, Wavelength400+ edge locations; Local Zones are metro extensions of a parent region. | Edge Zones, Azure Arc, Azure StackArc is the outlier: it manages non-Azure machines as if they were Azure resources. | Points of presence on Google's private backbone, Distributed CloudGoogle's fibre is the differentiator: traffic leaves the public internet early. |
| "Build it right" doctrine | AWS Well-Architected Framework — 6 pillarsPlus a lens catalogue: Generative AI, ML, Responsible AI lenses. | Azure Well-Architected Framework — 5 pillarsNo sustainability pillar; sustainability guidance lives elsewhere. | Google Cloud Well-Architected Framework — 6 pillarsRenamed from "Architecture Framework"; adds cross-pillar "perspectives". |
Verified Jul 2026 Counts and limits sourced in the session tabs. Hierarchy limits: Azure management groups Google resource hierarchy AWS authorization policies
Three habits this stage installs
When you meet a new service name, ask which layer of the skeleton is this? before asking what it does. A name you can place is a name you can reason about; a name you can only memorise is trivia that expires.
For any service, immediately draw the shared-responsibility line: what does the provider secure, what do you? The line moves as you climb IaaS → PaaS → SaaS, and the layers just above it are where every real incident lives.
An architect writes the requirement, then picks the service. Reverse that order and you get lock-in by accident rather than by decision. Lock-in is sometimes the right call — but only when it's a call.
How the sessions build
S1 builds the skeleton. S2–S4 hang one vocabulary on it each, in the order that makes the contrasts sharpest: AWS's account-wall model, then Azure's extra tenant layer, then Google's global-by-default inversion.
Your reading list, corrected
Four things differ, and one of them changes what S1 can be taught from.
| You wrote | The material actually is | What that changes |
|---|---|---|
| "Cloud Architecture Patterns" | the cloud application patterns catalog — A cloud patterns catalog, . §1 is "Cloud Applications". | section title matches. But its §1 covers NIST's definition, cloud-vs-traditional-IT practices, and the root Cloud Application pattern — it does not cover IaaS/PaaS/SaaS or public/private/hybrid at all. Those live in the GCP source's §1 opening and Azure §1. S1 therefore draws on all three. |
| AWS guide by "KnoDAX" | AWS guidance, AWS architecture guidance (2,290 pp). | Field note only. §1 = exam overview = AWS Global Infrastructure. Both correct as assigned. |
| S2 covers "the AWS account model" | §1–2 contain no coverage of accounts, Organizations, or OUs. That material starts in §3 (IAM), which covers cross-account access, Identity Center and Organizations. | I still teach the account model in S2 — you can't understand blast radius without it — but sourced from AWS docs rather than the material, and flagged so you know where the material picks it up. |
| GCP "§1 + intro/architect framing" | §1 is titled "GCP Compute Engine". It front-loads cloud fundamentals (5 characteristics, 3 deployment models, 3 service models), then covers regions/zones and the resource hierarchy before getting to VMs. | Perfect fit for S4 anyway — the hierarchy and regions/zones sections are exactly what we need. The material is by GCP guidance, as you had it. |
Freshness ledger — where the materials have already drifted
Cloud facts rot faster than almost anything in tech. Here is every number in your assigned section that is now wrong, with the current fact and its source. Each one recurs in its session tab.
| Source | What it says | What's true now (July 2026) | Source |
|---|---|---|---|
| GCP | "As of writing this material in December, 2023, GCP had 39 Regions, 118 Zones" | 43 regions, 130 zones, plus a new class of AI zones that didn't exist when the material was written. | cloud.google.com/about/locations, updated 23 Jul 2026 |
| Azure | "over 60+ regions with 300+ data centers" | Microsoft now states over 70 regions. Roughly 35 of them advertise availability-zone support — the rest are single-zone. | Microsoft Learn: What are Azure regions? |
| AWS | Region/AZ counts given only qualitatively; "over 400 edge locations" | 123 AZs across 39 regions, with 7 more AZs and 2 more regions announced (Saudi Arabia, Chile). Edge count still 400+. | AWS Global Infrastructure, page updated 15 Jul 2026 |
| All three | Free-tier descriptions assume 12-month free usage tiers | AWS replaced that on 15 Jul 2025 with a credit model: $100 on signup, up to $200 total, expires at 6 months. Azure = $200 for 30 days + 12 months of select services. GCP = $300 for 90 days. | AWS announcement Azure Google |
| Azure | Uses "Entra tenant" correctly, but surrounding material still mixes in older Azure AD phrasing | Azure AD is Microsoft Entra ID, renamed from Aug 2023. Same service, no migration. "Azure AD tenant" → "Microsoft Entra tenant". | Microsoft Learn: New name for Azure AD |
| AWS | Governance discussion predates two new AWS Organizations policy types | Resource control policies (RCPs) launched Nov 2024; declarative policies followed. And in Sept 2025 SCPs gained the full IAM policy language. | RCP launch |
| GCP | Framework referred to as the "Google Cloud Architecture Framework" with a System Design category | Renamed Google Cloud Well-Architected Framework. System Design was removed as a category; Sustainability was promoted to a full sixth pillar (Jan 2026). | Google Cloud WAF |
| All three | GPU instance families predate Blackwell | Current top-end: AWS P6e-GB200/GB300 UltraServers, Azure ND GB200/GB300 v6, Google A4/A4X. Your T4 and L4 work is still perfectly valid — see S4. | AWS P6e-GB300 GA |
Not "my sources are bad" — they're fine. The habit is: never quote a cloud number from memory or from print. Region counts, quota defaults, free-tier terms and service names all drift on a monthly cadence. Every number in this stage carries a link to the vendor page it came from, so you can re-check it in ten seconds rather than repeating a stale figure in an architecture review.
What you can do at the end of C1
Draw the shared-responsibility line for any named service, at any service model, without looking it up.
Translate any core concept across all three clouds instantly — and say what the translation loses.
Explain each provider's resource hierarchy and global fabric from a blank whiteboard.
Reach for requirements before service names — and notice when someone else hasn't.
Session 1 · The skeleton, before any vendor gets to name it.
"The cloud is just someone else's computer" is the most expensive joke in IT
It's funny because it's half true, and it's expensive because of the other half. Yes, the machines belong to someone else. But a single rented server gives you almost none of what makes cloud cloud: you can't summon a hundred more in ninety seconds, you can't hand a colleague a self-service slice of it, you can't pay only for the four minutes you used, and you certainly can't delete the whole thing with one API call and stop being billed.
The practical consequence: teams migrate an application unchanged onto rented VMs, discover it runs worse and costs more than it did on-premises, and conclude the cloud was oversold. What actually happened is that the application was built on assumptions the cloud deliberately breaks — that the hardware is reliable, that it never moves, that it's yours alone, that you scale by buying a bigger box.
And underneath every one of those assumptions sits a question nobody wrote down: who is responsible for this layer now? That question — the shared-responsibility line — is the first architectural decision on any cloud project, and it moves depending on which kind of service you pick. This session teaches you to draw it deliberately.
What "cloud" means, precisely
The five essential characteristics
Think of a commercial kitchen you rent by the hour, not a kitchen you build. You source it yourself through an app at 2 a.m. with no phone call (on-demand self-service). You can get to it from anywhere on any device (broad network access). Other chefs use the same building and equipment, and neither of you knows or cares which oven you were given (resource pooling). Friday night you take six stations, Tuesday you take one (rapid elasticity). And the bill is metered to the minute and itemised (measured service).
If a service is missing any one of these, it isn't cloud — it's hosting with a nice website. That's a genuinely useful test when a vendor calls something "cloud".
Each characteristic is implemented by a specific piece of machinery, and knowing which one helps you predict how a cloud behaves under stress:
On-demand self-service ← the control plane
Every cloud is split in two. The control plane is the set of APIs that create, modify and destroy resources. The data plane is the resources themselves doing work. Self-service exists because the control plane is a public, authenticated API — the console, the CLI and Terraform are all just clients of it. This is also why control-plane outages are so nasty: your running workloads are fine, but you can't change anything.
Broad network access ← everything is an endpoint
Services are reachable over standard protocols at DNS names, not at cabled locations. The architectural consequence is that the network is the perimeter you configure, not the perimeter you inherit. On-prem, being inside the building meant something. In cloud, it means nothing until you build a VPC, subnets, and policy that make it mean something.
Resource pooling ← the hypervisor and the scheduler
A virtualisation layer slices physical machines into virtual ones, and a scheduler places your workload on whichever host has room. You do not know which host. This is what makes capacity cheap and it's also the source of the "noisy neighbour" problem, of instance-type availability failures, and of the entire market for dedicated / sole-tenant hardware when regulation forbids sharing.
Rapid elasticity ← autoscaling loops
A controller watches a signal (CPU, queue depth, requests-per-second, GPU utilisation), compares it to a target, and adds or removes instances. Elasticity is not infinite and it is not instant: there's a warm-up time, a cooldown, and a real quota ceiling. For GPU workloads the warm-up is brutal — pulling a multi-gigabyte image and loading model weights can dominate the scale-out latency.
Measured service ← metering that predates the invoice
Usage is metered per resource per unit time and surfaced through a billing API. Two consequences that matter more than they sound: (1) cost becomes an observable property of your architecture, so you can alert on it like latency; (2) idle resources still meter. A GPU VM you forgot about bills identically to one doing useful work.
- Elasticity has a floor and a ceiling. The floor is cold-start time; the ceiling is your quota, which starts near zero for scarce hardware. On every cloud, GPU quota is zero by default and must be requested. Plan for the request to take days, not minutes.
- Pooling means correlated failure. Your three "independent" instances can land on hardware that shares a power feed unless you explicitly spread them across fault domains. This is the entire reason zones exist.
- Measured service cuts both ways. Per-second billing is wonderful for bursty batch work and terrible for anything you forget to turn off. The classic beginner bill is not a runaway autoscaler — it's one idle GPU instance left running over a long weekend.
- Self-service without guardrails is a governance hole. The same API that lets a team ship in an afternoon lets them open a public bucket in an afternoon. This is why the hierarchy sessions (S2–S4) spend so much time on preventive policy.
Three deployment models — where the infrastructure sits
Public cloud is the rented commercial kitchen: the provider owns everything, you share it with strangers, you pay per use. Private cloud is your own kitchen built to the same self-service, metered, API-driven standard — the cloud operating model without the shared building. Hybrid is running both and treating them as one system, usually because some ingredient is legally not allowed to leave your premises.
A fourth term you'll hear constantly: multicloud means using more than one public cloud provider. It is not a deployment model in the NIST sense — it's a procurement and architecture strategy — but Brown's source is right that "the cloud" was always plural.
What actually differs is who bears the capital cost and who holds the keys:
| Model | Owns the hardware | Pays capex | Real reason to pick it | The cost of picking it |
|---|---|---|---|---|
| Public | Provider | Provider | Elasticity, breadth of managed services, zero hardware lead time | You cannot inspect the physical layer; you inherit the provider's risk profile |
| Private | You (or a dedicated host) | You | Regulation, data sovereignty, existing depreciated hardware, predictable steady-state load | You are now the capacity-planning team. Elasticity stops at what you bought. |
| Hybrid | Both | Both | Systems of record that genuinely cannot move, fronted by systems of engagement that must scale | Two operating models, two security models, and a network between them that is now load-bearing |
| Multicloud | Two+ providers | Providers | Negotiating leverage, regional coverage, capability gaps, acquisition reality | Every abstraction you build to stay portable costs you the best features of each cloud |
Brown's source has a genuinely good framing for hybrid that's worth stealing: an old mainframe or core-banking system of record (SoR) that can't be rewritten, fronted by a new cloud-hosted system of engagement (SoE) that handles the millions of concurrent web and mobile users and holds a small pool of connections back to the SoR. The cloud part scales; the legacy part doesn't have to.
The honest version of the multicloud debate: portability is a real cost you pay up-front for an option you may never exercise. If you abstract over three clouds' object storage, you get the intersection of S3, Blob Storage and Cloud Storage — which means no S3 Express One Zone, no Azure immutable-blob legal hold, no Cloud Storage Autoclass. The mature position is portable architecture, not portable code: keep your data formats open, keep your compute in containers, keep your IaC in a tool that speaks all three — and then use each cloud's best services without apology. Your own stack already does this well: a vLLM container is portable in the way that matters, even though the thing that schedules it is not.
For GPU work specifically, multicloud is often forced rather than chosen: capacity for a given accelerator is scarce and regional, so "which cloud" frequently reduces to "who has H200s in a region I'm allowed to use, this quarter".
Three service models — and the line that moves
Pizza, the canonical version, because it's canonical for a reason. IaaS is buying flour, yeast and an oven: maximum control, maximum work. PaaS is buying a par-baked base and adding toppings: the provider handles the hard, boring, repeatable part. SaaS is ordering delivery: you make zero decisions except what to order and who gets a slice.
The thing the pizza analogy hides, and the thing that actually matters: at every step you gave away control and gained back responsibility-someone-else-carries. Those are the same transaction viewed from two sides.
This is the visual to burn in. The stack below is the same for all three clouds. The dashed line is the shared-responsibility boundary. Click a service model to watch it move.
Two rules that never change, whichever model you pick: data and identity are always yours, and the layers immediately above the line are where incidents happen. A managed database patches itself — but you still chose its network exposure, its users and its encryption settings, and that's where the breach will come from. Industry analysis has been consistent for years that the overwhelming majority of cloud security failures are customer-side misconfiguration, not provider compromise.
| Dimension | IaaS | PaaS / CaaS | FaaS | SaaS |
|---|---|---|---|---|
| Ops burden | Highest — you own OS, patching, HA, scaling | Medium — you own config + app | Low — you own the function and its config | Near zero — you own users and data |
| Unit cost at steady load | Lowest per compute-hour | ~1.3–2× IaaS for equivalent capacity | Highest per compute-second, cheapest at low duty cycle | Per seat / per call — decoupled from compute |
| Cold start | Minutes (boot + config) | Seconds to a minute (image pull) | Milliseconds to seconds — but multi-minute for GPU + model weights | None |
| Blast radius of a bad config | One VM, unless it's the network | One service or namespace | One function | One tenant — but the provider's outage is everyone's |
| Lock-in gradient | Low — a VM is a VM | Medium — Kubernetes portable, managed PaaS less so | High — event contracts and runtime limits are vendor-shaped | Highest — your data model is theirs |
| GPU availability | Full accelerator catalogue | Good and improving (managed K8s, serverless GPU containers) | Narrow, and cold starts hurt badly | N/A — you're buying the model, not the metal |
The non-obvious one is the cold-start row for GPU FaaS. Scale-to-zero is the headline benefit of serverless, and it's the benefit that a 14 GB model checkpoint destroys: you can't amortise a 90-second weight load over a 200 ms request. This is precisely the problem platforms like Modal solve with snapshotting and warm pools, and it's why "just make it serverless" is bad advice for inference until you've measured the load profile.
Decision tree — IaaS, PaaS or SaaS for this workload?
Read top to bottom. Any "yes" exits right and you're done. If you fall all the way through, the bottom-left box is your default.
The same service models, three vocabularies
| Layer | AWS | Azure | Google Cloud |
|---|---|---|---|
| IaaS compute | Amazon EC2 Elastic Compute Cloud — raw VMs. | Azure Virtual Machines Sized by "SKU" strings like Standard_D2s_v5. | Compute Engine Machine families → series → types, e.g. n1-standard-4. |
| Managed Kubernetes (CaaS) | Amazon EKS Elastic Kubernetes Service. | Azure Kubernetes Service (AKS) | Google Kubernetes Engine (GKE) Autopilot mode removes node management entirely. |
| Serverless containers | AWS Fargate A capacity mode for ECS/EKS, not a standalone service. | Azure Container Apps | Cloud Run Can attach an L4 GPU and still scale to zero. |
| FaaS | AWS Lambda | Azure Functions | Cloud Run functions Renamed from "Cloud Functions" — same thing, folded into Cloud Run. |
| Managed relational DB (PaaS) | Amazon RDS / Aurora | Azure SQL Database / Azure Database for PostgreSQL | Cloud SQL / AlloyDB / Spanner |
| Managed ML platform | Amazon SageMaker AI | Azure Machine Learning / Azure AI Foundry | Vertex AI |
| Foundation-model API | Amazon Bedrock | Azure OpenAI in Foundry Models | Vertex AI Model Garden + Gemini API |
| Responsibility doctrine | "Security of the cloud vs security in the cloud" Cleanest slogan; least granular published matrix. | Responsibility mapped by service layer Explicit "always yours" set: data, identities, devices, accounts. | Shared responsibility plus shared fate Google publishes per-service matrices and argues the provider should actively help you land it, not just draw a line. |
| Well-Architected doctrine | 6 pillars + lens catalogue Operational Excellence, Security, Reliability, Performance Efficiency, Cost Optimization, Sustainability. | 5 pillars Reliability, Security, Cost Optimization, Operational Excellence, Performance Efficiency. No sustainability pillar. | 6 pillars + perspectives Same five plus Sustainability, promoted to a full pillar in Jan 2026. |
What "well-architected" actually means
A well-architected framework is a checklist of the questions a senior architect would ask you in a design review — written down so you can ask them of yourself before the review. Nothing more mystical than that. All three vendors publish one, all three converge on roughly the same five questions, and the differences between them are smaller than the similarities.
The five shared pillars, in vendor-neutral phrasing:
Does it keep working when a component, a zone, or a region fails? What's the recovery time and recovery point?
Who can reach it, with what identity, and what happens when a credential leaks? Is data encrypted at rest and in transit?
Are you paying for capacity you use? Is cost attributable to a team and visible before the invoice?
Can you deploy safely, observe what's happening, and roll back? Is the runbook real?
Are you using the right resource shape, and does it stay right as load changes?
What's the energy, carbon and water cost of this design? Increasingly a procurement question, not just an ethical one.
On top of the pillars, vendors publish lenses (AWS) or perspectives (Google): the same pillars re-asked for a specific domain. Directly relevant to you: AWS shipped a Generative AI Lens in April 2025 and added a Responsible AI Lens plus updated ML and Generative AI lenses at re:Invent 2025; Google's WAF carries an AI & ML perspective; Microsoft publishes AI workload guidance under its five pillars.
AWS Generative AI Lens Three AI lenses, re:Invent 2025 Azure WAF: AI workloads Google Cloud WAF
The pillars conflict on purpose. Reliability wants three zones; cost optimisation wants one. Security wants a private endpoint and a bastion; operational excellence wants a developer to debug at 3 a.m. without a VPN ticket. A well-architected review isn't a scorecard where you maximise all six — it's a forcing function to make the trade-off explicit and recorded. The output of a good review is not "we scored 92%", it's "we accepted a 4-hour RTO for the reporting service to save $3.1k/month, signed off by the product owner on this date."
That's also the honest answer to why Azure has five pillars and the others six. Microsoft's position is that sustainability is a cross-cutting concern rather than a peer of reliability. Google took the opposite view in January 2026 and promoted it. Neither is wrong; they're editorial choices about a checklist.
One workload, four service models, on paper
The requirement. An internal document-QA service for a 400-person company. Employees ask questions against an internal corpus. Peak is 30 concurrent users for about three hours a day; overnight it's zero. Latency target: first token in under 2 seconds. The corpus is confidential but not regulated. You have one engineer, part-time, to run it.
Let's cost four honest options. Numbers are illustrative order-of-magnitude figures for reasoning practice, not quotes — GPU pricing moves weekly and varies by region and commitment. The shape of the answer is what transfers.
| 1 × mid-tier inference GPU VM, on-demand | ~$0.80/hr × 730 hr | $584/mo |
| Block storage, 200 GB for weights + OS | ~$0.10/GB-mo | $20/mo |
| Engineer time: OS patching, driver pinning, vLLM upgrades, on-call | ~6 hr/mo | 6 hr |
| Utilisation: 3 hr/day busy ÷ 24 hr | 12.5% — you pay for 87.5% idle | |
| Same GPU VM, running 10 hr/day on weekdays | ~$0.80/hr × 220 hr | $176/mo |
| Storage still billed while stopped | 200 GB | $20/mo |
| Engineer time: as above, plus scheduling automation to build and maintain | ~7 hr/mo | 7 hr |
| GPU node-hours, scaled to actual demand ~4 hr/day | ~$0.80/hr × 90 hr | $72/mo |
| Control-plane fee (varies by provider and mode) | ~$0.10/hr | $73/mo |
| Small always-on CPU node for the gateway | — | $25/mo |
| Engineer time: cluster upgrades, GPU operator, manifests | ~8 hr/mo | 8 hr |
| Cold start when scaling from zero: image pull + weight load | ~2–4 min — breaks the 2 s target on first request | |
| 30 users × 3 hr/day × 20 days, ~15 queries/user-hr | 27,000 queries/mo | — |
| ~4k tokens in + 700 out per query, mid-tier model pricing | ~$0.012/query | $324/mo |
| Vector store + retrieval (managed) | — | $40/mo |
| Engineer time: application code only | ~2 hr/mo | 2 hr |
Option B wins on money, Option D wins on the engineer. At $196 vs $364 the gap is $168/month — about two hours of a senior engineer's fully-loaded cost. Option B spends 7 hours a month to save that $168. Option B is losing money.
This is the calculation nobody does, and it's the whole reason PaaS exists. The IaaS bill is visible in the cloud console; the ops bill is invisible because it's already in payroll. An architect's job is to put both on the same page.
The answer flips at scale. At 40× this volume, Option D costs ~$14.5k/month while Option C's GPU hours grow sublinearly through batching — vLLM's continuous batching means one busy GPU serves far more than 40× one idle GPU's throughput. Where the crossover sits is the single most useful number to compute for any inference workload, and it is workload-specific.
Three grounded examples worth reading yourself
1 · The AWS Generative AI Lens — a shared-responsibility model for models
AWS published a Generative AI Lens for the Well-Architected Framework in April 2025 and updated it at re:Invent 2025 alongside a new Responsible AI Lens. The genuinely useful idea in it for this session: it extends shared responsibility into a three-party split for AI — model producer, model provider, and model consumer — because with a hosted foundation model, "the provider" is now two different organisations with different obligations.
That's a real conceptual upgrade over the classic two-party diagram, and it's the frame to use when someone asks who's accountable for a hallucination in production. AWS also states the lens is deliberately cloud-agnostic, which makes it usable as a neutral checklist even if you deploy elsewhere.
2 · Google's "shared fate" — the argument that a line is not enough
Google's position is that the shared-responsibility model, on its own, quietly offloads an unreasonable amount onto the customer: to hold up your side you need deep knowledge of every service you use, every configuration option it exposes, and what the provider already does for you. Their answer, branded shared fate, is to ship secure-by-default configurations, opinionated blueprints, and risk-transfer mechanisms rather than only publishing a matrix.
Take it as more than branding — it predicts real product behaviour. It's why Google publishes per-service responsibility matrices at a finer grain than the others, and why GCP defaults tend to be more locked-down out of the box. It's also a useful argument to have in your head when comparing vendors: how much of my side of the line does this vendor actively help me carry?
3 · The 2025 free-tier reset — a live example of documentation rot
On 15 July 2025, AWS replaced its long-standing "12 months free" tier with a credit model for new accounts: choose a Free plan or Paid plan at signup, get $100 in credits immediately, earn up to $100 more by completing five onboarding activities ($20 each — launch and terminate an EC2 instance, configure an RDS database, deploy a Lambda function, test a prompt in Bedrock, set up a budget). The Free plan closes after six months or when credits run out, whichever comes first; credits expire 12 months from account opening. Over 30 always-free services remain.
Two traps worth knowing before you touch the console. First: on the Free plan the account auto-closes when credits are exhausted, with a grace period to retrieve data. Second, and directly relevant to a multi-account curriculum: reporting indicates credits are forfeited if the account joins an AWS Organization — so building a practice Organization can silently burn your learning budget. Verify this against the current terms before you try it.
Your context, and one lab
Where you already live on this diagram
You've been operating at three different points on the shared-responsibility line without necessarily labelling them. Naming them is the exercise:
| What you deployed | Service model | What you owned vs what was handed to you |
|---|---|---|
| Gemma on vLLM, on Modal | PaaS / FaaS-shaped | You owned the container image, the vLLM config and the model choice. Modal owned the host, the GPU driver stack, the scheduler, the autoscaler, and — critically — the cold-start problem. Note how far up the line that is: you never once thought about a kernel version. |
| Vertex AI deployment script — T4s, autoscale 1–3, spot | PaaS (managed ML platform) | You owned the model artifact, the machine-type choice, the scaling bounds and the spot decision. Google owned serving infrastructure, health checks and the endpoint. Your min_replica_count=1 is a shared-responsibility decision in disguise: you bought away cold starts by paying for one always-warm GPU. |
| vLLM tutorial stack on a GCP L4 VM | IaaS | You owned everything above the hypervisor: OS, NVIDIA driver, CUDA, Python env, vLLM, the process manager. That's the bottom of the line, and it's why that one took the longest to get working. |
| KServe / Kubernetes concepts | CaaS | The middle rung. Cluster and control plane are managed; you own manifests, the GPU operator, resource requests, and the scheduling behaviour that determines whether your pod ever gets a GPU. |
Three ways the service-model choice hits differently for inference than for a web app:
- Cold start dominates. A stateless API cold-starts in 200 ms. A 14 GB model cold-starts in minutes. This single fact invalidates the standard "serverless is cheaper at low duty cycle" reasoning and is why warm pools, weight caching and snapshot-restore are the actual competitive surface in GPU PaaS.
- The driver stack is a lock-in vector at IaaS. Pinning a CUDA/driver/vLLM combination is the kind of work that quietly ties you to one image family. Containerising it is the cheapest portability insurance you can buy, and you already do this.
- Quota is the real capacity limit, not money. On every cloud, GPU quota starts at zero. The service model doesn't change that — managed platforms consume the same underlying quota pool. Request it before you need it.
Lab — draw the line, then verify it against reality
No provisioning in this one; the point is calibration. Budget: 45 minutes, $0.
- Take your Vertex AI deployment script. On paper, list every layer from physical hardware up to "the answer the user reads". About 12 layers.
- Mark each layer P (provider), Y (you), or S (shared). Do this from memory first — that's the test.
- Now open Google's shared-responsibility matrix for Vertex AI and check yourself. Note specifically which layers you marked P that are actually S. That gap is your risk surface, and it's the same gap in every architecture review you'll ever sit in.
- Repeat for the Modal deployment. The line will be higher. Ask yourself what you gave up to get it there, and whether you'd make the same trade for a workload with a compliance requirement.
Every later session has a hands-on step that provisions real, billable resources. Do these three things first, on whichever cloud you start with:
- Use free tier / smallest SKU. Never a GPU instance for a hierarchy lab — a burstable micro/B1s/e2-micro is enough to prove a concept, and it's a rounding error.
- Set a budget alert before you create anything. $5 threshold, email notification. On AWS this is AWS Budgets (and it's one of the five activities that earns free-tier credit); on Azure it's Cost Management budgets, settable at subscription creation; on Google it's a budget with alert rules on the billing account. A budget alert is the cheapest insurance in cloud.
- Write the teardown command before you write the create command. Literally paste it in a scratch file first. Idle resources are silent money leaks — a forgotten GPU VM bills identically to a busy one, and the bill arrives 30 days later when you've forgotten it exists.
You now have the skeleton and a movable responsibility line. Next we hang the first vocabulary on it: AWS, whose whole architectural personality comes from treating the account as a hard wall you're expected to create dozens of.
Carry this question into S2: if an account is cheap and disposable, what should get its own one — and what shouldn't?
Session 2 · The amber lane. Global fabric, and the account as a wall.
Three unrelated-looking questions with one answer
A regulator asks where customer data physically resides. A user in Singapore complains the app is slow. A junior engineer runs a script that deletes production. These look like a compliance problem, a performance problem and a governance problem. They're the same problem stated three ways: you did not decide, deliberately, which container this thing lives in.
AWS gives you two orthogonal containment systems. Geography — region, then Availability Zone — answers "where does this physically run, and what fails with it". Hierarchy — organization, OU, account — answers "who can touch it, who pays for it, and how far does a mistake spread". Every AWS architecture decision above the service level is a choice on one of these two axes.
The material covers the first axis thoroughly and the second not at all — accounts and Organizations don't appear until §3 (IAM). I'm teaching both here, because blast radius is unintelligible without the account model, and I've marked which parts come from AWS docs rather than the material.
Axis 1 — the global fabric
us-east-1 (N. Virginia) or eu-west-1 (Ireland).us-east-1a.A region is a city. An AZ is a building in that city, far enough from the next building that the same flood or substation failure won't take both, close enough that you can walk between them in the time it takes to say a sentence. An edge location is a parcel locker in a neighbourhood somewhere else entirely: it doesn't manufacture anything, it just holds copies so people nearby get them fast.
Deploying into one AZ is renting one building. Deploying across three is renting in three buildings and accepting that one may burn down. Deploying into two regions is opening in two cities, which is a different and much larger commitment.
Click any element to see what it means for a design decision.
- AZ letters are per-account aliases. Your
us-east-1aand myus-east-1aare probably different physical zones — AWS randomises the mapping so customers don't all pile into "a". If you need to coordinate placement across accounts (shared VPC subnets, cross-account clusters), use the stable AZ ID (use1-az4), not the name. This catches people constantly. - Not every service exists in every region. AWS publishes a list of core services present at every
region launch, with a second tier that typically arrives within 12 months. New and specialised services —
including much of the AI portfolio — land in
us-east-1first and diffuse outward. "Is it in my region?" is a real design constraint, not a footnote. - Cross-AZ traffic is billed, in both directions. Roughly $0.01/GB each way. A chatty microservice mesh spread across three AZs for resilience can generate a surprising data-transfer line item. This is a genuine reliability-vs-cost pillar conflict, and the right answer is workload-specific.
- Multi-AZ ≠ multi-region. Multi-AZ buys you high availability within one region and is often nearly free architecturally. Multi-region buys you disaster recovery and regional-outage survival, and costs you data replication, config drift, a global traffic policy, and roughly double the operational surface. The material's caution list flags this exact confusion, and it's a favourite exam trap.
- Latency is physics plus routing. Distance sets the floor; congestion, hop count and endpoint processing add the rest. Measure before you assume — CloudPing-style tools and CloudWatch/X-Ray traces are how you find out, rather than reasoning from a map.
- Compliance is regional, and specialised. GovCloud regions are a separate partition, FedRAMP- authorised and isolated from commercial regions, and the European Sovereign Cloud opened on its own partition in January 2026. HIPAA-eligible services and BAAs, GDPR data-residency, ISO and SOC coverage all vary by region. Choose the region against the regulation first, then optimise latency inside what's left.
Axis 2 — the account model
Not in the material This material starts in §3 (IAM), which covers cross-account roles, Identity Center and Organizations. Sourced from AWS documentation here.
Other clouds treat their top-level container as something you create rarely and carefully. AWS treats accounts like disposable rooms with concrete walls. Making a new one is free and takes minutes. The expected pattern in a serious AWS estate is dozens or hundreds of them: one per workload per environment, plus dedicated accounts for logging, security tooling, shared networking and sandbox.
Why so many walls? Because AWS's isolation between accounts is far stronger than its isolation inside one. Inside an account, separation depends on IAM policies being written correctly. Between accounts, separation is the default and access is the exception. Given a choice between "trust that every policy is right" and "make the mistake impossible", the second is the better bet.
The policy types, precisely
This is the part that changed most recently, and the part the material predates.
Principal-centric. Sets the ceiling on what IAM users and roles in member accounts may do — including the account root user. Classic use: "no principal in this OU may operate outside eu-west-1", or "nobody may disable CloudTrail".
Since September 2025 SCPs support the full IAM policy language, including conditions in Allow statements and specific resource ARNs in Deny statements. Older guidance that says "wildcards only in denies" is out of date.
Resource-centric. Sets the ceiling on who may access your resources, regardless of what the resource's own policy says. The canonical use: "no principal outside my organization can read any S3 bucket in it" — enforced even if someone writes a permissive bucket policy.
Launched November 2024. Supports a defined service list including S3, STS, KMS, SQS and Secrets Manager. Requires all-features mode in Organizations.
Configuration-centric. Pins a service's configuration to a desired state organization-wide, and can return a custom error message pointing the user at your internal docs.
Newest of the three and narrowest in scope at launch. Neither SCPs nor RCPs apply to service-linked roles — a real gap worth knowing.
AWS Organizations — authorization policies AWS Cloud Operations Blog — enterprise-wide preventive controls
Global vs regional vs zonal — a service-scope cheat sheet
Getting this wrong is how people accidentally build a single point of failure inside an otherwise multi-AZ design.
| Scope | Examples | What it means for your design |
|---|---|---|
| Global | IAM, Route 53, CloudFront, WAF (for CloudFront), Organizations | One namespace for the whole account across all regions. An IAM role you create is visible everywhere. Also means a global-service problem is a global problem. |
| Regional | S3 buckets, DynamoDB tables, VPCs, Lambda functions, SQS queues | Lives in one region, usually replicated across that region's AZs by the service itself. The service survives losing an AZ without you doing anything. |
| Zonal | EC2 instances, EBS volumes, RDS single-AZ instances, subnets | Pinned to one AZ. You are responsible for spreading these. An EBS volume cannot attach to an instance in a different AZ — a constraint that shapes a lot of designs. |
The material is exam scaffolding, and it's accurate: the AWS Certified Solutions Architect – Professional exam (code SAP-C02) is 75 questions in 180 minutes, $300, scored 100–1000 with a 750 pass mark, compensatory scoring across four domains — Design Solutions for Organizational Complexity (26%), Design for New Solutions (29%), Continuous Improvement for Existing Solutions (25%), Accelerate Workload Migration and Modernization (20%). Verified current as of 2026.
The detail worth extracting: Domain 1 is a quarter of the exam and it is entirely about the hierarchy axis. Multi-account strategy, cross-account access, network topology across accounts, centralised logging, policy inheritance. AWS's own view of what separates a professional-level architect from an associate-level one is precisely the material the material defers to §3 — which is why we're covering it here in session 2 rather than waiting.
Decision tree — which boundary should own this?
A new workload arrives. Where does it go? Read down; any "yes" exits right.
Global fabric and hierarchy, three ways
| Concept | AWS | Azure | Google Cloud |
|---|---|---|---|
| Count (Jul 2026) | 39 regions / 123 AZsMinimum 3 AZs in every region, no exceptions. | 70+ regionsOnly ~35 advertise AZ support; the rest are single-zone. | 43 regions / 130 zones3+ zones per region, plus AI zones on top. |
| Fault domain name | Availability ZoneLetter-suffixed, per-account alias. Use AZ IDs to coordinate. | Availability zoneNumber-suffixed, per-subscription alias. Target <2 ms between zones. | ZoneLetter-suffixed. AI zones use ai1a-style suffixes. |
| Residency wrapper | Partition (aws, aws-us-gov, aws-cn)Separate ARNs, separate IAM, separate consoles. | GeographyAn explicit named layer above region — the clearest of the three. | Multi-region / locationMostly a storage concept; residency enforced via Org Policy constraints. |
| Cheap disposable boundary | AccountFree to create, hard wall, expect hundreds. | SubscriptionHeavier — tied to a billing account. Resource groups are the cheap unit instead. | ProjectFree, hard wall, expect hundreds. Closest analogue to an AWS account. |
| Grouping layer | OU — 5 levelsUnder a single root. | Management group — 6 levels10,000 per directory. | Folder — 10 levels300 direct children per parent. |
| Preventive guardrail | SCP (principals) + RCP (resources) + declarativeThree distinct systems; only AWS splits principal and resource this way. | Azure PolicyOne system, but can also modify resources, not just deny. | Organization Policy constraintsSeparate from IAM entirely. Boolean and list constraints. |
| Landing-zone product | AWS Control Tower (+ Landing Zone Accelerator, AFT)A managed service that builds and governs the whole structure. | Azure Landing Zones under the Cloud Adoption FrameworkReference architecture plus IaC — no single managed service. | Cloud Foundation Toolkit / blueprintsTerraform-first, least prescriptive of the three. |
| Multi-account SSO | IAM Identity CenterPermission sets projected into many accounts. | Entra ID is already the tenant-wide identityNo equivalent extra layer needed — identity is unified by design. | Cloud Identity + IAM at hierarchy nodesInheritance does the work Identity Center does on AWS. |
Counts verified July 2026: AWS Azure Google Cloud. These change monthly — re-check before quoting.
Where the GPUs actually are
EC2's accelerated families, from "you can probably get one today" to "call your account team":
| Family | Silicon | What it's for, and how you get capacity |
|---|---|---|
| G-series | NVIDIA L4, L40S, and similar | Inference and graphics. Broadly available on-demand, and the realistic starting point for a vLLM endpoint. Closest AWS analogue to the L4 work you've already done on GCP. |
| P4 / P5 | A100, H100, H200 | Training and large-model inference. Available on-demand in a subset of regions, plus EC2 Capacity Blocks for ML — you reserve a block of GPU-days in advance, like booking a hotel. |
| P6 | Blackwell B200 / B300 | Current-generation training. Predominantly Capacity Blocks; reserved pricing has moved more than once in 2026. |
| P6e UltraServers | GB200 NVL72 / GB300 NVL72 | Rack-scale. A P6e-GB200 UltraServer exposes up to 72 Blackwell GPUs in one NVLink domain — 360 petaflops FP8 and 13.4 TB of HBM3e. GB300 adds 1.5× memory and 1.5× FP4 compute. Contact your account team; this is not a console click. |
| Inferentia / Trainium | AWS custom silicon | The lock-in-flavoured option: real price-performance gains, but you compile through AWS Neuron rather than running stock CUDA. Weigh against your open-source-first preference. |
P6e-GB300 GA announcement, Dec 2025 AWS PCS adds UltraServer support, Jun 2026
The placement rule that matters. GPU capacity is not evenly spread. A given accelerator exists in a handful of regions and often only some AZs within them, which means your region choice for a training run is frequently made for you by capacity — and then your data-residency and latency requirements have to fit around it, rather than the other way round. For tightly-coupled multi-node training you also need the instances physically close, which is what EC2 UltraClusters and cluster placement groups exist to guarantee.
Counting blast radius, on paper
The scenario. A GenAI platform team runs four things: a production inference endpoint, a dev/staging copy of it, a fine-tuning pipeline that periodically grabs a lot of GPU, and a data-labelling web app used by contractors. Same team, same budget. The question is how many accounts.
| Failure | What it reaches |
|---|---|
| An over-broad IAM policy on the labelling app's role | All 4 workloads. One policy mistake is total. |
| Fine-tuning job requests 64 GPU vCPUs | Consumes the shared per-account-per-region quota. Production autoscaling now fails to get capacity. |
| A leaked long-lived access key | Everything the key's policy allows — and in one account, policies are usually broader than anyone intended. |
| Runaway spend | Visible only via tags. Untagged resources are unattributable, and there will be untagged resources. |
| Contractor needs console access to the labelling app | You're now writing a deny-by-default IAM policy that has to be right about every service in the account. Forever. |
| Same failure | What it reaches now |
|---|---|
| Over-broad IAM policy on the labelling app's role | 1 of 4. The wall holds by default. |
| Fine-tuning job requests 64 GPU vCPUs | 1 of 4. Quota is per-account — production's pool is untouched. |
| Leaked access key | 1 of 4, and an RCP saying "no principal outside this organization may read our S3" limits the exfiltration path even then. |
| Runaway spend | Attributed automatically — the account is the cost centre. No tagging discipline required. |
| Contractor console access | A permission set in Identity Center scoped to one account. The other three are simply not reachable. |
Design 2 costs roughly a day of setup and adds cross-account plumbing: a shared VPC or Transit Gateway if the workloads talk, a central log-archive account, an Identity Center configuration. Call it 8–12 hours once plus an hour a month.
It buys a 4× reduction in blast radius on every failure mode simultaneously, and it converts cost attribution from a tagging-discipline problem (which decays) into a structural property (which doesn't). There is no realistic estate size where Design 1 wins once you have more than one environment. This is why AWS's own multi-account guidance is unusually blunt about it.
The nuance: don't create accounts for things that share a lifecycle and a team and a budget. Three microservices deployed together by one team in one pipeline are one workload, and one account. The unit is the workload, not the service.
The AZ-name trap, quantified
Two accounts in your organization each deploy into "us-east-1a" believing they've co-located for low latency and zero cross-AZ transfer cost. AWS maps AZ names to physical zones independently per account:
Account A: us-east-1a | → physical zone use1-az4 |
Account B: us-east-1a | → physical zone use1-az1 |
| Assumed: same building, free traffic | Reality: different buildings, cross-AZ charges in both directions, extra latency |
use1-az4), which is stable across accounts. Check with aws ec2 describe-availability-zones, which returns both the name and the ID.Two grounded examples
1 · AWS's own landing-zone guidance — and the service that ended the DIY era
AWS published a "Landing Zone" solution years ago, then stopped active development on it and replaced it with AWS Control Tower as a managed service. Their prescriptive guidance is now explicit: transition off the old solution, because the complexity of managing and customising it grew faster than the value. That's a useful piece of vendor honesty to note — AWS deprecating its own reference implementation in favour of a service.
Practically: Control Tower sets up the multi-account structure, the OUs, the log-archive and audit accounts, and a set of preventive and detective controls. Landing Zone Accelerator extends it for heavier compliance requirements and works in regions where Control Tower isn't available (falling back to Organizations directly), and Account Factory for Terraform (AFT) handles account vending as code. You don't need any of this for learning, but you need to recognise the names in a design review.
AWS Prescriptive Guidance — transitioning from AWS Landing Zone to Control Tower
2 · Cross-cloud reality check — when copying a hierarchy design fails
A documented multi-cloud consulting pattern worth internalising: a manufacturer running primarily on Azure acquired an analytics product on AWS, and tried to replicate their Azure Cloud Adoption Framework enterprise-scale design by mapping management groups one-to-one onto AWS OUs. Six months later the cross-account IAM model was tangled, SCPs kept fighting the prescriptive structure, and engineering time was going into retrofitting things AWS does naturally with a looser hierarchy and tighter account walls. Re
The lesson is exactly this stage's thesis, inverted: the skeleton translates, the proportions don't. Azure's design pushes governance up into the management-group tree because subscriptions are relatively heavyweight. AWS pushes it down into account walls because accounts are free. Translate the concept, then re-derive the design from the target cloud's economics.
Reported at bluent.com — AWS vs Azure vs GCP landing zone security (vendor blog; treat the case study as illustrative, the architectural point as sound)
Your context, and one lab
Translating your existing work into AWS
| What you've done elsewhere | The AWS shape of it, and what changes |
|---|---|
| Vertex AI endpoint, T4, autoscale 1–3, spot | Closest analogue is a SageMaker AI real-time endpoint with an instance count range, or a G-series EC2 Auto Scaling group behind an ALB if you want to keep vLLM. AWS's equivalent of spot is EC2 Spot Instances — interruptible, up to ~90% off, 2-minute warning. For inference this is workable with fast checkpointing and a warm on-demand baseline; for a single-replica endpoint it isn't. |
| vLLM container on Modal | The AWS shapes are ECS on Fargate (no GPU on Fargate — a real limitation), EKS with a GPU node group, or SageMaker. None of them scale-to-zero for GPU the way Modal does. That gap is the actual product Modal sells, and it's worth naming rather than assuming AWS has a drop-in. |
| KServe / Kubernetes concepts | Transfers almost unchanged to EKS. Differences are peripheral: IAM Roles for Service Accounts (IRSA) instead of Workload Identity, the AWS Load Balancer Controller, and Karpenter as the node autoscaler of choice. Your manifests largely survive; the identity plumbing doesn't. |
| Gemma weights and open models | Amazon Bedrock is the managed-API route and includes several open-weight families; self-hosting on EC2/EKS keeps you fully open-source. Bedrock is the higher line on the shared-responsibility diagram from S1 — convenient, and a different data-handling conversation. |
AWS's capacity model for accelerators is more explicit than the others. On-demand GPU is best-effort and frequently unavailable in the shape you want. The real mechanisms are Capacity Blocks for ML (reserve GPU-days in advance for a fixed window), Capacity Reservations, and Savings Plans. If you're planning a fine-tuning run, the capacity question comes before the region question, and the region question comes before everything else.
Second thing: GPU vCPU quota is a per-account, per-region limit that starts at zero for most families. This is the strongest practical argument for the multi-account design in the reality check above — your fine-tuning experiments literally cannot starve production if they're behind a different wall.
Lab — read your own hierarchy, spend nothing
Budget: 30 minutes, $0.00. This lab is deliberately read-only: it provisions nothing, so there is nothing to leak money. Prerequisite: an AWS account with the CLI configured.
If this is a brand-new account: choose the Free plan at signup for $100 in credits (up to $200 by completing five onboarding activities — one of which is creating a budget, so do that first and get paid for it). Note the two traps from S1: the Free plan auto-closes after six months or when credits run out, and reporting suggests joining an AWS Organization forfeits remaining credits — so don't build a practice Organization on the account holding your learning budget. Check the current terms before you do anything organizational.
- Set the budget first. Console → Billing and Cost Management → Budgets → Create budget → Monthly cost, $5, alert at 80% and 100% to your email. Do this before step 2, always.
- Find your real AZ mapping.
Compareaws ec2 describe-availability-zones --region us-east-1 \ --query 'AvailabilityZones[].[ZoneName,ZoneId,ZoneType]' --output tableZoneNametoZoneId. That difference is the trap from the reality check, made concrete on your own account. - Ask whether you're in an organization.
aws organizations describe-organization # AWSOrganizationsNotInUseException means you're a standalone account — that's fine and expected - Check which services exist where. Pick a GPU instance type and ask which AZs offer it:
Then run the same command againstaws ec2 describe-instance-type-offerings --location-type availability-zone \ --filters Name=instance-type,Values=g6.xlarge --region us-east-1 --output tableeu-west-2orap-southeast-1. The difference in output is the "capacity decides your region" lesson, in your own console. - Confirm your GPU quota is zero. Service Quotas → EC2 → search "G and VT instances". Note the current value. If you ever want to run one, that request goes in days ahead.
Nothing was created, so nothing needs deleting — that's the design of this
lab. Two housekeeping items anyway: (1) leave the $5 budget in place permanently, it costs nothing and
it's your smoke alarm. (2) If you experimented beyond the steps above, run
aws ec2 describe-instances --query 'Reservations[].Instances[?State.Name==`running`].[InstanceId,InstanceType]' --output table
in every region you touched, and terminate anything you don't recognise. Region-by-region is the only way —
there is no global "show me everything running" view, and forgotten instances in an unfamiliar region are the
classic surprise-bill story.
AWS puts one hard wall between workloads and expects you to build many of them. Azure takes a different bet: fewer, heavier boundaries, and an extra layer on top that AWS has no equivalent for.
Carry this into S3: if Azure's subscription is the quota and billing unit, what job does the resource group underneath it do — and why does AWS need no such thing?
Session 3 · The blue lane. Five layers, one control plane, two governance systems.
Azure has one more layer than the others, and it isn't decoration
AWS: organization → OU → account → resource. Google: organization → folder → project → resource. Azure: tenant → management group → subscription → resource group → resource. That extra rung is the thing people trip over when they arrive from another cloud, and it exists for a reason worth understanding.
The reason is economic. On AWS and GCP, the isolation boundary — the account, the project — is free and disposable, so you make hundreds and each one holds a small thing. An Azure subscription is heavier: it's tied to a billing arrangement, it carries quota, and organisations tend to have tens rather than hundreds. So Azure needs a cheap grouping layer inside the boundary, and that's the resource group.
The second thing that makes Azure distinct: everything goes through one control plane. Azure Resource Manager sits in front of every service. The portal is an ARM client. The CLI is an ARM client. Terraform is an ARM client. Once you internalise that, a lot of Azure's behaviour — the consistency of the tooling, the way deployments are objects you can inspect, why Bicep exists — stops being trivia and becomes predictable.
The five-layer hierarchy
something.onmicrosoft.com. The material puts
this well: organisation is the business term, tenant is the technical term.A corporate campus. The tenant is the company itself — the entity that issues ID badges. The management groups are divisions, nested as deeply as your org chart deserves. A subscription is a building with its own utility meter and its own capacity limits. A resource group is a floor of that building, rented to one project, where everything on the floor gets renovated and vacated together. The resources are the furniture.
The badge system (Entra ID) is campus-wide. The meters (subscriptions) are per building. The lease terms (RBAC and Policy) can be set at any level and flow downward.
Click any layer to see what it actually controls — and, importantly, what it doesn't.
Two governance systems, not one
This is the Azure concept that most often gets muddled, and the distinction is clean once you see it:
Role-based access control. Assigns a role (a set of allowed operations) to a principal (user, group, service principal, managed identity) at a scope (management group, subscription, resource group, or single resource). Inherits downward.
Answers: "may Priya restart this VM?" Built-in roles: Owner, Contributor, Reader, plus hundreds of service-specific ones.
Rules about resource configuration, evaluated by ARM on every write and audited
continuously. Effects include deny, audit, append,
modify and deployIfNotExists.
Answers: "may anyone create a VM without disk encryption, in a region we
don't allow?" The modify and deployIfNotExists effects are genuinely distinctive
— Azure Policy can fix resources, which AWS SCPs and GCP Org Policies cannot.
Both attach at any level of the hierarchy and inherit down. An Owner role assignment at a management group makes you Owner of every subscription beneath it — which is why Microsoft's guidance is unusually stern about the root management group: nobody has access by default, only Entra Global Admins can elevate themselves into it, and assignments there should be strictly "must have".
Bicep — the readable face of ARM
Here the configuration is the mechanism, so a short snippet earns its place. This is the shape of every Bicep resource declaration:
resource stg 'Microsoft.Storage/storageAccounts@2023-05-01' = {
name: uniqueStorageName // the real name in Azure
location: location
sku: { name: storageSKU }
kind: 'StorageV2'
properties: { supportsHttpsTrafficOnly: true }
}
Two things to read off it. (1) stg is a symbolic name used
only inside the template; name: is the actual resource name in Azure. The material flags this
confusion explicitly and it's worth heeding. (2) The type string
Microsoft.Storage/storageAccounts@2023-05-01 is provider/type@API-version — pinning the API
version is what makes the template reproducible over time.
- The resource group's location is metadata only. Genuinely counter-intuitive. You pick a region when creating an RG, and that region stores the group's metadata — not its contents. Resources inside can be anywhere. Practical consequence: if that metadata region has a regional outage you may be unable to manage resources that are themselves running perfectly elsewhere. Keeping the RG in the same region as its resources is the usual advice, when compliance allows.
- 980 resource groups per subscription. Sounds enormous until you're vending one RG per microservice per environment via a pipeline. Worth knowing before you design the automation.
- Management groups: 6 levels deep, 10,000 per directory, one parent each. The CAF reference architecture uses about three levels, and going deeper than four is usually a sign the tree is modelling the org chart rather than the governance requirements.
- Quotas are per-subscription and per-region. A GPU core quota granted in West Europe does nothing for you in Sweden Central. Every region you expand into needs its own quota request. This is the single most common Azure surprise for ML teams.
- Not every Azure region has availability zones. Around 35 of the 70+ regions advertise AZ support. A region without zones can still be paired with another for geo-redundancy, but you cannot build zone-redundant HA there. Check before you promise an SLA.
- Paired regions are not universal any more. Azure historically paired every region for geo-replication and staged updates. Newer regions may be non-paired, relying on availability zones plus your own cross-region design instead. Don't assume a pair exists — look it up.
- Moving resources between subscriptions or resource groups is possible but uneven. Some resource types move cleanly, some can't move at all, and some move but break their dependencies. Design the placement correctly the first time; treat moves as a migration project, not an afternoon.
Limits verified July 2026: management group limits Azure regions and zones
Decision tree — new tenant, new subscription, or new resource group?
Something new needs a home in Azure. Read down; any "yes" exits right.
owner, env,
costcenter) and move on — Azure's cost tooling relies on tags in a way AWS accounts and GCP
projects don't, because your boundaries are coarser here.Hierarchy, identity and IaC, three ways
| Concept | Azure | AWS | Google Cloud |
|---|---|---|---|
| Layers, root → resource | 5: tenant → mgmt group → subscription → resource group → resourceThe only one with a cheap grouping layer below the boundary. | 4: organization → OU → account → resourceNo resource group; tags and IAM do that job. | 4: organization → folder → project → resourceNo resource group; the project is small enough to be one. |
| Identity service | Microsoft Entra IDFormerly Azure AD. Tenant-wide, and also your Microsoft 365 identity. | IAM + IAM Identity CenterIAM is per-account; Identity Center federates across them. | Cloud Identity / Workspace + Cloud IAMThe org resource is derived from your Cloud Identity domain. |
| Authorization model | RBAC (roles at scopes) + Azure Policy (config rules)Two separate systems that both inherit down the tree. | IAM policies + SCPs/RCPsSame language for both; SCPs cap rather than grant. | IAM allow/deny policies + Org Policy constraintsDeny policies are newer; constraints are a separate vocabulary. |
| Can policy fix a resource? | Yes — modify and deployIfNotExistsAzure's genuine differentiator in governance. | No — SCPs and RCPs only denyRemediation is a separate service (Config rules + SSM). | No — constraints only restrictRemediation via separate automation. |
| Universal control plane? | Yes — ARM fronts everythingUniform tooling; also a single conceptual bottleneck. | No — per-service APIsMore variation between services; CloudFormation is one client among many. | Partly — Cloud Resource Manager plus per-service APIsLess unified than ARM, more than AWS. |
| First-party IaC language | ARM JSON, with Bicep as the human-facing DSLBicep compiles to ARM; type-safe, modular, idempotent. | CloudFormation YAML/JSON, with CDK for real languagesCDK synthesises CloudFormation. | No dominant first-party option — Terraform is the de-facto standardConfig Connector for Kubernetes-native management. |
| Billing boundary | SubscriptionTied to a billing account/profile. Also the quota boundary. | Account, consolidated at the organizationBilling and isolation are the same object. | Billing account, separate from the hierarchyThe odd one out — see S4. Projects link to a billing account sideways. |
| Interactive shell in-browser | Azure Cloud ShellBash or PowerShell, persistent file share, pre-authenticated. | AWS CloudShell | Cloud ShellIncludes a free ephemeral VM and an editor; the most generous of the three. |
Azure's global fabric, and where GPUs sit in it
Azure's geography is the one piece of vocabulary here with no clean equivalent elsewhere, and it's the one a compliance officer will care about. Think of it as the country or bloc — "Europe", "United States", "India" — inside which Microsoft commits to keeping your data. Regions are cities inside that country. Zones are buildings inside the city.
The practical effect: on AWS you answer "where does the data live?" by naming regions and hoping nobody asks what binds them together. On Azure you answer with a single word, because Microsoft named the layer. That's a small thing that makes conversations with auditors substantially shorter.
Azure adds one layer above the region that the others don't name as clearly:
| Layer | What it is |
|---|---|
| Geography | A broad area — United States, Europe, India — containing multiple regions. This is the data-residency boundary, and it's the layer compliance teams care about. Microsoft's clearest structural idea; AWS approximates it with partitions, Google with org policy constraints. |
| Region | A set of datacenters within a geography, connected by a low-latency network. 70+ of them. Region names are place-based: westeurope, eastus2, swedencentral. |
| Availability zone | Physically separated groups of datacenters within a region, each with independent power, cooling and networking. Microsoft targets under approximately 2 ms round-trip between zones. Supported in roughly 35 regions. |
| Paired region | A second region in the same geography used by some services for geo-replication and staged platform updates. Not every region is paired — newer ones increasingly aren't. |
| Datacenter | The physical building. You never address one directly. |
Zonal vs zone-redundant is the Azure vocabulary worth memorising. A zonal resource is pinned to one zone you chose — if that zone fails, it fails, and redundancy is your job. A zone-redundant resource is spread across zones by the platform, which handles failover for you. Whether a given SKU supports zone-redundancy varies by service and by region, and it's the first thing to check when someone asks for a availability guarantee.
The ND and NC families
| Family | Silicon | Notes |
|---|---|---|
| NC-series | A100, H100 and predecessors | General compute-focused GPU VMs. The realistic starting point for self-hosted inference on Azure. |
| NV-series | Visualisation-oriented GPUs | Remote desktop and rendering. Occasionally cheaper for light inference, but not designed for it. |
| ND-series | H100, H200, GB200, GB300 | The training tier, with InfiniBand between nodes. ND GB300 v6 delivers up to 1.44 exaFLOPS FP4 per NVL72 domain and has demonstrated roughly 1.1 million tokens/second of LLM inference throughput per rack — about 27% above ND GB200 v6, with 288 GB HBM3E per GPU versus 192 GB. |
Microsoft Learn — ND GB300 v6 series
Those rack-scale numbers are not something you'll provision from a portal, but they're the right units to think in when comparing vendors' training capacity — tokens/second per rack is a more honest comparison than FLOPS.
- The zone-coverage gap is the big one. Roughly half of Azure's 70+ regions don't advertise availability zones. If a compliance requirement pins you to a geography whose only region is single-zone, zone-redundant HA is simply unavailable and your resilience story has to bebefore you commit to an SLA, not after.
- Zone-redundancy is a per-SKU property, not a per-service one. A service may support it on its premium tier and not its standard tier, and support can differ by region within one tier. "Does Azure SQL support zones?" is the wrong question; "does this tier, in this region?" is the right one.
- Paired regions are a fading guarantee. Azure historically paired every region for staged platform updates and geo-replication. Newer regions increasingly ship non-paired, on the reasoning that availability zones plus explicit customer-designed replication is the better model. Don't assume a pair exists because one always used to.
- Region names understate and overstate distance.
eastusandeastus2are both in Virginia;westusis California andwestus2is Washington state. Deploying to "east" and "west" gives you real separation; deploying toeastusandeastus2gives you considerably less than the names suggest. - GPU capacity concentrates in a handful of regions. The ND-series doesn't exist everywhere, and within a supported region it can be constrained. As on AWS, capacity frequently decides your region, and your latency and residency requirements then have to fit inside what's left.
Counting the boundaries, on paper
The scenario. Same GenAI platform team from S2, now on Azure. Four workloads: production inference, dev inference, a fine-tuning pipeline, a labelling app. Plus a hard requirement: EU customer data must stay in the EU. How does the shape differ from AWS?
| Layer | Choice | What it buys you |
|---|---|---|
| Tenant | 1 | One identity domain. Adding a second would double identity ops for no gain here. |
| Management groups | 3 + root | Platform / Landing Zones / Sandbox. A single Policy at "Landing Zones" saying allowedLocations = [westeurope, northeurope, swedencentral] satisfies the EU-residency requirement for every current and future subscription beneath it. That's the layer earning its keep. |
| Subscriptions | 4 | prod-inference, dev-inference, finetune, labelling. Four separate GPU quota pools — the fine-tuning run cannot starve production. |
| Resource groups | ~10 | Per workload: one for compute, one for data, one for networking. Lifecycle-aligned, so teardown is one command per group. |
On AWS the residency requirement is enforced by an SCP on the OU denying all
actions outside approved regions. On Azure it's an Azure Policy at the management group with an
allowedLocations constraint. Functionally equivalent — and this is exactly the kind of
translation this stage is training.
But note one asymmetry that isn't just naming: the Azure policy can be set to
deny and paired with a modify policy that, say, appends a required tag to
every resource on creation. AWS has no equivalent preventive-mutation capability — you'd deny the untagged
creation and let the developer fix it, or remediate after the fact with Config plus Systems Manager. Same
goal, materially different developer experience.
A resource group is a deletion boundary as well as a management one.
Suppose rg-inference-prod contains:
| AKS cluster (3 nodes) | deleted |
| Managed identity used by the cluster | deleted — and every role assignment referencing it breaks |
| Public IP + load balancer | deleted — the IP is released and someone else may claim it |
| Storage account holding model weights | deleted — and unless soft-delete is on, the blobs go with it |
| Key Vault with API credentials | deleted, but soft-delete is on by default with a 90-day recovery window |
| A VNet in a different resource group that the cluster peers to | survives — different RG, different deletion boundary |
CanNotDelete) on anything whose loss would ruin your week.Two grounded examples
1 · Azure landing zones — and Microsoft's answer to "do I need an AI landing zone?"
Microsoft's Cloud Adoption Framework defines the Azure landing zone as a reference architecture plus reference IaC (Bicep, Terraform, ARM), rather than a managed service like AWS Control Tower. The canonical management-group tree is Tenant Root → a single top-level management group → Platform, Landing Zones, Decommissioned, Sandbox — with subscriptions hanging off the appropriate branch.
The directly relevant guidance: Microsoft explicitly addresses whether AI workloads need their own landing zone, and answers no — you deploy AI workloads into ordinary application landing zone subscriptions, because the existing design areas and principles already cover them. That's a deliberately deflationary answer and a good one. It's also a useful counter to the reflex of building a bespoke "ML platform" structure that diverges from everything else the organisation runs.
2 · The free account, and why the "12 months free" mental model misleads
Azure's free offer has three distinct components that people routinely merge into one: (1) a $200 credit valid for 30 days only — unused credit is lost, cannot be extended, and cannot be reissued; (2) a set of popular services free for 12 months up to monthly limits; (3) 55–65+ services that are always free up to monthly limits. When the 30 days expire or the credit is spent, your subscription and services are disabled until you move to pay-as-you-go.
Two practical notes. The material pricing section covers Free Tier, pay-as-you-go, Reserved Instances, Spot and Hybrid Benefit accurately as concepts, but treat the specific figures as indicative. And: GPU SKUs are commonly blocked during the credit period — if a single deployment would cost more than your remaining credit, Azure may refuse it outright. Don't plan a GPU lab on trial credit.
Microsoft Learn — avoid charges with your Azure free account Azure free account
Your context, and one lab
Working Azure literacy, from where you already stand
You asked for working literacy rather than depth here, so this is the translation table that makes an Azure conversation legible rather than one that makes you an Azure engineer.
| You know | Azure calls it | The difference that actually matters |
|---|---|---|
| GKE | Azure Kubernetes Service (AKS) | No Autopilot equivalent — you manage node pools. GPU nodes need the NVIDIA device plugin or the GPU operator, same as anywhere. Your KServe and vLLM manifests port over largely unchanged. |
| Vertex AI | Azure Machine Learning, and Azure AI Foundry | Azure ML is the training/deployment platform; AI Foundry is the newer model-and-agent layer that wraps Azure OpenAI and other models. Two products where Google has one, which is genuinely confusing at first. |
| Cloud Run with a GPU | Azure Container Apps | Serverless containers with a GPU option. The closest Azure gets to the Modal experience — check current GPU availability by region before designing around it. |
| GCP spot / preemptible VMs | Azure Spot Virtual Machines | Same idea, same deep discount, eviction on capacity pressure. Configurable eviction policy (deallocate vs delete), which GCP doesn't offer in the same form. |
| Workload Identity | Managed identities for Azure resources | The same "give the workload an identity instead of a secret" pattern. System-assigned identities are tied to the resource's lifecycle; user-assigned ones outlive it. |
| gcloud CLI | az CLI | Verb-last instead of verb-last-ish: az vm create, az group delete. Same shape. Azure Cloud Shell gives you it pre-authenticated in the browser with a persistent file share. |
The specific thing to remember: GPU quota is per-subscription per-region and starts at zero. Not per-tenant, not per-management-group. If your team gets four subscriptions per the reality-check design, that's four separate quota conversations — and if you later expand from West Europe to Sweden Central for capacity reasons, that's a fresh request in each subscription that needs it.
Plan the request before the project. The people who get surprised are the ones who architect for six months and then discover the accelerator they designed around has a zero quota and a multi-week lead time in the region their compliance policy allows.
Lab — deploy the smallest possible thing with Bicep, then destroy it
Budget: 40 minutes. Cost if you follow the teardown: under $0.05, or $0 on a free account. This lab exists to make the ARM/Bicep loop concrete, not to build anything useful.
- Budget before resources. Portal → Cost Management → Budgets → Add. Scope: your subscription. Amount: $5, monthly. Alert at 50%, 80%, 100% to your email. Azure lets you set a budget at subscription creation — do it there if you're creating one now.
- Smallest SKU only.
Standard_B1s— 1 vCPU, 1 GB. Burstable, cheapest thing that boots. No GPU SKUs in this lab. - One resource group for everything, so teardown is a single command.
- Open Cloud Shell from the portal (the >_ icon) and pick Bash. It's pre-authenticated, so no credential setup.
- Look at the hierarchy you're actually in:
az account show --output table # which subscription, which tenant az account management-group list --output table # empty is normal on a personal account az group list --output table # existing resource groups - Create one resource group:
Note that this cost nothing — resource groups are free. Only what's inside them bills.az group create --name rg-lab-s3 --location westeurope - Write a minimal Bicep file —
cat > lab.bicepthen paste:param location string = resourceGroup.location resource stg 'Microsoft.Storage/storageAccounts@2023-05-01' = { name: 'stlab${uniqueString(resourceGroup.id)}' location: location sku: { name: 'Standard_LRS' } kind: 'StorageV2' properties: { supportsHttpsTrafficOnly: true, minimumTlsVersion: 'TLS1_2' } } output storageName string = stg.name - Deploy it, then deploy it again:
The second run changes nothing and succeeds. That's idempotency, and it's the whole reason declarative IaC beats scripts. An emptyaz deployment group create --resource-group rg-lab-s3 --template-file lab.bicep az deployment group create --resource-group rg-lab-s3 --template-file lab.bicep # run it twiceStandard_LRSstorage account costs essentially nothing. - See what ARM recorded:
Deployments are first-class objects with history. There is no equivalent single view in AWS or GCP — this is a direct consequence of the universal-control-plane design.az deployment group list --resource-group rg-lab-s3 --output table - Optional — see Policy work. Assign the built-in "Allowed locations" policy to your resource group,
restricted to
westeurope, then try creating something ineastus. The denial happens at ARM, before any resource provider is involved. That is the mechanism from Pass 2, visible.
az group delete --name rg-lab-s3 --yes --no-wait
# then confirm it's actually gone (--no-wait returns immediately):
az group list --output table
# and check nothing survived elsewhere in the subscription:
az resource list --output table
Two gotchas. If you assigned a policy in step 7, remove the
assignment separately — policy assignments at RG scope are cleaned up with the group, but assignments you
made at subscription scope are not: az policy assignment list --output table, then
az policy assignment delete --name <name>. And if you created a Key Vault at any point,
soft-delete keeps it recoverable (and name-blocking) for 90 days — purge it explicitly with
az keyvault purge --name <name> if you want the name back.
Azure gave you five layers and one universal control plane. Google goes the other way: four layers, a boundary as cheap as AWS's, and a networking model that is global by default rather than regional.
Carry this into S4: if a VPC can span every region at once, what does "region" still decide — and where did Google put the billing boundary, given it isn't in the tree?
Session 4 · The green lane. Four layers, a billing account off to the side, and a network that ignores regions.
Google inverted a default, and it changes the designs
On AWS and Azure, a virtual network is a regional object. Want your Frankfurt and Tokyo workloads on one private network? You build two VPCs and peer them, or you attach both to a transit hub. The regional boundary is the default and global reach is the thing you construct.
On Google Cloud, a VPC is a global resource. One network object spans every region; you add regional subnets to it. Two VMs on opposite sides of the planet in the same VPC can talk over private IPs with no peering, no gateway, no extra object. Similarly, a Google Cloud load balancer can present one anycast IP address worldwide and steer each user to the nearest healthy backend.
This isn't a marketing distinction — it changes what a design looks like. Google is willing to make things global by default because they own an unusually large private fibre network and route your traffic onto it as early as possible. Which leads to the second theme: on Google, the interesting question is often not "which region?" but "which scope — global, regional, or zonal?"
And one structural oddity that catches everyone: Google's billing boundary is not in the resource hierarchy. Projects link sideways to a billing account. We'll get to why that's actually useful.
Organization → folder → project → resource
A university. The organisation is the university itself. Folders are faculties and departments, nested however the institution is actually shaped. A project is a single research project: it has its own budget code, its own key-card list, its own lab space, and it ends. The resources are the equipment in the lab.
The billing account is the finance office. It isn't inside the biology department — it's a separate entity that departments charge to. Two projects in completely different faculties can both charge the same grant, and moving a project between departments doesn't change which grant funds it. That's exactly Google's model, and once you see it that way the "sideways" billing link stops being weird and starts being obviously correct.
Click any node to see what it controls and where the inheritance flows.
Project identifiers — three of them, and they aren't interchangeable
| Identifier | Example | Properties |
|---|---|---|
| Project ID | infer-prod-4471 | Globally unique across all of Google Cloud, chosen by you at creation, permanently immutable. This is what almost every API and CLI command wants. Choose carefully — you cannot rename it, only recreate the project. |
| Project number | 884219347715 | Auto-assigned, globally unique, immutable. Appears in service-account emails and some API responses. You'll paste it more than you expect. |
| Project name | Inference Prod | Human display label. Not unique, freely editable, means nothing to the API. The one that's safe to change. |
Two governance systems, again — but shaped differently from Azure's
Bind a role (a bundle of permissions) to a principal at a node in the hierarchy. Allow policies inherit downward and are additive: a role granted at the organisation cannot be revoked at a project by an allow policy. Deny policies exist for that, and are newer and less commonly used.
The additive-inheritance rule is the trap. Grant someone Editor at the org "just for now" and you cannot scope it back down at a folder — you have to remove it where it was granted.
A separate system built on named constraints rather than IAM permissions. Set a
constraint at a node and every descendant inherits it. Examples:
constraints/gcp.resourceLocations to enforce data residency,
constraints/compute.requireShieldedVm, constraints/iam.disableServiceAccountKeyCreation.
Constraints restrict; they never grant. This is the direct analogue of an AWS SCP
and an Azure Policy deny, but with its own vocabulary — you look up constraint names, you
don't write policy documents.
Scope in practice — why the global VPC changes designs
The three-scope model isn't trivia; it's the thing that makes Google Cloud designs look structurally different from their AWS and Azure equivalents. Worth three passes, because it's the concept most likely to mislead someone arriving from another cloud.
On AWS and Azure, a private network is a walled garden you build per city, and connecting two cities means building a road between them. On Google, the private network is closer to a national postal system: it already reaches everywhere, and what you allocate per city is an address range. You don't connect Frankfurt to Tokyo — they were never disconnected.
A VPC network is a global resource with no region attribute at all. You attach regional subnets to it, each with its own CIDR range. Firewall rules are properties of the network, so they apply wherever the traffic is. A global external load balancer takes a single anycast IP, advertised from Google's edge worldwide, and routes each user to the nearest healthy backend — which may sit on a different continent from the user's entry point, with the journey travelling over Google's own fibre rather than the public internet.
The equivalent on the other two: a regional VPC/VNet per region, an explicit peering or transit object joining them, a load balancer per region, and a DNS-based or anycast frontend on top to steer between them. Same outcome; four more object types to build, secure and keep in sync.
- A global object has a global blast radius. One over-permissive firewall rule applies in every region the network reaches. On AWS the identical mistake is contained to one region's VPC by construction. Convenience and containment are trading against each other here.
- It concentrates authority. If every team's workloads share one VPC, whoever can edit that VPC can affect every team. The answer is Shared VPC: a host project owns the network, service projects attach to it, and the right to change the network becomes an IAM grant on the host project. Governance moves out of the network and into the hierarchy — which is very much the Google pattern, and the same instinct behind org policy constraints.
- Global doesn't mean free, and it doesn't mean fast. Inter-region egress is billed, and the speed of light is unchanged. You removed the plumbing, not the physics.
- IP planning becomes one global exercise. A single address space across all regions means overlapping CIDRs can't be papered over later. That's a real discipline benefit paid for with real upfront work — and it's the thing to settle before your first production subnet, not after.
The gcloud CLI, structurally
Google's CLI is the most consistently-shaped of the three, and worth learning as a grammar
rather than a list of commands: gcloud <group> <subgroup> <verb> [args].
gcloud compute instances list # group=compute, subgroup=instances, verb=list
gcloud projects describe MY_PROJECT_ID
gcloud resource-manager folders list --organization=ORG_ID
gcloud config set project MY_PROJECT_ID # sets the ambient project for later commands
The gcloud config ambient state is a real footgun: commands silently
operate on whichever project is currently configured. In scripts, always pass --project
explicitly rather than trusting the ambient value.
- Folder depth 10, 300 children per parent, one parent each. Deeper than Azure's 6 and AWS's 5. Almost nobody needs 10 — three or four levels is a healthy tree, and more usually means you're modelling the org chart instead of the governance requirements.
- A folder requires an organisation resource. On a personal free-trial account with no Cloud Identity domain, projects are the top of your hierarchy and folders are simply unavailable. GCP guidance's source notes this explicitly and it surprises people who follow enterprise tutorials on a personal account.
- Deleting a project is reversible for ~30 days. The project moves to a pending-deletion state and can be restored. Genuinely more forgiving than deleting an Azure resource group. Don't rely on it, but it has saved people.
- Quotas are per-project, and GPU quota starts at zero. Same story as the other two clouds. Because projects are cheap, the natural GCP pattern is a dedicated project per GPU workload with its own quota.
- Global resources are a shared blast radius. A global VPC's firewall rules apply everywhere in it. A bad rule is a global bad rule. Shared VPC — a host project owning the network, service projects attaching — is how you keep the convenience while putting a governance boundary around who can change it.
- P100 GPUs reach end of support on 15 September 2026 — after that you cannot create or access resources using them. Google's own recommendation is to migrate to T4 or L4. Checked I want to flag this explicitly because there is third-party content circulating claiming Google is retiring the T4 in 2026. That is wrong — the T4 is one of the recommended migration targets, and it's still listed as attachable to N1 instances in current documentation. Your T4-based Vertex AI work is not on a deprecation path.
Google Cloud — NVIDIA P100 end of support GPU machine types
AI zones — the 2026 addition that changes GPU placement
us-central1-ai1a. Every AI zone has a parent zone — a standard zone with the same suffix
(here, us-central1-a) — through which it connects to the rest of Google Cloud.Significant accelerator density — the place large GPU and TPU capacity actually exists.
TPU7x, for instance, is listed in us-central1-ai1a alongside standard zones. If you need a
lot of accelerators at once, this is increasingly where they are.
They sit geographically apart from the region's standard zones — typically within a 5 ms radius — and they don't offer every Google Cloud service locally. Reaching a service in the parent region adds network latency. Google's own guidance: run non-ML workloads in standard zones.
Shared fate with the parent zone. They share software update schedules and
sometimes infrastructure, so a problem in us-central1-a can take
us-central1-ai1a with it. For availability maths, treat an AI zone and its parent as
one failure domain, not two.
Compute Engine release notes list AI zones as generally available; access must be enabled per project. Google Cloud — About AI zones TPU regions and zones
Decision tree — new project, new folder, or an existing project?
Something new needs a home in Google Cloud. Read down; any "yes" exits right.
The full translation table — everything from all four sessions
This is the recap. If you can reproduce this table from memory, C1 has done its job.
| Concept | AWS | Azure | Google Cloud |
|---|---|---|---|
| Hierarchy root | Organizationvia a management account | Tenant → root management groupidentity and governance root are one | Organization resourcederived from your Cloud Identity domain |
| Grouping node | Organizational Unit — 5 deep | Management group — 6 deep, 10,000 max | Folder — 10 deep, 300 children |
| Isolation boundary | Accountfree, hard wall | Subscriptionheavier; billing + quota unit | Projectfree, hard wall, trust boundary |
| Sub-boundary grouping | — (tags + IAM) | Resource group — 980/subscriptionalso the deletion unit | — (the project is already small) |
| Billing attaches to | Account, rolled up at the org | Subscription | Billing account, referenced sidewaysthe structural outlier |
| Region count (Jul 2026) | 39 | 70 | 43 |
| Fault domains | 123 AZs, min 3/region | ~35 AZ-enabled regions, <2 ms target | 130 zones, 3+/region, plus AI zones |
| Virtual network scope | VPC is regional | VNet is regional | VPC is globalsubnets are regional inside it |
| Multi-region private networking | VPC peering / Transit Gateway | VNet peering / Virtual WAN | Nothing to build — same VPC |
| Identity spine | IAM + Identity Center | Microsoft Entra ID + RBAC | Cloud Identity + Cloud IAM |
| Preventive guardrail | SCP + RCP + declarative policy | Azure Policycan also modify/remediate | Organization Policy constraints |
| Landing zone | Control Tower (managed service) | CAF Azure Landing Zones (architecture + IaC) | Cloud Foundation Toolkit / blueprints (Terraform) |
| Managed Kubernetes | EKS | AKS | GKEAutopilot removes node management |
| Managed ML platform | SageMaker AI | Azure ML + AI Foundry | Vertex AI |
| Serverless container + GPU | —Fargate has no GPU; use EKS or SageMaker | Container Apps | Cloud RunL4 attachable, scales to zero |
| Discounted interruptible compute | Spot Instances2-min warning | Spot VMsdeallocate or delete policy | Spot VMssuccessor to preemptible; also Flex-start for GPUs |
| Free offer | $100→$200 credits, 6-month Free plan, 30+ always-free | $200 for 30 days, 12 months select services, 55+ always-free | $300 for 90 days, 20+ always-free products |
| Well-Architected | 6 pillars + lenses | 5 pillars | 6 pillars + perspectives |
| Responsibility doctrine | "of the cloud / in the cloud" | Layered by service model | Shared responsibilityshared fate |
Availability maths when a zone has a parent
The scenario. You're placing a fine-tuning job that needs 16 accelerators in us-central1,
and an inference endpoint that must stay up. AI zones have the capacity. What does that do to your availability
numbers?
| Placement | Assumed independent domains | Assumed outcome |
|---|---|---|
us-central1-a (parent) | 1 | "Any one zone can fail and two remain. Standard 3-zone HA." |
us-central1-ai1a (AI zone) | 2 | |
us-central1-b | 3 |
| Placement | Real failure domain | Why |
|---|---|---|
us-central1-a | Domain 1 | The AI zone connects to the rest of Google Cloud through its parent, and they share software update schedules and sometimes infrastructure. An issue in the parent can take the AI zone with it. |
us-central1-ai1a | Domain 1 — same | |
us-central1-b | Domain 2 | A genuinely independent standard zone. |
-b, -c, and an AI zone whose parent is neither.Split by workload type, not by convenience. The fine-tuning job is batch —
it can tolerate a zone failure by restarting from a checkpoint, so put it in the AI zone where the
accelerators actually are and take the capacity win. The inference endpoint has an availability target, so
put its replicas in standard zones -b and -c, which are independent of each other
and of the AI zone's parent.
That's a clean example of the general rule: capacity and availability are different requirements and they often want different placements. Trying to satisfy both from one zone choice is how designs quietly become single-domain.
| Cloud | Delete the boundary | What happens |
|---|---|---|
gcloud projects delete | Project enters a pending-deletion state. Resources stop, but the project can be restored for roughly 30 days. The most forgiving of the three. | |
| Azure | az group delete | Resources are destroyed. Only services with their own soft-delete (Key Vault at 90 days, blob soft-delete if enabled) survive. No group-level undo. |
| AWS | Close account | 90-day post-closure window during which the account can be reopened, but resources are terminated and data in most services is gone. Closing an account is not a teardown mechanism. |
Two grounded examples
1 · vLLM on GKE is a first-class, documented path — including for Gemma
Google maintains official tutorials for serving Gemma and Llama models with vLLM on GKE
across H200, H100, A100 and L4 GPU hardware, including TPU variants for Gemma. The pattern is exactly the
one you already know: a Hugging Face token in a Kubernetes secret, a Deployment running a pre-built vLLM
container, resource requests specifying nvidia.com/gpu, and an OpenAI-compatible endpoint
exposed at the end of it.
The interesting recent addition is GKE Inference Gateway, which extends the Kubernetes Gateway API with routing that's aware of AI-specific signals — pending prompt requests and KV cache utilisation — rather than the round-robin or least-connections logic a normal ingress controller uses. If you've run vLLM behind an ordinary load balancer and watched requests pile onto a replica whose KV cache is already saturated, that's the problem it addresses. Worth reading even if you deploy elsewhere, because the concept generalises.
Serve Gemma using GPUs on GKE with vLLM GKE Inference Gateway walkthrough
2 · The free trial's hierarchy limitation — and why enterprise tutorials fail on it
Signing up creates a Free Trial billing account preloaded with $300 of credit, valid for 90 days. During it you get full product access plus the always-free tier. If you don't upgrade to a paid billing account before the 90 days elapse (or before the credit runs out), the billing account closes and all associated projects and resources are stopped — with a 30-day window to recover by upgrading.
The structural point GCP guidance's source makes, which matters for this session: free-trial and free-tier users can only create projects and the resources inside them. Projects sit at the top of your hierarchy because you have no organisation resource — and without an organisation resource, folders are unavailable entirely. So every enterprise tutorial that begins "create a folder for production" simply cannot be followed on a personal account. That's not a mistake in the tutorial; it's a real property of the hierarchy that you should be able to explain.
Your context, and one lab
Your Vertex AI script, re-read as a hierarchy document
You already wrote a Vertex AI deployment — T4 GPUs, autoscaling 1–3, spot instances. Every line of it is making a decision from this session, whether or not it was framed that way at the time:
| What your script sets | Which concept | What you actually decided |
|---|---|---|
| Project | Isolation boundary | Which quota pool you draw from, which service accounts have default trust, which billing account pays, and — if you're in an org — which folder's policies apply. One field, five consequences. |
| Region / location | Global fabric | Where the endpoint runs, what your latency floor is, which residency regime applies, and whether T4s are even available there. Vertex AI's regional availability for specific accelerators is narrower than Compute Engine's. |
| T4 accelerator | Zonal resource | A GPU is zonal. The endpoint is regional, so Vertex places replicas for you — but the underlying capacity constraint is per-zone, which is why "no capacity" errors can happen in a region that nominally supports the accelerator. |
min_replica_count=1 | Shared responsibility + cost | You bought away cold starts by paying for one always-warm GPU. That's roughly $200–300/month of "the latency guarantee is not my problem". A completely defensible trade — just an explicit one now. |
max_replica_count=3 | Elasticity ceiling | Your self-imposed cap. Note it's below your quota, not equal to it — which is the right instinct. A max that equals your quota means a traffic spike consumes everything. |
| Spot instances | Interruptible compute | Deep discount for eviction risk. Fine for the replicas above your baseline; risky if your only replica is spot. Check whether your config would survive an eviction of replica 1. |
- Check whether L4 beats T4 for your model. Both are fully supported and neither is deprecated (P100 is the one going away, in September 2026). The L4 has substantially more memory and newer tensor cores; for a model that just fits on a T4 with heavy quantisation, an L4 may be cheaper per token despite a higher hourly rate. Measure tokens/second per dollar, not dollars per hour — that's the metric that actually decides.
- Look at Cloud Run with a GPU as a Modal-shaped alternative. You can attach an L4 to a Cloud Run service, bill per second, and scale to zero, with no quota request required in the way Compute Engine demands. That's the closest thing in the three hyperscalers to the Modal experience, and it's directly comparable to what you already built.
- Decide, deliberately, whether GKE or Vertex owns your serving. Google's own docs push you toward Vertex for a managed path and GKE when you want Kubernetes control — and given your KServe background, GKE plus the Inference Gateway is probably the better long-term fit for open-source-first work. Vertex is the higher line on the S1 diagram; GKE keeps the vLLM configuration in your hands.
Lab — walk your own hierarchy, create one project, delete it
Budget: 35 minutes. Cost: $0.00 if you follow the steps — projects and hierarchy operations are free, and this lab deliberately provisions no compute at all.
- Budget on the billing account, before anything else. Console → Billing → Budgets & alerts → Create budget. Scope it to your billing account, $5/month, alerts at 50 / 90 / 100%. Remember budgets live on the billing account, not in the hierarchy — that's this session's structural quirk made practical.
- No GPUs, no VMs, no clusters in this lab. If you want a compute exercise afterwards, use
e2-microin a free-tier-eligible region, and read the current free-tier terms first — they change. - Use Cloud Shell. Free, pre-authenticated, and its ephemeral VM costs nothing.
- See where you actually are in the hierarchy:
Ifgcloud organizations list # empty on a personal account — that's the point gcloud projects list gcloud config list # the ambient project/region footgun, made visibleorganizations listis empty, you have no organisation resource, which means no folders. You've just confirmed the free-trial limitation from the reality check on your own account. - Create a throwaway project (free, and the ID must be globally unique):
Look at the output:PROJECT_ID="lab-s4-$(date +%s)" gcloud projects create "$PROJECT_ID" --name="C1 Lab" gcloud projects describe "$PROJECT_ID"projectId,projectNumber,name. Three identifiers, as promised. Note alsolifecycleState: ACTIVE— that field is what changes toDELETE_REQUESTEDlater. - Link it to billing (required before most APIs will work, and the sideways link made concrete):
The billing account existed before the project and will outlive it. Nothing has been charged.gcloud billing accounts list gcloud billing projects link "$PROJECT_ID" --billing-account="XXXXXX-XXXXXX-XXXXXX" - See the three resource scopes for real:
In the zone list, look for any zone with angcloud compute regions list --project="$PROJECT_ID" --limit=5 gcloud compute zones list --project="$PROJECT_ID" --filter="region:us-central1"ai1-style suffix. If you see one, you're looking at an AI zone and its parent side by side. - Confirm your GPU quota is zero (the universal truth across all three clouds):
gcloud compute regions describe us-central1 --project="$PROJECT_ID" \ --format="table(quotas.metric,quotas.limit)" | grep -i gpu - Optional, if you have an organisation resource (work account only) — see inheritance:
Compare that constraint list to the SCPs in S2 and the Azure Policies in S3. Same job, three vocabularies — which is the whole point of the stage.gcloud resource-manager folders list --organization=YOUR_ORG_ID gcloud resource-manager org-policies list --organization=YOUR_ORG_ID
gcloud projects delete "$PROJECT_ID"
# confirm it's pending deletion rather than gone:
gcloud projects describe "$PROJECT_ID" --format="value(lifecycleState)"
# expect: DELETE_REQUESTED — recoverable for ~30 days, then permanent
Then verify nothing else is running. The GCP-specific risk isn't this project — it's an older one you forgot. Run:
gcloud projects list --format="value(projectId)" | while read p; do
echo "== $p"; gcloud compute instances list --project="$p" 2>/dev/null
done
Any running VM you don't recognise — especially a GPU one from an
old vLLM experiment — is billing right now. Stop it or delete it. Also check Vertex AI endpoints separately;
an endpoint with min_replica_count=1 holds a GPU permanently and does not appear in
compute instances list: gcloud ai endpoints list --region=us-central1 --project="$p".
That one has caught a lot of people, and it's exactly the shape of deployment you've already built.
You can now place any resource on any of the three clouds and say what fails with it, who can reach it, and who pays. That's the foundation the next stage stands on: identity and networking in depth, where the boundaries you've learned to draw start carrying real traffic and real permissions.
The question to sit with until then: you've seen three hierarchies and three guardrail systems. Which of the three would you actually choose to govern a fifty-team GPU platform, and — more useful — what would you need to know about the org to answer that properly?