liveBook · Manning

Subnetwork

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

A subnet is a logically segmented portion of an IP network with its own address range.

A subnetwork, or subnet, divides a virtual private cloud (VPC) into a network segment with its own IP address range. A Terraform module that launches an AWS instance can accept a subnet ID so the caller chooses where the instance goes, rather than being limited to a default subnet. section 10.2 section 3.8

When a module only needs to use an existing network, accept a VPC ID or subnet IDs and pass them to resources. For an instance module, declare a string input named `subnet_id` and set `aws_instance.subnet_id = var.subnet_id`. Input validation can check the ID’s expected format before the value reaches the resource. section 10.2 section 3.8.2

Listing 3.33 Using input variables
resource "aws_instance" "hello_world" {
  ami           = data.aws_ami.ubuntu.id
  subnet_id     = var.subnet_id                             #1
  instance_type = var.instance_type                         #2
}

The instance resource takes its subnet from an input variable, allowing the same module to launch into different subnets. section 3.8.2

Creating subnets is a different job. A network module can take a CIDR block—the range of IP addresses it may use—and divide it with `cidrsubnet`. A two-segment design assigns one resulting range to a public subnet and the other to a private subnet. Its AWS subnet resources also specify a VPC and availability zone. 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 shows `cidrsubnet` deriving separate address ranges and `aws_subnet` placing a subnet in a VPC and availability zone. section 10.2.3

Subnet placement alone does not establish internet access. The public subnet enables public IP addresses; the private subnet disables them and uses a NAT gateway for outbound access. An internet gateway remains a responsibility of the higher-level network module. A three-segment design can add an isolated subnet without internet access. section 10.2.3

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

How deep it goes
Works through subnet input validation and a two-segment Terraform module, including address division and connectivity dependencies.
Examples
Shows an instance configured with `var.subnet_id` and modules that divide address space into public, private, and isolated subnets.
What it assumes
Introduces Terraform input variables and describes CIDR blocks as address ranges while using AWS instances and VPC IDs.
What you can do after
Build it from scratch: configure a subnet-selectable instance module or create segmented AWS subnets with Terraform.
How it connects
Connects subnets to VPCs, CIDR blocks, AWS instances, availability zones, NAT gateways, and internet gateways.

Also explained in

Compare how 5 books explain subnetwork →

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.