Connecting VPCs
VPCs are islands by default. Here are the five bridges, peering, Transit Gateway, VPN/Direct Connect, PrivateLink, and Lattice, and exactly when to reach for each.
From your mentor
Don't memorise five services, learn the shape of each connection. Once you can picture 1:1 vs hub-spoke vs 'expose one service' vs 'service mesh', the choice makes itself.
Connecting VPCs is just picking the right bridge between two islands.
In 10 minutes you’ll know which of the five bridges to reach for. You do NOT need every route-table detail yet.
Pick your way in, same idea, 5 doors
Each VPC is its own island, nothing crosses between them by default. To connect them you build a bridge. There are five kinds of bridge, and the only trick is knowing which one fits the trip.
VPCs are isolated by design
A VPC can't reach another VPC, your office, or a partner's network unless you deliberately build a bridge. Each option below is a different shape of bridge.
In plain English
VPC Peering, the private road between two
The simplest bridge: a direct, private connection between exactly two VPCs (same or different accounts/regions).
A direct 1:1 link between two VPCs. It is NOT transitive, A reaches B and B reaches C, but A can’t reach C through B. The two CIDR ranges also can’t overlap.
The two gotchas
Peering is not transitive, each pair needs its own connection, so N VPCs need N×(N−1)/2 links (a mesh that explodes fast). And the two VPCs’ CIDR blocks can’t overlap. Great for 2–3 VPCs; painful beyond that.Transit Gateway, the central interchange
Instead of wiring every VPC to every other, attach each one once to a central hub. Everything routes through it.
A hub-and-switch in the middle. Every network attaches once to the Transit Gateway and can reach every other, it IS transitive, and scales to thousands of VPCs plus on-prem.
Nice, that’s the win
Reaching your own data centre, VPN & Direct Connect
Hybrid setups need AWS to talk to on-prem. Two ways in, trading cost for performance.
An encrypted IPsec tunnel from your data centre to AWS over the public internet, quick and cheap to set up. Need guaranteed bandwidth/low latency? Direct Connect is a dedicated private line instead (pricier, slower to provision).
| Site-to-Site VPN | Direct Connect | |
|---|---|---|
| What it is | Encrypted IPsec tunnel over the internet | A dedicated private line into AWS |
| Setup | Minutes, software config | Weeks, physical cross-connect |
| Performance | Variable (shares the internet) | Consistent, low latency, up to 100 Gbps |
| Cost | Low | Higher (port + data fees) |
| Reach for it | Quick, cheap, or backup connectivity | Heavy, steady, latency-sensitive traffic |
Often both
A common production setup uses Direct Connect for the fast path and a VPN as cheap backup, both landing on a Transit Gateway so every VPC reaches on-prem through one hub.PrivateLink, expose one service, not a network
Sometimes you don't want to join two networks at all, you just want VPC B to call one service in VPC A, privately.
Exposes ONE service privately, not whole networks. The consumer gets an interface endpoint (a private IP in their own subnet); traffic never touches the internet, and the two VPCs’ CIDRs are allowed to overlap.
Why it’s different from peering
Peering/TGW connect whole networks (and forbid overlapping CIDRs). PrivateLink exposes a single service through an interface endpoint, the consumer only reaches that one service, traffic never hits the internet, and overlapping CIDRs are fine. It’s also how you privately reach AWS services (interface VPC endpoints) without a NAT/IGW.VPC Lattice, networking by service, not IP
The newest layer: stop thinking about subnets and IPs for app-to-app traffic. Lattice connects services by name.
Service network
Connects SERVICES, not subnets or IPs. Inside a logical “service network,” services talk by name with built-in routing, auth (IAM), and observability, no peering, no CIDR planning, no sidecars.
Lattice is AWS’s managed Layer-7 service mesh (GA 2023). You put services into a logical service network; it handles discovery, request routing, IAM-based auth, and observability, across VPCs and accounts, with no peering, no CIDR planning, and no sidecar proxies.
Worth pondering
Transit Gateway, deeper: route tables & attachments
A Transit Gateway isn't just a hub, it's a router with its own route tables. Two verbs control all of it: association and propagation.
| Term | What it controls |
|---|---|
| Attachment | A connection to the TGW: VPC, VPN, Direct Connect gateway, peering, or Connect |
| Association | Which ONE TGW route table an attachment uses for traffic leaving it |
| Propagation | Which route table(s) an attachment advertises its own routes into |
| Appliance mode | Pins a flow to one AZ so a stateful inspection appliance sees both directions |
Worth pondering
Why this matters
Association + propagation is how real networks do dev/prod isolation, central egress, and traffic-inspection VPCs on a single Transit Gateway, the governance layer peering lacks.Peering edge cases that bite
Peering is simple until it isn't. Four limits cause most real-world surprises, and one of them catches almost everyone.
| Limit | What it means |
|---|---|
| No edge-to-edge routing | A peered VPC can’t use your IGW, NAT, VPN, or Direct Connect to reach the outside, peering connects the two VPCs only |
| Non-transitive | A↔B and B↔C never adds up to A↔C; each pair needs its own connection |
| No overlapping CIDRs | The two address ranges must be distinct |
| Cross-region SG references | You can reference a peer’s security group same-region (acct#/sg-id) but NOT across regions, use the CIDR there |
The edge-to-edge trap
The classic mistake: peer to a “shared services” VPC expecting to borrow its NAT or IGW for internet access. You can’t. Each VPC needs its own egress, or you centralise egress through a Transit Gateway (which can route through to a shared NAT), never through peering.PrivateLink: endpoint policies, private DNS & endpoint services
Two controls turn a raw private connection into a governed one, and one feature makes it invisible to existing clients.
| Piece | What it does |
|---|---|
| VPC endpoint policy | A resource policy on the endpoint: which principals/actions/resources may be reached through it (default: allow all) |
| Endpoint service (provider) | Your service behind an NLB; you list allowed principal ARNs and accept/reject each connection request |
| Private DNS | Makes the service’s normal DNS name resolve to the endpoint’s private IP, existing clients work unchanged |
An endpoint policy is a quiet but powerful guardrail. This S3 gateway-endpoint policy lets traffic through the endpoint reach only your bucket, blocking exfiltration to any other bucket, even if IAM alone would allow it:
{
"Statement": [{
"Effect": "Allow",
"Principal": "*",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::my-company-bucket/*"
}]
}AWS docs: control access to VPC endpointsDirect Connect: virtual interfaces & the DX Gateway
One dedicated line carries different 'virtual interfaces' depending on what you need to reach.
| VIF type | Reaches | Use it for |
|---|---|---|
| Private VIF | A VPC’s private IPs (via VGW or DX Gateway) | Direct private access to one or a few VPCs |
| Public VIF | AWS public services (S3, public endpoints) over the line | A private path to public AWS services |
| Transit VIF | Transit Gateway(s) via a Direct Connect Gateway | Many VPCs / multi-region at scale |
DX Gateway + resilience
A Direct Connect Gateway is a global object that lets one DX connection reach VPCs/TGWs in any region. A single line is a single point of failure, for production, aggregate links into a LAG and provision a second connection (ideally a second location).Which bridge, when
Match the shape of the connection to the shape of the problem.
| Option | Connects | Transitive? | Reach for it when |
|---|---|---|---|
| VPC Peering | Two whole VPCs | No | You have just 2–3 VPCs to link |
| Transit Gateway | Many VPCs + on-prem | Yes | You have many networks, replace the mesh |
| Site-to-Site VPN | On-prem ↔ AWS (internet) | Via TGW | Quick/cheap hybrid or backup link |
| Direct Connect | On-prem ↔ AWS (dedicated) | Via TGW | Heavy, steady, latency-sensitive traffic |
| PrivateLink | One service across VPCs | N/A | Expose/consume a single private service (CIDRs may overlap) |
| VPC Lattice | Services (Layer 7) | N/A | App-to-app comms without network plumbing |
How this shows up in interviews
“You have 12 VPCs that all need to talk to each other and to on-prem. How do you connect them?”
How to answer it
Reject the peering mesh out loud (it explodes), reach for Transit Gateway as the hub, then add on-prem connectivity, and mention PrivateLink/Lattice for the service-level cases.
- 1Not full-mesh peering, 12 VPCs would need 66 connections and isn’t transitive.
- 2Use a Transit Gateway as a central hub: each VPC attaches once and gets transitive routing to all the others.
- 3Bring on-prem into the same hub via Direct Connect (fast path) and/or a Site-to-Site VPN (cheap/backup).
- 4If some VPCs only need one shared service, expose it with PrivateLink instead of joining whole networks.
- 5For pure service-to-service app traffic, VPC Lattice avoids network plumbing entirely.
Green flags
- Knows peering isn’t transitive and doesn’t scale
- Reaches for Transit Gateway as the hub
- Distinguishes network-level (TGW) from service-level (PrivateLink/Lattice)
Red flags
- Proposes a full peering mesh for 12 VPCs
- Thinks peering is transitive
- Makes services public to connect them
Q.Why doesn’t VPC peering scale?
A.It’s 1:1 and non-transitive, so N VPCs need N×(N−1)/2 links, a mesh that’s unmanageable past a handful.
- Every pair must be wired explicitly, on both sides.
- Transit Gateway (hub-spoke, transitive) is the fix once you have ~4+ VPCs.
They’re checking: That you reach for a TGW hub once the mesh grows.
Q.Peering/TGW vs PrivateLink, when which?
A.Peering/TGW connect whole networks; PrivateLink exposes one service.
They’re checking: That you pick PrivateLink to expose one thing, not to join networks.
Q.VPN vs Direct Connect for on-prem?
A.VPN: fast, cheap, over the internet, variable. Direct Connect: a private line, consistent, but costlier and slow to provision.
They’re checking: That you weigh setup/cost vs performance, and mention DX + VPN for HA.
Q.What problem does VPC Lattice solve that TGW doesn’t?
A.TGW is L3 network plumbing; Lattice is L7 application networking (services by name).
They’re checking: That you separate network connectivity (TGW) from app networking (Lattice).
Your turn, peer two VPCs (free)
Creating a peering connection costs nothing (you only pay for cross-AZ/region data). Wire two VPCs together and prove routing works.
Now do it in your own account
Wire two VPCs together with peering and prove routing works. Peering itself is free, you only pay for cross-AZ/region data.
Before you start
3 to have readyYour IAM admin user from Lesson 1.
AWS CLI v2 signed in.
aws sts get-caller-identityThe VPC from Lesson 6, plus a second VPC with a non-overlapping CIDR (e.g. 10.1.0.0/16). Overlap breaks peering.
- 1
Request a peering connection between the two VPCs.
Free tierYour terminal
aws cli
AWS docs: create-vpc-peering-connection$ aws ec2 create-vpc-peering-connection --vpc-id <vpc-a> --peer-vpc-id <vpc-b>You should see: a VpcPeeringConnectionId (pcx-…) in pending-acceptance.
- 2
Accept the connection from the peer side.
Free tierYour terminal
aws cli
AWS docs: accept-vpc-peering-connection$ aws ec2 accept-vpc-peering-connection --vpc-peering-connection-id <pcx-id>You should see: the connection moves to active.
- 3
Add routes on BOTH sides: each VPC’s route table needs the other’s CIDR → the pcx.
Free tierYour terminal
aws cli
AWS docs: create-route$ aws ec2 create-route --route-table-id <rtb-a> --destination-cidr-block 10.1.0.0/16 --vpc-peering-connection-id <pcx-id>You should see: both route tables point the other CIDR at the pcx; now instances can reach across.
Both sides need the route, a missing one side is the #1 peering bug.
- 4
Optional: create an interface endpoint to reach an AWS service privately, no internet route.
Costs moneyYour terminal
aws cli
AWS docs: create-vpc-endpoint$ aws ec2 create-vpc-endpoint --vpc-id <vpc-a> --vpc-endpoint-type Interface --service-name com.amazonaws.<region>.ssmYou should see: an endpoint that privately resolves the service inside your VPC.
Interface endpoints bill hourly + per-GB, delete it after. (Gateway endpoints for S3/DynamoDB are free.)
Last step: tear it down
Once you’ve seen it work, remove everything so nothing keeps billing.
Delete the peering connection to stay tidy.
aws ec2 delete-vpc-peering-connection --vpc-peering-connection-id <pcx-id>Peering connections and routes are free to keep, but remove the routes and the extra VPC too.
Made an interface endpoint, TGW, NAT, or VPN while exploring? Those bill per hour, delete them the same day.
Next up
Next, Ship & Scale: CI/CD + Containers
The final area: getting code into AWS with a pipeline (CodeSuite), then running it on containers, ECS, Fargate, EKS, and ECR.