Controlling traffic flow in a VPC
Three mechanisms control traffic in a VPC, and they answer different questions.
- Route tables decide where traffic is sent.
- Security groups decide whether traffic is allowed, at the network interface.
- Network ACLs decide whether traffic is allowed, at the subnet boundary.
A packet needs a route and permission from both firewalls. Route tables cannot deny anything, and security groups and network ACLs cannot redirect anything.
Association
Section titled “Association”Network ACLs and route tables are both associated with subnets, and independently of each other. There is no relationship between a subnet’s network ACL and its route table.
- A subnet has exactly one network ACL and exactly one route table at any time.
- One network ACL can be associated with many subnets; so can one route table.
- If a subnet is not explicitly associated with a route table, it uses the VPC’s main route table.
Security groups and network ACLs
Section titled “Security groups and network ACLs”| Security group | Network ACL | |
|---|---|---|
| Applies at | The network interface (an instance, load balancer, RDS instance, endpoint) | The subnet boundary |
| State | Stateful — return traffic is allowed automatically | Stateless — return traffic needs its own rule |
| Rule types | Allow only | Allow and deny |
| Evaluation | All rules are evaluated; if any allows the traffic, it is allowed | Rules are evaluated in number order, lowest first, and the first match wins |
| Sources | IP ranges, prefix lists, or another security group | IP ranges only |
| Default | Denies all inbound, allows all outbound | The default network ACL allows all inbound and outbound |
| Ephemeral ports | Handled automatically | Must be allowed explicitly in the return direction |
| Change propagation | Immediate | Immediate, but existing connections are evaluated per packet, so an in-flight connection can be cut |
Two consequences worth stating plainly:
Statelessness is where network ACLs catch people out. An inbound allow on port 443 is not enough — the response leaves from port 443 to the client’s ephemeral port, and needs an outbound rule. Because the client’s port varies, that generally means allowing 1024–65535 outbound.
Referencing a security group is why security groups scale. A rule allowing the application tier’s security group as the source stays correct as instances come and go, where an IP-range rule does not.
Use both. Security groups carry the day-to-day policy; network ACLs give a coarse subnet-level backstop and are the only place a deny can be expressed — which is how you block a specific address range.
The default network ACL
Section titled “The default network ACL”Creating a VPC creates a default network ACL that allows all inbound and outbound traffic, associated with every subnet until you create custom ACLs and associate them explicitly. A network ACL created by hand, by contrast, denies everything until rules are added.
Network ACLs have no IP address of their own. They are filters at the subnet boundary, evaluating traffic by address, protocol and port.
Routing between VPCs
Section titled “Routing between VPCs”A route table cannot point at an IP address in another VPC. Routes resolve within the VPC, and a target such as 10.1.0.0/16 → 10.2.0.5 is not valid. Reaching another VPC means routing to a construct that connects them:
VPC peering
10.1.0.0/16 → pcx-0123456789abcdef0Transit gateway — note the target is the gateway, not the attachment:
10.1.0.0/16 → tgw-0123456789abcdef0Virtual private gateway, for a Site-to-Site VPN or a Direct Connect private virtual interface:
10.1.0.0/16 → vgw-0123456789abcdef0A NAT gateway is not in this list. It handles outbound traffic to the internet or, as a private NAT gateway, to another network via a transit gateway or virtual private gateway — it is not a way to reach a peered VPC.