VPC structure and subnet types
A VPC lives in a single AWS region and has a CIDR block that defines its IP address space, such as 10.0.0.0/16. You divide that space into subnets, each associated with one Availability Zone. Subnets do not span AZs, so a resilient architecture places resources in subnets across multiple AZs.
Public subnets have a route to an Internet Gateway in their route table, which means resources in those subnets can send and receive traffic from the internet. Private subnets have no such route, meaning resources in them are not directly reachable from the internet. A web server that needs to accept public connections goes in a public subnet. A database that should only accept connections from the application tier goes in a private subnet.
A NAT Gateway sits in a public subnet and gives resources in private subnets a way to initiate outbound connections to the internet (to download patches, call external APIs) without being reachable inbound. NAT Gateways are managed by AWS, highly available within an AZ, and charged per hour plus per GB of data processed. For HA across AZs, deploy a NAT Gateway in each AZ and configure private subnets in each AZ to route through their local NAT Gateway.
Security groups and NACLs
Security groups are stateful instance-level firewalls. Stateful means if you allow traffic in one direction, the return traffic is automatically allowed regardless of any other rule. Security groups only have allow rules. The absence of a rule is a deny. You apply security groups to EC2 instances, RDS databases, Lambda functions in VPCs, and load balancers. A single instance can have multiple security groups applied, and the rules across all of them are combined.
Network Access Control Lists (NACLs) operate at the subnet level and are stateless. Stateless means you must explicitly allow both inbound and outbound traffic, including the return traffic on ephemeral ports (1024 to 65535 for most responses). NACLs have both allow and deny rules, processed in numbered order from lowest to highest. The first matching rule wins. NACLs are useful for blocking specific IP addresses across an entire subnet.
Think of NACLs as the outer wall around a neighborhood (subnet) and security groups as the lock on each individual house (instance). You use the wall to block unwanted visitors from the neighborhood entirely. You use the lock to control who can enter specific houses.
VPC endpoints and connectivity
Without VPC endpoints, traffic from your VPC to AWS services like S3 travels over the public internet, even though both are in AWS. This creates cost, exposure, and latency. Gateway Endpoints add a route table entry that directs traffic to S3 or DynamoDB over the AWS private network instead, at no charge. Interface Endpoints create a private IP in your VPC for almost any AWS service, so traffic never leaves the Amazon network, though they do carry an hourly fee.
VPC peering connects two VPCs so they can route traffic to each other as if they were on the same network. Peering does not require a VPN or internet access. The catch is that peering is non-transitive: if VPC A peers with VPC B and VPC B peers with VPC C, A cannot reach C through B. Transit Gateway solves this for complex multi-VPC architectures by acting as a central hub.
How to choose the correct answer
Public vs private subnet: needs inbound internet connections = public subnet. Should not be reachable from internet = private subnet. Private subnet needs internet access for updates = NAT Gateway in public subnet.
Security group vs NACL: stateful, instance-level, allow-only = security group. Stateless, subnet-level, allow and deny = NACL. Block a specific IP from entering the subnet = NACL.
Traffic to S3 without internet = Gateway Endpoint (free). Traffic to other AWS services privately = Interface Endpoint (paid). Connect two VPCs = VPC peering (non-transitive). Connect many VPCs = Transit Gateway.
Bastion host: a single hardened EC2 instance in a public subnet used as the only SSH entry point to instances in private subnets. Alternative: AWS Systems Manager Session Manager removes the need for a bastion entirely.