Cidrsubnets - generate list of all subnets

Hi!

I have a root cidr 10.48.0.0/12 - that I’m looking to populate all 256 /20 subnets from, into a list.

Given the code, below - can all_subnets be populated in a more efficient way, without specifying 8, 256 times ?

locals {
  max_subnets = 256
  all_subnets = cidrsubnets("10.48.0.0/12", 8, 8, 8..)
}

Hi @edwdev,

The cidrsubnets function is primarily intended for packing various differently-sized subnets into a single prefix, as the hashicorp/subnets/cidr module does.

Since you wish to allocate evenly-sized subnets I think it would be simpler to use the cidrsubnet function (note: singular) along with other constructs in the Terraform language.

locals {
  subnet_count = 256 # NOTE: Must be a power of two
  newbits      = log(local.subnet_count, 2)

  all_subnets = tolist([
    for i in range(local.subnet_count) :
    cidrsubnet("10.48.0.0/12", local.newbits, i)
  ])
}

This should result in a local.all_subnets that’s a list with local.subnet_count elements where each element is one CIDR address with a network number corresponding to its index.

Using the log function to calculate the number of new bits required for 256 addresses isn’t necessary if you don’t actually plan to ever vary the subnet count, but since you showed it as a separate variable in your example I wondered if perhaps you intended that to be a configurable variable in your real system, and would thus need to dynamically select an appropriate newbits value based on it.

If so, you could in principle represent that “must be a power of two” rule as a custom validation rule against a variable:

variable "subnet_count" {
  type = number

  validation {
    condition     = floor(log(var.subnet_count, 2)) == log(var.subnet_count, 2)
    error_message = "Subnet count must be a power of two."
  }
}

…and then use var.subnet_count instead of local.subnet_count in the example above.

1 Like