Cloud platforms
Where the infrastructure actually lives
Go deep on one provider (AWS is the safe default). Compute, storage, IAM, VPC design, serverless and data services — then map the concepts to GCP and Azure.
On this page · 6 lessons
Core cloud building blocks
EC2, S3, VPC, RDS, Lambda — the five primitives everything else composes from. Plus billing alarms on day one.
The cloud is where your infrastructure actually lives. Go deep on one provider — AWS is the safe default given its market share — and the concepts transfer to the others.
The primitives everything else is built from:
- Compute — EC2: virtual servers you rent by the second. (Plus serverless Lambda: run code with no server to manage.)
- Storage — S3: effectively infinite object storage for files, backups, and static sites.
- Networking — VPC: your private, isolated network — subnets, route tables, and security groups.
- Database — RDS: managed SQL databases (Postgres, MySQL) so you don't operate the engine yourself.
- Identity — IAM: who can do what. This is the one to learn properly — most cloud breaches are misconfigured permissions.
The golden rule everywhere is least privilege: grant the minimum permissions needed, use roles instead of long-lived keys, and turn on a billing alarm on day one so a mistake doesn't become a shocking invoice. Frame every design against the Well-Architected Framework (reliability, security, cost, performance, operations).
IAM & cloud identity
Users, roles, policies and least privilege. Most cloud breaches are misconfigured permissions — learn this properly.
Most cloud breaches are not clever exploits — they're misconfigured permissions. IAM is the single highest-stakes thing you'll configure, and it's worth genuine study.
The building blocks (AWS names; every cloud has equivalents):
- Users — humans. Groups — collections of users.
- Roles — a set of permissions that can be assumed temporarily, by a person, a service, or an EC2 instance/Pod.
- Policies — JSON documents granting or denying specific actions on specific resources.
The rules that keep you safe:
- Least privilege. Grant the minimum action on the minimum resource. Start from nothing and add; never start from
*and trim."Action": "*"on"Resource": "*"is how companies end up in the news. - Roles over long-lived keys. A static access key that leaks into a Git repo is a permanent breach. Roles issue short-lived, auto-rotating credentials. Give applications a role (IAM Roles for Service Accounts on EKS, Workload Identity on GKE), never a key file.
- MFA everywhere, and never use the root account for daily work — lock it away.
- Audit. Turn on CloudTrail (every API call is logged), and use access analysers to find unused permissions and prune them.
VPC design & cloud networking
Public vs private subnets, NAT, security groups, multi-AZ, peering and PrivateLink — the backbone diagram of production.
Cloud networking is where the theory from Stage 3 becomes a design you're responsible for. Get it wrong and you're either exposed to the internet or unable to talk to your own database.
A VPC is your private, isolated network in the cloud, defined by a CIDR block (e.g. 10.0.0.0/16). Inside it you carve subnets, and the fundamental split is:
- Public subnet — has a route to an Internet Gateway. Put only internet-facing things here: load balancers, bastion hosts.
- Private subnet — no direct route in from the internet. Put everything else here: app servers, and above all databases. Private resources reach out (for updates) through a NAT Gateway.
That two-tier pattern is the default for a reason: your database should be unreachable from the internet by construction, not by a firewall rule someone might loosen.
Traffic is controlled by security groups (stateful, attached to resources — the main tool) and NACLs (stateless, at the subnet level). Deploy across multiple Availability Zones so one datacentre failure doesn't take you down.
To connect networks: VPC peering (simple, one-to-one), Transit Gateway (a hub for many VPCs), and PrivateLink/VPC endpoints — which let you reach cloud services (like S3) without traversing the public internet at all.
Serverless & event-driven
Lambda and Cloud Run, event triggers, cold starts and lock-in — and when serverless genuinely wins.
Serverless doesn't mean no servers — it means you don't manage them. You hand the provider a function or a container, and it handles provisioning, scaling, and patching. You pay only for what you actually execute.
The core service is Functions as a Service — AWS Lambda, Google Cloud Functions, Azure Functions. Your code runs in response to an event: an HTTP request via an API Gateway, a file landing in S3, a message on a queue, a cron schedule.
def handler(event, context):
bucket = event["Records"][0]["s3"]["bucket"]["name"]
key = event["Records"][0]["s3"]["object"]["key"]
make_thumbnail(bucket, key)
return {"statusCode": 200}
Where serverless wins: spiky or unpredictable traffic (it scales from zero to thousands automatically), event-driven glue, scheduled tasks, and anything where paying for an idle server is silly.
Where it hurts: cold starts (an idle function takes time to boot — bad for latency-critical paths), execution time limits (~15 min), vendor lock-in, and the fact that a large serverless system becomes a distributed system that is genuinely hard to debug and test locally. At sustained high volume it can also cost more than a plain server.
The middle ground is serverless containers — AWS Fargate, Google Cloud Run — where you ship a normal container image and still don't manage nodes. This is often the sweet spot.
Databases, caching & queues
Managed SQL vs NoSQL, Redis in front, and queues/streams (SQS, Kafka) so failures buffer instead of cascading.
Applications are stateless and disposable; data is neither. Choosing and operating the right data store is where a lot of real engineering happens.
Databases
- Relational (SQL) — Postgres, MySQL, via managed services like RDS/Cloud SQL. Strong consistency, transactions, joins. This should be your default; "boring" Postgres solves the overwhelming majority of problems.
- NoSQL — DynamoDB, MongoDB, Cassandra. Enormous scale and flexible schemas, but you must design around your access patterns up front and give up joins and (often) strong consistency.
Whatever you pick, use the managed version. Running your own production database — backups, replication, failover, patching — is a full-time job you don't want.
Caching — Redis/Memcached (ElastiCache) sit in front of the database and serve hot data from memory. A cache turns a 200 ms query into a 1 ms lookup, and is the cheapest performance win available. The two hard parts are, famously, cache invalidation and naming things.
Queues and streams decouple services so a spike or a failure doesn't cascade:
- Queues — SQS, RabbitMQ. One message, one consumer, processed once. Perfect for background jobs.
- Streams — Kafka, Kinesis. An append-only log many consumers can read independently and replay. The backbone of event-driven architectures.
GCP, Azure & multi-cloud
The same primitives, different names. A translation table, and an honest take on multi-cloud hype.
Once AWS clicks, the other big clouds are the same ideas with different names — and being able to move between them makes you far more hireable.
A quick translation table:
| Concept | AWS | Google Cloud | Azure |
|---|---|---|---|
| Virtual server | EC2 | Compute Engine | Virtual Machines |
| Object storage | S3 | Cloud Storage | Blob Storage |
| Managed K8s | EKS | GKE | AKS |
| Serverless | Lambda | Cloud Functions | Functions |
| Identity | IAM | IAM | Entra ID |
GCP is loved for its networking and Kubernetes heritage (Google created K8s). Azure dominates enterprises already invested in Microsoft. You don't need to master all three — skim GCP and Azure enough to map concepts and read their docs.
"Multi-cloud" (running across providers) is sometimes reality and often hype — it adds real complexity, so it should be a deliberate choice, not a default. More common and pragmatic is picking one primary cloud and avoiding needless lock-in by preferring open tools (Kubernetes, Terraform, Postgres) over proprietary ones where it matters.
- $Design and build a two-tier VPC: load balancer in a public subnet, app and database private, across two AZs.
- $Deploy a containerised app to a managed service (ECS/Cloud Run) with least-privilege IAM roles and a billing alarm.