Working with the cidrsubnets function in Terraform is a bit of a pain – but it’s so extremely handy for automated networking that it’s worth spending the time to figure it out. Suffice to say, I am not going to dig deep on how to use cidrsubnets; rather I am going to bring up a really handy and (as far as I can tell) “not documented” method for supplying a list of “newbits” values to this function.
Cidrsubnets has the following usage:
An example would be like this (all stolen from the Hashi documentation):
[
"10.1.0.0/20",
"10.1.16.0/20",
"10.1.32.0/24",
"10.1.48.0/20",
]
I was creating a re-usable “quick networking” module and was using this function to do subnetting for me. I wanted to allow the module end-user to be able to supply a list of “newbits” as a variable input into my module. So the module call would look something like this:
source = "../.."
vnet = "10.25.0.0/16"
subnets = [8,8]
}
The module itself (this is for Azure) would take that information (and some other stuff) and create a virtual network and however many subnets at the sizes specified in the input. Seemed like a great idea. Inside my module code I tried this:
subnet_list = cidrsubnets(var.vnet, var.subnets)
}
Which (following the above examples) should have resulted in something like this happening…
[
"10.25.0.0/24",
"10.25.1.0/24"
]
This doesn’t work. The cidrsubnets function won’t take a list input like that and I tried all manner of nonsense like these (non-working code examples):
subnet_list = cidrsubnets(var.vnet, var.subnets[*])
}
subnet_list = cidrsubnets(var.vnet, join("," , var.subnet_cidrs))
}
–and things just got more profane from here–
However, somewhere on the internet, probably in a random Stack Overflow post, someone posted the below syntax – which does work (I stumbled across this months ago and failed to document it, no idea where I found it…):
subnet_list = cidrsubnets(var.vnet, var.subnets[*]...)
}
Note the triple dot notation “…” after the splat.
And just for the sake of completeness – here is a fully working local example:
vnet = "10.30.0.0/16"
subnets = [4,3,8]
subnet_list = cidrsubnets(local.vnet, local.subnets[*]...)
}
output "subnet_list" {
value = local.subnet_list
}
I have been looking through Hashi’s documentation and I can’t find that “[*]…” syntax – if you are reading this article and happen to know if and where it is documented, please respond and post the link. Better yet, tell me if there is a simpler way. For the time being, all I can say is that the above works in the cidersubnets function and it’s not nearly as ugly as some of the other things I attempted.