New CDK Bootstrap and the EKS Cluster
In the AWS CDK Version v1.25.0, the CDK team added a new bootstrap template that includes new resources like IAM Role and S3 Buckets. From the AWS CDK Documentation: > The AWS CDK supports two…
In this exercise we will look at the basics of subnets in AWS Virtual Private Cloud. We will examine CIDRs, reserved IP addresses and subnet strategies.
This is exercise 1.5 for the AWS Advanced Networking Specialty training. For an explanation and overview of all exercises, see the overview post.
The exercises are built on the assumption that you’re already familiar with the AWS basics and have achieved at least one associate level AWS certification.
Navigate to the VPC console. Contrary to previous exercises, we will not use the Launch VPC wizard this time. Instead, navigate to the “Your VPCs” section and click Create VPC.
In the next screen, hover over the (i) after the IPv4 CIDR block line.
You can choose any IP range (eg.
18.104.22.168/16 would work), but it’s advisable to stick to the RFC1918 ranges, meant for private networks. These are
The popup shows that the largest accepted range is /16 (good for 65531 addresses), and the smallest is /28 (with only 11 addresses).
The formula to calculate the maximum amount of available addresses in AWS is
2^(32 - subnet_size) - 5. For example
2^(32 - 16) - 5 = 65531. The reason we subtract five is that AWS reserves five addresses for internal use. We’ll get to the details of these reserved addresses later.
For now, choose
10.0.0.0/16 and click Create.
There is a lot of binary logic behind CIDR calculations. We will not go into all the details in this post, but two rules are important to remember:
If we look at the exact size of a CIDR (not available addresses), the formula is
2^(32 - CIDR_suffix): so a /32 CIDR has
2^(32-32) = 1 addresses, /31 has
2^(32-31) = 2 addresses, and a /30 has
2^(32-30) = 4 addresses.
Take all of this information for granted and accept that any CIDR fits two CIDRs with a suffix that is one higher.
If we would add one single subnet in our VPC, we could make it as large as /16 (the size of the VPC). Let’s try this now. Navigate to the Subnets section of the VPC console and click the “Create subnet” button.
Fill in the following details, which will let the subnet fill the entire VPC space:
Then select the subnet, and look at the Description tab at the bottom. As you can see, it says there are 65531 available addresses.
Amazon reserves five addresses in every subnet:
In our example subnet of
10.0.0.0/16, these would translate to:
Every address between 10.0.0.3 and 10.0.255.255 can be used for resources, which corresponds with the 65531 mentioned earlier.
In an example subnet with a CIDR of
10.0.0.0/28, the reserved addresses would be:
The eleven addresses 10.0.0.4 - 10.0.0.14 are free to use.
In our previous example we deployed one single subnet. Because it uses the entire VPC CIDR, we can’t deploy any additional subnets.
Subnets are always limited to a single availability zone. Because best practice would be to deploy resources in at least three availability zones, a single big subnet is not the best idea.
Let’s delete the big subnet and replace it with three smaller ones. Configure the small ones like this:
For AZ 1b, use CIDR block
10.0.64.0/18, and for AZ 1c use
Remember from earlier in this post that a /16 fits two /17’s? By extension, a /16 fits four /18’s. Because we need at least three subnets, the largest subnet size we can use is a /18.
Each of these subnets has
2^(32 - 18) = 16384 available addresses, which is quite acceptable. However, the CIDR
10.0.192.0/18 is now unused, leading to 16384 unusable addresses. To visualize this:
Because every subnet has 5 reserved addresses, the total amount of available addresses is now
3 * (2^(32 - 18) - 5) = 49137
However, it’s unlikely we will be using only public subnets. Good cloud native design requires us to have public resources (like load balancers) and private resources (like databases and web servers).
To achieve this, we could equally split the environment in six subnets (three public and three private).
The amount of available addresses would now be
6 * (2^(32 - 19) - 5) = 49122, which is comparable to what we previously had.
In this design, all public resources (think NAT gateways, load balancers, bastion hosts and so on) would share the same public subnets. The same goes for the private resources like databases, webservers, EMR workers and so on).
Because an environment is likely to have more private resources than public resources, this could lead to over-utilized private subnets and under-utilized public subnets.
That’s why there is a third alternative.
You could also split your VPC in a CIDRs per service. For example, split your /16 into 32 ‘virtual’ CIDRs of /21 each. This gives you blocks with 2048 addresses per service, which is enough for most use cases. For example:
In the table above, we haven’t yet taken availability zones into account. Because we need three zones, we will need to split every /21 into four /23 CIDRs. The result would be something like this:
Every subnet would have
(2^(32 - 23) - 5) = 507 addresses available. This would be enough for most use cases, but for some workloads this might not be the best design and you would need to fiddle with the CIDR sizing.
In this exercise we’ve created VPC with a number of subnets in different sizes. We’ve seen that choosing a larger size subnets impacts your flexibility. Smaller subnets provide a lot more flexibility, but naturally limit the amount of resources you can deploy in a subnet.
Because Amazon reserves five IP addresses per subnet, more subnets also lead to more overhead.