Creating new subnets (and other network components) within an existing VPC is the primary function of this terraform module. This is in contrast to the VPC Network terraform module that does a similar job but creates its own VPC housing.
The first question is why? Before jumping into the how - let's uncover common use cases that would require you to setup infrastructure within an existing VPC.
Why would you want to set out your (subnet) stalls within an existing VPC? The common use cases are
- to place performance test infrastructure within an application's VPC
- to setup a bastion EC2 instance in an existing VPC for troubleshooting
- to setup a green environment for blue/green deployments
- to reuse NAT gateways that are associated with mandated public elastic IP addresses
- when you are not allowed to create new VPCs
That's the why! Now Let's get to grips with how subnets sub-divide an address space and learn how to side-step the dreaded subnet address overlap issue.
Your primary concern here is to avoid a subnet address overlap scenario. The existing VPC will likely have subnets that have reserved and/or issued a certain number of IP addresses.
This module is going to create a new subnet network within wthe auspices of an existing VPC. To do its work, you'll need to provide it with a handful of important input variables which are
- the VPC cidr block (like 10.42.0.0/20) defines the entire VPC allocable address range
- the VPC cidr integer comes after the Cidr Block slash so is 20 if the cidr block is 10.42.0.0/20
- the subnets max integer specifies maximum number of carvable subnets. A formula for deriving it from the number of allocable addresses per subnet and the VPC Cidr integer is given below.
- a subnet offset count that says these n subnets have already been allocated - skip them
- terraform's cidrsubnet function that does the addressing math
You! - know the subnets that have already been created and this module does not attempt to work things out for itself. It takes your inputs as read and gets on with the job of carving out extra subnets in an existing vpc.
The above 3 variables must be provided along with the ID of the existing VPC. The sensible defaults mantra that held sway when a fresh VPC was being created, ceases to apply.
That said, all other inputs and behaviour run along the same lines as in the VPC network sister module.
module sub-network
{
source = "github.com/devops4me/terraform-aws-sub-network"
in_vpc_id = var.in_vpc_id
in_vpc_cidr = var.in_vpc_cidr
in_internet_gateway_id = var.in_internet_gateway_id
in_subnets_max = var.in_subnets_max
in_subnet_offset = var.in_subnet_offset
in_num_public_subnets = 2
in_num_private_subnets = 0
}
Input Variable | Type | Description | Default |
---|---|---|---|
in_vpc_id | String | The ID of the VPC to create subnet networks within. | vpc-123456789 |
in_vpc_cidr | String | The VPC's Cidr defining the range of available IP addresses | 10.42.0.0/16 |
in_subnets_max | Integer | 2 to the power of this integer is the maximum number of carvable subnets. How do we reverse engineer this value? See the section below this table. | 4 (16 subnets) |
in_subnet_offset | Integer | The number of subnets to skip over which is usually the number of existing subnets. If 16 is the maximum number of subnets, the offset must an integer from 0 to 15. This offset plus the number of subnets to create cannot exceed the number of carvable subnets. | mandatory |
in_num_private_subnets | Integer | Number of private subnets to create across availability zones | 3 |
in_num_public_subnets | Integer | Number of public subnets to create across availability zones. If one or more an internet gateway and route to the internet will be created regardless of the value of the in_create_gateway boolean variable. | 3 |
in_create_gateway | Boolean | If set to true an internet gateway and route will be created even when no public subnets are requested. | false |
in_ecosystem | String | the class name of the ecosystem being built here | eco-system |
It's easy to find the VPC ID, the VPC Cidr and the (internet or NAT) gateway IDs. That said, deriving two of the above values, needs further explanation. Those two values are
- the subnets offset
- the subnets max
To be blunt - we are gatecrashing an existing VPC. If subnets were market stalls, we are turning up and setting up some more market stalls. We can't set them up over the stalls that already exist, hence the offset.
The number of existing subnets plus the number of required subnets must not exceed the maximum number of allocable subnets.
- with 8 allocable subnets and
- 6 existing subnets (subnet offset of 6)
- you can only create 2 subnets
This terraform module will fail durin the apply unless this constraint is respected.
A subnet_max of 8 means you can have a maximum of 28 (256) subnets. 4 means your VPC can hold at most 16 subnets.When creating a network within an existing VPC you need to reverse engineer and provide the correct subnet max value to avoid overlap.
To reverse engineer this value go to the AWS Console and
- note the trailing Cidr integer on the IPV4 Cidr column on the VPC page ( 20 if the cidr block is 10.42.0.0/20 )
- note the Available IPv4 column on the subnet page against your VPC.
- increase the available IPv4 count until you arrive at the next power of 2
The subnet_address_power is the integer power of 2 that you got after increasing the available ipv4 count.
IPv4 Count | Next 2 Power | 2subnet address power | subnet address power | VPC Cidr Block | VPC Cidr Int | Formula | Subnet Max |
---|---|---|---|---|---|---|---|
250 | 256 | 28 | 8 | 10.222.0.0/16 | 16 | 32-(16+8) | 8 |
4087 | 4096 | 212 | 12 | 10.111.0.0/16 | 16 | 32-(16+12) | 4 |
A common error is to read the IPV4 Cidr from the subnets screen - don't! Read it from the VPC screen otherwise you are getting the Subnet's Cidr block which is not the same as the VPC's Cidr block.
The fundamentals of vpc and subnet design boils down to asking (and answering) 3 golden questions.
- how many addresses can a VPC issue?
- how many subnets can be carved out of a VPC?
- how many addresses can a subnet issue?
Use the below discussion to answer the 3 golden questions. Once you get the gist, you know the arithmetic that underpins VPC and subnet design.
The subnet max can combine with the VPC Cidr to define the number of addresses available in each subnet's pool.
A vpc_cidr of 21 (eg 10.42.0.0/21) and subnets_max of 5 gives a pool of 232-(21+5) = 64 addresses in each subnet. (Note it is actually 2 less). We can carve out 25 = 32 subnets as in_subnets_max is 5.
vpc cidr | subnets max | number of addresses per subnet | max subnets | vpc addresses total |
---|---|---|---|---|
/16 | 6 | 232-(16+6) = 210 = 1024 addresses | 26 = 64 subnets | 232-16 = 65,536 addresses |
/16 | 4 | 232-(16+4) = 212 = 4096 addresses | 24 = 16 subnets | 232-16 = 65,536 addresses |
/20 | 8 | 232-(20+8) = 24 = 16 addresses | 28 = 256 subnets | 232-20 = 4,096 addresses |
/20 | 2 | 232-(20+2) = 210 = 1024 addresses | 22 = 4 subnets | 232-20 = 4,096 addresses |
Check the below formula holds true for every row in the above table.
addresses per subnet * number of subnets = total available VPC addresses