Terraform cidrsubnet explained

cidrsubnet is a very handy function to do subnet division in Terraform, but its official documentation looks a bit daunting. Here I will try to explain it in my words.

10.0.128.0/24 translates to the the range of 10.0.128.0 - 10.0.128.255. If we divide it into a smaller subnet, we can have something like 10.0.128.32/28, which translates to 10.0.128.32 - 10.0.128.47. The Terraform cidrsubnet call to do this is cidrsubnet("10.0.128.0/24", 4, 2).

How does work? Especially, why the third parameter is 2? Let’s break this down:

cidrsubnet step by step

Step 1: We will extend the netmask by 4. This is denoted by the second parameter. In combination, the new prefix length for this cidr block will be 28 (24+4).

Step 2: The third parameter will override the extended netmask (in step 1 it is extended and filled as 0). In our example, the parameter is 2, converting to binary it will be 10; therefore we will fill 0010 for the extended range.

Result: Recalculating the IP. The final digit now becomes 00100000. That is 32 in decimal, and we know the new prefix length is 28, so the final result is 10.0.128.32/28.

This also means the digits of the binary of the third parameter can never be greater than the second parameter. In our example, our second parameter (extended netmask length) is 4, so the maxium value for the third parameter will be 15 (whose binary is 1111). When it goes to 16 (whose binary is 10000), the extended range (red block in above picture) will not be able to hold it, hence it is not able to calculate a new CIDR block.

Here is the proof:

cidirsubnet error when exceeding the extending range

Hopefully, now when you refer back to the official documentation for the explanation of the third parameter:

netnum is a whole number that can be represented as a binary integer with no more than newbits binary digits, which will be used to populate the additional bits added to the prefix.

It makes more sense now :)