How cidrsubnet works in Terraform
As you might already know by using cidrsubnet you can calculate a subnet by given network address prefix in Terraform.
However if you are like me who is not that much a geek about network subnets/netmasks/CIDRs ..etc, you might feel a little bit magical when you use this function. How the hell that subnet got generated 🤔 There is an almost-good example in the documentation but I couldn’t grasp fully. Specially the netnum
part. So I spent little time to understand how this actually works and how these parameters relate to each other. If you have the same magical feeling may be this article helps you to understand how this function works.
cidrsubnet(prefix, newbits, netnum)
How it’s in the documentation.
- prefix = must be given in CIDR notation, as defined in RFC 4632 section 3.1.
- newbits = is the number of additional bits with which to extend the prefix. For example, if given a prefix ending in
/16
and anewbits
value of4
, the resulting subnet address will have length/20
. - 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.
First and second params are self-explanatory and easy to understand. However the third, yeah it went over my head too. Don’t worry little later we will go through few examples then you will understand the logic behind the netnum
and relation to prefix
and newbits
. Before that we need to know the structure of CIDR notation. Let’s have a look that first!
Understanding Network and Host portion
Take 10.1.0.0/24
as the example.
CIDR notation has 2 parts: network portion and the host portion. Let’s get the 10.1.0.0
and write it in binary and find out these 2 parts there.
Note: Counting binary is starting from right.
Our current suffix is 24
which means 24 bits
out of 32
is allocated for the network portion and remaining 8 bits
are for the host portion.
Understanding relation of params
cidrsubnet(“10.1.0.0/24”, 4, 10)
As in the function suffix needs to be extended with another 4bits(newbits)
so current network portion(/24) + newbits(4) = /28
which means we add 4 more bits to the network portion.
Before extend
After extended with 4 bits
of newbits
Definition: 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.
Would be easy to think as: an integer could represent from newbits
.
Let’s grab these newbits
and find little bit more about netnum
We have 4 newbits
, ignore current position in the octals of the CIDR, as you see below with 4 bits
possible maximum decimal value is 15 and minimum is 0.
Hmm so? It means with given parameters maximum value that you can use as netnum
is 15 and minimum is 0. Ok if i put 16 i should get error ha? Let’s try in terraform console
and check.
As you see: you can have 16 subnets(by using netnum
0–15) with /28
suffix. You can verify with ipcalc
command ipcalc 10.1.0.0/24 /28
it will show how many subnets are available. Let’s go through examples and understand how exactly these subnets get return with given parameters.
Example number one:
cidrsubnet(“10.1.0.0/24”, 4, 10)
Step 1: Binary representation with newbits.
Little explanation about below 0s and 1s.
- Current network portion (24bits before the
newbits
) - Then
newbits
(orange color bits) - Final Host portion (after orange color bits)
Step 2: Reset those newbits
to 0s, if there are any 1s, since here no 1s nothing to change.
for ex:
Step 3: Let’s represent 10(netnum
) in newbits
yes ignore current position in the octal.
Step 4: Now get the result as octals and convert to decimal(counting binary is starting from right).
Here you go, your subnet is 10.1.0.160/28
Example number two:
cidrsubnet(“10.1.0.0/24”, 4, 13)
Step 1: Binary representation with newbits.
Step 2: Let’s reset those newbits
if there are any 1s, since here no 1s nothing to change. Cool let’s move on!
Step 3: Now represent 13(netnum
) in newbits
Note: Ignore current position in the octal. We just need bits
!
Step 4: Now get the binary representation as octals and convert to decimal(counting binary is starting from right).
is it true? yes it is!
ok! this is boring give me a harder one 🤓 how about newbits
spread among 2 octals.
Example number three:
cidrsubnet(“10.121.0.0/20”, 5, 11)
Step 1: Binary representation with newbits.
Note: newbits
spreading between 2 octals.
Step 2: Let’s reset those newbits
if there are any 1s, nope nothing to change.
Step 3: Now represent 11(netnum
) in newbits
Note: Ignore current position in the octal. We just need bits
!
Cool we are getting better with this!
Last step result time: Now get the binary representation as octals and convert to decimal(counting binary is starting from right).
Last one:
cidrsubnet(“10.121.20.0/21”, 8, 14)
Step 1: Binary representation with newbits
this one is cool: spread among 2 octals and we have 1s.
Step 2: Let’s reset those newbits
if there are already 1s, yep we have a 1 here!
Step 3: Now represent 14(netnum
) in newbits
Note: Ignore current position in the octal. We just need bits
!
Now: convert octals to decimal(counting binary is starting from right).
So result is 10.121.16.112/29
great 👏🏻
Yep that was it, job done! Now hopefully you don’t feel anymore magical when you use cidrsubnet
and hope this helps to clear your confusion. Please let me know if i missed anything or i got something wrong. Thank you very much for come this far fellow human beings ✌️ Happy Terraforming!