A well-designed Virtual Private Cloud (VPC) leverages public and private subnets to create a secure and functional network environment. Public subnets are intended for resources that require direct internet access, such as load balancers, bastion hosts, or public-facing web servers. These subnets achieve internet connectivity via an Internet Gateway (IGW) attached to the VPC. Conversely, private subnets house your sensitive application components like database servers, application servers, or internal microservices, which should never be directly exposed to the internet. This segregation is a cornerstone of secure cloud architecture, allowing you to tightly control external access based on the role of each resource.
Route tables are the traffic directors within your VPC. Every subnet must be associated with a route table, which contains rules that determine where network packets are sent based on their destination IP address. For a public subnet, its route table will typically have a default route (0.0.0.0/0) pointing to the Internet Gateway, enabling direct internet access. However, for a private subnet, direct access to the Internet Gateway is deliberately omitted. Instead, if instances within a private subnet need to initiate outbound connections to the internet (e.g., for software updates, fetching dependencies, or sending logs), their default route will point to a NAT Gateway.
A NAT Gateway (Network Address Translation Gateway) is a crucial component that allows instances in private subnets to securely access the internet for outbound connections while preventing unsolicited inbound connections from the internet. You deploy a NAT Gateway in a public subnet and it is assigned an Elastic IP address. Private subnets are then configured with a route table entry that directs all internet-bound traffic (0.0.0.0/0) to the NAT Gateway. The NAT Gateway performs network address translation, presenting its public IP address to the internet on behalf of the private instances, thereby preserving the isolation and security of your private resources.
Key Takeaways
- Public subnets provide direct internet access via an Internet Gateway for public-facing resources.
- Private subnets host sensitive resources, lacking direct internet access for enhanced security.
- Route tables define traffic flow; public subnets point default traffic to IGW, private subnets point to NAT Gateway for outbound access.
- NAT Gateways enable instances in private subnets to initiate outbound internet connections securely.
- A NAT Gateway must be deployed in a public subnet.
Code Example
resource "aws_route_table" "private_rt" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.example.id
# This route directs all outbound internet traffic from associated subnets
# through the specified NAT Gateway.
}
tags = {
Name = "Private-Subnet-Route-Table"
}
}
resource "aws_route_table_association" "private_subnet_association" {
subnet_id = aws_subnet.app_private_us_east_1a.id
route_table_id = aws_route_table.private_rt.id
# This associates the route table with a specific private subnet.
}How this code works
This code establishes the necessary routing for private subnets to access the internet securely, without exposing their instances directly. Specifically, it configures a route table to direct all outbound internet traffic from private subnets through a NAT Gateway, and then associates this route table with a designated private subnet.
The resource "aws_route_table" "private_rt" block defines a new route table. Inside its route block, the cidr_block = "0.0.0.0/0" signifies all possible internet addresses, meaning any traffic going to the internet will be routed via the nat_gateway_id. This setup allows instances within associated private subnets to initiate connections to services on the internet, such as downloading updates, while remaining protected from unsolicited inbound internet traffic.
The resource "aws_route_table_association" "private_subnet_association" then links this custom route table (private_rt) to a specific private subnet identified by aws_subnet.app_private_us_east_1a.id. This is a crucial step; a subtle point is that without such an explicit aws_route_table_association, subnets in AWS automatically receive a default route table. For private subnets, this default table typically only routes traffic within the VPC, meaning they wouldn't have internet access. This association ensures the private subnet uses the NAT Gateway for all its internet-bound communications.