By Wolfgang Unger
February 2024 AWS started to charge not only unused IP addresses but by now all public IP Adresses.
Together with the NAT costs, which have increased also a lot over the years, a VPC is now a
considerable cost factor especially for small workloads.
If you run 180 microservices and 30 databases, it does not matter so much, but for customers running
one or two fargate services or elastic beanstalk apps, the VPCs costs will increase your aws bill considerably.
It's time to rethink how we setup a VPC under cost considerations.
Also we should also consider of using IPv6 in the near future.
Why setting up your own VPC?
As you might already know, it is best practice, not to use the default VPC in your region, but instead
create your own VPC together with your other resources with IaC.
There are some reasons to do so.
First, the default VPCs differ from region to region and the number of AZs in the region.
US east got 6 AZs and therefore 6 subnets, most regions have 3 AZs and therefore 3 subnets, some regions have only 2 AZs and 2 subnets.
If you setup your infrastructure based on the us-east-1 region with 6 subnets, you might have problem, when are
expanding your business and you want
to setup your resources in a region with less subnets, because some of your Templates expect 6 of them
You VPCs should always be the same for your environments, even in different regions, this keeps it much easier.
Second, the default VPC is not under your control.
AWS makes changes, which might affect your services.
When I started long time ago on AWS, the default VPCs used to have 3 public subnets and 3 private subnets.
The private subnets are gone by now, so only this change would have made a massive impact on your infrastructure.
VPC Design Considerations
With the latest changes from AWS we have to design our VPC under cost considerations.
10 years ago, I would create a VPC with 3 Availability Zones and Subnets, 3 public and 3 private subnets.
Most public available CloudFormation Example Templates also used to have this setup.
The private subnets need a NAT Gatway to communicate with the Internet, here you have 2 options.
One NAT for the 3 private subnets, which is sufficient, but not high available.
If the AZ from the NAT fails, the other 2 subnets will no longer be able to communicate with the internet.
Therefore best practice was to use a NAT in each Subnet, which is a high availability solution.
I used to setup VPCs this way.
But today, in 2024, this will be a expensive setup.
One NAT will cost you about 30$ a month, so for 3 NATs you pay about 90$ for the NATS, with much traffic even more.
NAT Gatways are charged for NAT Gateway Hourly Charge, NAT Gateway Data Processing Charge and Data Transfer Charge.
The IP address for the NAT will cost you about 20$ a month, for 3 of them you pay 60$ .
So you will have costs of about 150$ a month just for your VPC ( 3 public, 3 private subnets, high availability), even
before you have launched the first EC2 instance, RDS or another service.
Lets say you have 4 stages, Dev, Int, QA and Prod, you will have 4 x 150$ just VPC costs.
VPC Design 2024
Keeping costs in mind, we should ask ourselves, do we really need 3 AZs and subnets?
2 would be fine for high availability. 3 even better, but dispensable for smaller workloads.
So a VPC with 2 public and 2 private subnets.
Still you have to decide, if you want a NAT in each AZ or only one, but by now, at least
you will only double the costs.
If you can accept the small risk of a AZ failure, you can go for one NAT for both private subnets.
Talking about the CIDR Range you can create a /16 VPC.
No reason to use a smaller subnet mask, the CIDR range will not increase costs.
Better to have sufficient IP addresses, maybe you need them one day.
With 2 public and 2 private subnets, each subnet can the have a /18 CIDR range.
With 3 AZs and Subnets you always lose 25% of the available IP addresses, by the way.
If you create you VPC with IaC, no matter of CloudFormation, Terraform or CDK, you normally
want to be able to define the CIDR range as a parameter.
You can define the whole CIDR range as parameter or what I normally do, the classB value, the 2nd number of the IP range as parameter.
So your VPC would be (10.XXX.0.0/16) and by parameter you can set the second value different for your stages or customer environments.
With the new costs on IP addresses and also the NAT costs, we should rethink how to setup a VPC.
2 AZs and 2 private/public subnets is a perfect setup for smaller workloads.
Use 1 NAT if you want to go for less costs and are willing to accept the really small chance of a AZ failure.
For high availability with 2 Subnets you have at least only 2 NATs and not 3 to pay for.
The costs on IP addresses are also a way of AWS to push more the usage of IPv6.
Time to see IPv6 as an option.
IPv6 does not need Network Address Translation and due to the much higer number of IP addresses, there are
no costs on them neither.
In IPv6 there are no public or private IP addresses, just IP addresses and enough of it.
Unfortunatelly the adaption of IPv6 is still not yet so much advanced as it should be.
Just take a look in this table on the support for IPv6 only:
But for sure, IPv6 VPCs will be more relevant by now much faster.
And we should get familiar how to set ip up and use it.
Take a look into this blog for a introduction and how to setup a IPv6 VPC.
VPC IPv6 Introduction
Take also a look into this blog for how to run EC2 instances with IPv6.
VPC IPv6 - Running EC2 instances
This blog for how to run Fargate with IPv6.
VPC IPv6 - Running Fargate
Take also a look in my Github Repo for IPv6.
The repo (under construction) is :
Wolfgang Unger - AWS IPv6
This is also an interesting blog from AWS Community Builder Eyal Estrin
Is the Public Cloud Ready for IPv6?