Global infrastructure
Regions, Availability Zones, edge locations.
AWS (Amazon Web Services) is laid out like a global courier company. Regions are the national sorting hubs: big, self-contained, one per major geography. Availability Zones are separate warehouses spread around the same metro area, close enough to shuttle parcels between them in minutes, far enough apart that a flood at one warehouse doesn't stop the city's deliveries. Edge locations are the parcel lockers on street corners, hundreds of them, holding popular items a short walk from your door. Every architecture decision you will ever make about latency, resilience, compliance and cost starts with knowing which of those three tiers a resource lives in.
The counts at the time of writing: 39 launched Regions, 123 Availability Zones, and 750+ edge points of presence (PoPs, small sites that serve traffic but never run your servers). The counts matter less than this. Nearly every AWS service is scoped to exactly one tier, *global*, *Regional* or *zonal*, and that scope decides what fails together, what you pay to move traffic around, and whose law your data sits under.
Regions: choose the geography on purpose
A Region is a named geographic area. eu-west-1 is Ireland, ap-south-1 is Mumbai. Each one holds several Availability Zones plus its own independent copy of the Regional services: EC2 (Elastic Compute Cloud, rented virtual machines), VPC (Virtual Private Cloud, your own private network inside AWS), RDS (Relational Database Service, managed databases), Lambda and most of the rest. Regions are walled off from each other on purpose. Nothing copies from one to another unless you build the copying yourself, which keeps a bad day contained but also makes disaster recovery your job rather than Amazon's. Four things decide which Region you pick. Latency to the people actually using your app. Data-residency law: GDPR (the General Data Protection Regulation, the European Union's privacy law) restricts moving EU personal data outside the EEA (European Economic Area) without legal safeguards, so plenty of teams keep it in EU Regions and sleep better. Service availability: new services usually land in us-east-1, us-west-2 and eu-west-1 first. And price: the same m5.large runs about $0.096/hour in Virginia and $0.153/hour in São Paulo, roughly 60% more for identical hardware.
$ aws ec2 describe-regions --all-regions \--query "Regions[].{Region:RegionName,OptIn:OptInStatus}" \--output table-------------------------------------------| DescribeRegions |+----------------------+------------------+| OptIn | Region |+----------------------+------------------+| opt-in-not-required | eu-west-1 || opt-in-not-required | us-east-1 || opted-in | ap-east-1 || not-opted-in | af-south-1 || not-opted-in | eu-central-2 |+----------------------+------------------+# trimmed — expect ~40 rows in a current account# Turn on an opt-in Region for this account (no output on success):$ aws account enable-region --region-name af-south-1# The operation is asynchronous — poll it:$ aws account get-region-opt-status --region-name af-south-1{"RegionName": "af-south-1","RegionOptStatus": "ENABLING"}
Any Region launched after March 20, 2019 is opt-in. It stays invisible to your account until you switch it on with the Account Management API (application programming interface) shown above. Two wrinkles follow. Enabling finishes in minutes for most accounts but can drag on for hours, because AWS has to copy your IAM (Identity and Access Management) data into the new Region, and the switch applies account-wide. That makes it account-baseline automation, not something a deploy script should be doing. The second wrinkle bites harder. The global STS (Security Token Service, the thing that hands out temporary credentials) endpoint sts.amazonaws.com issues v1 session tokens, and opt-in Regions reject them. Move to Regional STS endpoints, which AWS recommends anyway, or set the token version to v2 with aws iam set-security-token-service-preferences --global-endpoint-token-version v2Token. That is the classic reason a role assumption works fine in eu-west-1 and then dies for no visible reason in ap-east-1.
Availability Zones: fault isolation you can walk into
An Availability Zone (AZ) is one or more separate data centers with their own power, cooling and physical security, wired to the other AZs in its Region over private, encrypted fiber. AWS keeps sibling zones within roughly 100 km of each other, so a round trip takes low single-digit milliseconds. Close enough for a database to replicate synchronously. Far enough that a fire, a flood or a dead power grid stays inside one zone. That makes the AZ the unit of fault isolation you design against, the thing that *fails together*. A VPC stretches across every AZ in its Region, but each subnet sits in exactly one zone, and so does every EC2 instance you launch into that subnet. (The VPC networking lesson takes it apart properly.)
$ aws ec2 describe-availability-zones --region eu-west-1 \--query "AvailabilityZones[].{Name:ZoneName,Id:ZoneId,Type:ZoneType,State:State}"[{ "Name": "eu-west-1a", "Id": "euw1-az3", "Type": "availability-zone", "State": "available" },{ "Name": "eu-west-1b", "Id": "euw1-az1", "Type": "availability-zone", "State": "available" },{ "Name": "eu-west-1c", "Id": "euw1-az2", "Type": "availability-zone", "State": "available" }]# --all-availability-zones also lists Local Zones and Wavelength Zones,# e.g. "us-east-1-bos-1a" with "Type": "local-zone".
Read that output again. eu-west-1a maps to euw1-az3, not euw1-az1. The letter-suffixed zone name is an alias that belongs to your account alone. The zone ID is the stable name of the physical zone underneath. AWS shuffles that mapping account by account on purpose, so that everybody's default "a" zone doesn't turn into the most crowded building in the Region.
us-east-1a in your account and us-east-1a in a teammate's account are usually *different physical zones*. So anything that crosses an account boundary has to key off zone IDs like use1-az4 and never zone names: keeping traffic inside one zone to dodge transfer charges, lining a partner's endpoints up with yours, or working a capacity problem with AWS Support. Resource Access Manager shares and support tickets speak zone IDs for exactly this reason.Not everything you want is available everywhere
Which services and which hardware you can get varies by Region and even by zone, and the console stays quiet about it until a launch fails. Two CLI (command line interface) habits answer the question "can I actually run this here?" before you commit a whole architecture to a Region. The first one: AWS publishes its own infrastructure catalog as public SSM (Systems Manager) parameters, a queryable list of which service exists where, with no documentation scraping involved.
# Every Region that offers EKS, straight from the public parameter store:$ aws ssm get-parameters-by-path \--path /aws/service/global-infrastructure/services/eks/regions \--query "Parameters[].Value" --output text --region us-east-1af-south-1 ap-east-1 ap-northeast-1 ap-south-1 eu-west-1 ...# Same trick for any service — swap 'eks' for 'bedrock', 'outposts', etc.$ aws ssm get-parameters-by-path \--path /aws/service/global-infrastructure/services/bedrock/regions \--query "length(Parameters)" --region us-east-132
The second habit covers hardware. Instance types differ *by zone inside a single Region*. New generations skip the older zones, old generations quietly vanish from the newer ones. You will care about this at 3 a.m., when an Auto Scaling group starts throwing InsufficientInstanceCapacity, which is a per-zone error. The grown-up fix is to spread across several instance types and several AZs. Retrying harder in the same zone is not a fix.
$ aws ec2 describe-instance-type-offerings \--location-type availability-zone \--filters Name=instance-type,Values=c7g.xlarge \--region eu-west-1 \--query "InstanceTypeOfferings[].Location" --output texteu-west-1a eu-west-1b eu-west-1c# Older generations quietly disappear from newer zones:$ aws ec2 describe-instance-type-offerings \--location-type availability-zone \--filters Name=instance-type,Values=m3.medium \--region eu-west-1 \--query "InstanceTypeOfferings[].Location" --output texteu-west-1a eu-west-1b
Edge locations, and what "global" really means
Edge locations are the third tier: small sites in hundreds of cities that don't *run* your workload, they *serve* it. CloudFront caches content there, Route 53 answers DNS (Domain Name System, the internet's address book) queries there, and Global Accelerator pulls user traffic onto Amazon's private backbone there. (The Route 53 and CloudFront lesson goes much deeper.) Only a handful of control-plane services are genuinely global: IAM, where one set of users, roles and policies covers every Region, plus Route 53 and CloudFront. Almost everything else is Regional. The classic exam trap is S3 (Simple Storage Service, AWS's object storage): bucket *names* are unique across the entire planet, yet every bucket and every byte inside it lives in exactly one Region. AMIs (Amazon Machine Images, the templates instances boot from) and EC2 key pairs are Regional too, so copy them deliberately if you go multi-Region.
Three infrastructure *extensions* finish the exam picture. Local Zones drop a single zone of compute into a metro area right next to end users, for single-digit-millisecond latency (game servers, live video). Wavelength Zones put compute inside 5G mobile carrier networks. Outposts is a rack of AWS-managed hardware installed in your own data center. On the exam they are keyword matches: "city-level latency" is a Local Zone, "5G or mobile edge" is Wavelength, "on-premises but with AWS APIs" is Outposts.
Designing with the three tiers
The default production posture is one Region chosen deliberately, with every layer of the stack spread across two or three AZs. Multi-AZ is not free, though. Traffic between zones costs $0.01/GB in each direction, so a chatty mesh of microservices that replicates everything across zones can quietly cost more than the servers running it. On very high volume internal paths, teams sometimes route traffic to stay inside one zone, trading a slice of resilience for real money. Going multi-Region multiplies complexity and spend, and it is reserved for hard residency rules or aggressive recovery targets. The lesson on high availability (HA) and disaster recovery (DR) covers when that earns its keep. Region price gaps cut the other way too: batch jobs and backups are perfectly happy in a cheap Region your users never touch.
You now know *where* things live in AWS. The next question is *who is allowed to touch them*, and the answer is IAM, the first genuinely global service on that list. Next up: how users, roles and policies gate every API call you ran above, and why aws sts get-caller-identity should be the first command you type in any account you don't know well.
When a compliance team says "the data must stay in the EU," what they mean is: pick eu-central-1 or eu-west-1, and do not quietly copy customer objects into us-east-1 because the analytics pipeline was easier to build there. Region choice is a legal decision and a latency decision before it is a pricing decision. Edge locations don't change that. CloudFront can cache your static assets a few miles from Paris, and your RDS primary still sits in one Region's Availability Zones.
Try reading every architecture diagram with three colored pencils: global (IAM, Route 53, CloudFront), Regional (a VPC, an S3 bucket, a Lambda function) and zonal (an EC2 instance, its EBS disk, its subnet). EBS is Elastic Block Store, the virtual hard drives that attach to instances, and a volume never leaves its zone. If two boxes that are supposed to fail independently end up the same color, you have drawn a single point of failure. The exam loves that trap. Real outages love it more.
Cross-Region traffic is never free and never instant. Replication lag, DNS TTLs (time to live, how long a resolver is allowed to cache an answer) and the plain human minutes it takes somebody to declare a disaster all dominate a real recovery. Knowing which tier a service sits in tells you what fails together, and what you have to copy yourself if you ever want a second Region to take over.
Try this
Point the AWS CLI at any profile you already have configured, list the Regions, then look at how many Availability Zones your default Region actually gives you. You are proving the hierarchy against live API data instead of taking a slide's word for it.
aws ec2 describe-regions --query 'Regions[].{Region:RegionName,OptIn:OptInStatus}' --output tableaws ec2 describe-availability-zones --region us-east-1 \--query 'AvailabilityZones[].{Zone:ZoneName,State:State,Group:GroupName}' --output tableaws s3api list-buckets --query 'Buckets[].Name' --output text | head -c 200
-----------------------------------------------------| DescribeRegions |+-------------+-------------------------------------+| OptIn | Region |+-------------+-------------------------------------+| opt-in-not-required | us-east-1 || opt-in-not-required | eu-west-1 |+-------------+-------------------------------------+us-east-1a | available | us-east-1us-east-1b | available | us-east-1# S3 bucket names are global; the bucket itself is still Regional
Takeaway
Hold on to three sentences. Regions are your compliance and blast-radius boundary. Availability Zones are the high-availability unit inside a Region. Edge locations only pull content closer to people, and they never move your database.
Next: sketch one workload on paper, spread it across AZs for high availability, and write an explicit line on whether multi-Region is genuinely required for disaster recovery or for regulation. Then price the data transfer before you promise anyone a recovery time objective (RTO).