Compute AWS VPC Subnet CIDRs in Terraform
Dennis Groß (he/him)
Posted on December 22, 2022
Subnetting is the process of dividing a larger network CIDR e.g. 10.0.0.0/16
into smaller subnets e.g. 10.0.1.0/24
, 10.0.2.0/24
.
A CIDR consists of two parts
- the host part of the CIDR
- the subnet mask part of the CIDR
The subnet mask is the /16
value behind the CIDR IP and determines how many bits of the IP are host part. The /16
is a short notation for the bit mask 255.255.0.0
which is another short notation for 11111111.11111111.00000000.00000000
Do a logical and with the CIDR IP to find the host part, in our case it is the first half of the IP which determines the stable part of the subnet range. The second half of the IP is a wildcard and refers to the dynamic part of our CIDR IP.
This means that our network defined through 10.0.0.0/16
spans the network 10.0.0.0
- 10.0.255.255
which is around ~65k IPs.
So the network mask determines the amount of IPs spanned over the network. A higher subnet mask refers to a smaller network size.
Subnetting in Terraform
Subnetting is the process of breaking a larger CIDR range down to a smaller subnet CIDRS. E.g. we have a network CIDR 10.0.0.0/16
and break it down to multiple subnets 10.0.0.0/24
, 10.0.1.0/24
This is often necessary for the context of e.g. VPCs in AWS or other cloud providers.
Terraform offers a function called cidrsubnet
that makes it possible to calculate subnets based on the
- base CIDR - network CIDR that we divide into subnets
- netnum - Offset that we use for the subnet
- newbits - base CIDR net mask + newbits determines new subnet mask for subnet
resource "aws_subnet" "subnet_computing" {
vpc_id = aws_vpc.main.id
map_public_ip_on_launch = false
count = local.azs_count
cidr_block = cidrsubnet(var.cidr, var.cidr_offset, count.index + local.computing_offset)
availability_zone = element(var.availability_zones, count.index)
tags = {
Name = "${var.vpc_name}-subnet-computing-${count.index}"
Environment = var.environment
}
}
The example above uses the VPC cidr var.cidr
e.g. 10.0.0.0/16
and adds the newbits netmask offset to it 16 + 8 = 24
which results in the new subnet bit mask /24
Finally, we add the netnum which is the current index count.index
+ the offset local.computing_offset
that we already used to compute subnet CIDRs for other AWS VPC subnets.
The result is a subnet CIDR e.g. 10.0.12.0/24
that we use for the VPC subnet.
Using the Terraform cidrsubnet
function makes it obsolete to define lists of subnet CIDRs ranges for each subnet that you want to create. You just have to define a base network CIDR range and an newbits value.
Posted on December 22, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.