Compute AWS VPC Subnet CIDRs in Terraform

gdenn

Dennis Groß (he/him)

Posted on December 22, 2022

Compute AWS VPC Subnet CIDRs in Terraform

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
  }
}
Enter fullscreen mode Exit fullscreen mode

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.

💖 💪 🙅 🚩
gdenn
Dennis Groß (he/him)

Posted on December 22, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

AWS IAM roles in Terraform
terraform AWS IAM roles in Terraform

December 23, 2022

Compute AWS VPC Subnet CIDRs in Terraform
terraform Compute AWS VPC Subnet CIDRs in Terraform

December 22, 2022