Week 4

VPC - An analogy about shared resources

Public subnets and Internet Gateway

Private subnets and NAT

Endpoints and Security Groups

Putting it all together

Load balancing - one front door, many clerks

Auto Scaling

Architecture and Tradeoffs

Practice

Assignment

Cloud Track

Under construction

<aside> 🚧

This page is currently under construction. Please check back later.

</aside>

<aside> 🧱

The full picture — recap

You have now built every layer of the week's architecture yourself, one section at a time. This page puts the three sections back together into a single diagram, walks a real request through it end to end, and gives you a checklist to tear it all down before it costs you money.

Nothing new is introduced here. If something below feels unfamiliar, that is a signal to go back to the section that built it.

</aside>


The architecture you built

Read it once more, now that every box means something to you:

Where What lives there Route table Reachable from
Public subnet — AZ A
10.0.1.0/24 hyf-web, hyf-bastion, Internet Gateway, NAT Gateway 0.0.0.0/0 → IGW the internet
Private subnet — AZ A
10.0.2.0/24 hyf-app 0.0.0.0/0 → NAT hyf-web (and hyf-bastion, port 22 only)
Private subnet — AZ B
10.0.3.0/24 hyf-db • S3 gateway endpoint on its route table local, plus a prefix-list route to S3 hyf-app (and hyf-bastion, port 22 only)

Three subnets, three route tables, four security groups, and one rule that ties the whole thing together: each tier accepts traffic only from the tier directly above it — with a single bastion as the one way in for a human being.

Follow a request through the whole thing

Inbound: a user loads your site

  1. A browser resolves your web server's public IP and sends a packet to it on port 80.
  2. The packet arrives at the Internet Gateway attached to hyf-week4-vpc, which translates the public IP to hyf-web's private IP 10.0.1.x.
  3. hyf-web-sg is checked: TCP 80 from 0.0.0.0/0 is allowed. The packet is delivered.
  4. Your web server needs data, so it calls the API at 10.0.2.x:3000. The route table finds this inside 10.0.0.0/16 → the local route keeps it inside the VPC.
  5. hyf-app-sg is checked: TCP 3000 from hyf-web-sg is allowed, and the caller is wearing that badge. Delivered.
  6. The app queries the database at 10.0.3.x:5432. Same local route — this hop crosses from AZ A to AZ B and needs no gateway to do it.
  7. hyf-db-sg is checked: TCP 5432 from hyf-app-sg is allowed. Delivered.
  8. Every reply travels back without a single extra rule, because security groups are stateful.

<aside> 💭

Count the ways an attacker who owns hyf-web is still stuck. They cannot reach hyf-db — no security group rule matches them. They cannot reach the internet from hyf-db even if they got there — the only route out of that subnet leads to S3. And nothing outside can address hyf-app or hyf-db at all — no public IPs. That layering is the point of the whole week.

</aside>

Outbound: hyf-app runs apt update

  1. hyf-app sends a packet to a public repository address. Not inside 10.0.0.0/16, so the local route does not match.
  2. hyf-week4-private-rt-a matches 0.0.0.0/0 → NAT Gateway.
  3. The NAT Gateway (sitting in the public subnet, holding an Elastic IP) rewrites the source address to its own and forwards the packet to the Internet Gateway.
  4. The reply comes back to the NAT Gateway, which remembers the translation and returns it to hyf-app.
  5. Nothing on the internet can use this path in reverse — a NAT Gateway only forwards connections that started inside.

Admin: you open a shell on hyf-db

  1. You SSH to hyf-bastion's public IP. It sits in the public subnet, so the Internet Gateway delivers the packet, and hyf-bastion-sg allows TCP 22 from your address and no other.
  2. From there, SSH continues to 10.0.3.x. That address is inside 10.0.0.0/16, so the local route carries it — across the AZ boundary, with no gateway involved.
  3. hyf-db-sg allows TCP 22 from hyf-bastion-sg, and the caller is wearing that badge. You have a shell on a machine with no public IP and no route to the internet.
  4. With ssh -J, your private key never touches the bastion — it only forwards the encrypted tunnel.

Outbound: hyf-db pushes a backup to S3

  1. hyf-db sends a packet to s3.eu-central-1.amazonaws.com, which resolves to a public S3 address — a gateway endpoint changes routing, not DNS.
  2. hyf-week4-private-rt-b has no 0.0.0.0/0 route, but it does have one whose destination is the S3 prefix list. That route matches.
  3. Its target is the gateway endpoint, so the packet reaches S3 with no IGW, no NAT Gateway and no public IP anywhere in the path.
  4. Anything else outbound — curl https://example.com — matches no route at all, and times out. One door, one service.

Why each choice was made

Decision Reason What breaks without it
Web server in a public subnet It is the only tier users must reach directly Nobody can load your site
App server in a private subnet, same AZ Business logic should not be internet-addressable; same AZ avoids cross-AZ hops and charges for NAT traffic Your API is exposed to the whole internet
NAT Gateway in the public subnet It needs its own route to the IGW to work Nothing outbound works; the NAT is useless
Database in a second AZ Survives the loss of a whole data centre One AZ failure takes your data offline
Database subnet with no 0.0.0.0/0 route Data has no business calling the internet A compromised database can exfiltrate data outbound
An S3 gateway endpoint instead of a NAT route for the DB subnet Grants exactly one AWS service, not the whole internet — and a gateway endpoint is free You either give up backups, or reopen the internet to your data
A single bastion as the only way in One machine to guard, one rule in the VPC that mentions the internet, and it works even for a subnet with no route out Either every tier needs its own SSH rule, or private instances cannot be administered at all
Security groups referencing other security groups Rules survive instance replacement and IP changes Hardcoded IPs break on every redeploy

When it does not work

Almost every VPC problem is one of five things. Work down the list in order — it is roughly the order of how often each is the culprit.

  1. No public IP. A public subnet does not hand out public IPs by itself. Check Auto-assign public IP on the instance.
  2. Route table not associated. You edited the right route table but never ticked the subnet, so the subnet is silently still using the main route table.
  3. Security group too narrow. A timeout points here. Check the destination's inbound rules, not the source's outbound.
  4. Nothing listening. Connection refused points here instead — the packet arrived fine, no process is on that port.
  5. NAT Gateway in the wrong subnet. If it is in a private subnet it has no route out, and everything downstream of it silently fails.

<aside> 💡

When you are properly stuck, use VPC Reachability Analyzer (VPC console → Reachability Analyzer). You give it a source and a destination, and it tells you exactly which route table, security group or NACL is blocking the path. It is the fastest way to stop guessing.

</aside>

Check yourself

Answer these before moving on. Try to answer out loud first, then open the toggle.

Clean up before you leave

<aside> 💰

</aside>

<aside> 💡

</aside>

What comes next

This architecture has one obvious weakness left: a single web server, in a single Availability Zone. If it dies, or if traffic doubles, you have no answer.

That is exactly what Load Balancing and Scaling — the second topic of this week — solves, and it is why the diagram was drawn with an empty slot in front of the web tier. The pieces you will add there (an Application Load Balancer spanning both AZs, and an Auto Scaling group behind it) all plug into the subnets and security groups you just built.