liveBook · Manning

Private subnet

As explained in Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu

A private subnet is a subnet whose resources are not directly reachable from the public internet.

Suppose an application has an API container, database, cache, and internet-facing load balancer. Put the load balancer in a public subnet, but keep the API, database, and cache in a private subnet: those services should not be directly reachable from the internet. section 10.2.2

A private subnet can still give its resources outbound internet access. In a two-segment network, a NAT gateway sits in the public subnet, and a route sends internet-bound traffic from the private subnet through it. This does not make the private subnet directly reachable from the internet. section 10.2.2 section 10.2.3

Define the two subnets with Terraform

Pass a CIDR block, VPC ID, and availability zone to the network module. Use `cidrsubnet(var.cidr_block, 1, 0)` for the private subnet and `cidrsubnet(var.cidr_block, 1, 1)` for the public subnet. Configure the private subnet without public IP addresses on launch; place the NAT gateway in the public subnet. section 10.2.3

Listing 10.6 Public and private subnet module
variable "cidr_block" {
  description = "The CIDR block for the network."
  type        = string
}
 
variable "vpc_id" {
  description = "The ID of the VPC."
  type        = string
}
 
variable "availability_zone" {
  description = "The availability zone."
  type        = string
}
 
locals {
  private_subnet_cidr_block = cidrsubnet(var.cidr_block, 1, 0) #1
  public_subnet_cidr_block  = cidrsubnet(var.cidr_block, 1, 1) #1
}
 
 
#
# Public Network
#
 
resource "aws_subnet" "public" {
  vpc_id                  = var.vpc_id
  cidr_block              = local.public_subnet_cidr_block     #2
  map_public_ip_on_launch = true                               #3
  availability_zone       = var.availability_zone
  tags = {
    Network = "Public"                                         #4
  }
}
 
resource "aws_eip" "nat" {
  tags = {}
}
 
resource "aws_nat_gateway" "main" {                            #5
  allocation_id = aws_eip.nat.id                               #6
  subnet_id     = aws_subnet.public.id                         #7
  tags          = {}
}
 
 
#
# Private Network
#
 
resource "aws_subnet" "private" {                              #8
  vpc_id            = var.vpc_id
  cidr_block        = local.private_subnet_cidr_block          #9
  availability_zone = var.availability_zone                    #10
  tags = {
    Network = "Private"
  }
}
 
resource "aws_route_table" "private" {                         #11
  vpc_id = var.vpc_id
}
 
resource "aws_route_table_association" "private" {             #12
  subnet_id      = aws_subnet.private.id
  route_table_id = aws_route_table.private.id
}
 
resource "aws_route" "internet_access" {                       #13
  route_table_id         = aws_route_table.private.id
  nat_gateway_id         = aws_nat_gateway.main.id
  destination_cidr_block = "0.0.0.0/0"                         #14
}
 
output "private_subnet_id" {                                   #15
  value = aws_subnet.private.id
}
 
output "public_subnet_id" {                                    #16
  value = aws_subnet.public.id
}

The two-segment module listing shows how one supplied CIDR block becomes separate public and private subnet ranges. section 10.2.3

Choose an isolated subnet instead when a network must have no internet access; unlike the private subnet, it needs no NAT route. For availability across locations, create a network with the chosen topology in each location. NAT gateways are straightforward to configure but can be expensive. section 10.2.2 section 10.2.3

How Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu covers it

How deep it goes
Works through CIDR division, public-IP settings, NAT placement, and outbound routing in a Terraform subnet module.
Examples
Uses an API container, database, cache, and load balancer, alongside a Terraform public-and-private-subnet module.
What it assumes
Defines the module inputs as a CIDR block, VPC ID, and availability zone, then demonstrates dividing the CIDR block.
What you can do after
Build it from scratch with Terraform: divide a supplied CIDR block and configure private-subnet outbound access through NAT.
How it connects
Connects private subnets to public subnets, NAT gateways, route tables, isolated subnets, and availability zones.

Also explained in

Compare how 2 books explain private subnet →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu. The section links point to the parts of the book it draws on.