keep getting the following error while I try to create a subnet using terraform. No issues creating subnet using aws console. Could someone help me?
Error: error creating subnet: InvalidSubnet.Range: The CIDR '10.2.0.128/26' is invalid. │ status code: 400
Error: error creating subnet: InvalidSubnet.Range: The CIDR '10.2.0.64/26' is invalid. │ status code: 400
Error: error creating subnet: InvalidSubnet.Range: The CIDR '10.2.0.0/26' is invalid. │ status code: 400
I am using below CIDR ranges for VPC and Subnets
variable "cidr_block" {
default = "10.1.0.0/21"
description = "VPC CIDR Block"
type = string
}
variable "public_subnet_cidr_blocks" {
default = ["10.1.0.0/26","10.2.0.0/26","10.1.0.64/26","10.2.0.64/26","10.1.0.128/26","10.2.0.128/26"]
type = list
description = "List of public subnet CIDR blocks"
}
variable "private_subnet_cidr_blocks" {
default = ["10.3.0.0/25", "10.4.0.128/25", "10.3.0.128/25", "10.5.0.0/25", "10.4.0.0/25","10.5.0.128/25"]
type = list
description = "List of private subnet CIDR blocks"
}
CodePudding user response:
Assuming that you are trying to declare subnets with the given address ranges inside the VPC block 10.1.0.0/21
, this is invalid because not all of the subnet addresses you declared belong to that VPC address prefix.
The command line tool ipcalc
is helpful for visualizing this. There are some online tools with similar capabilities, but this one's output is easiest to share in this answer.
First, let's examine the VPC CIDR block:
$ ipcalc 10.1.0.0/21
Address: 10.1.0.0 00001010.00000001.00000 000.00000000
Netmask: 255.255.248.0 = 21 11111111.11111111.11111 000.00000000
Wildcard: 0.0.7.255 00000000.00000000.00000 111.11111111
=>
Network: 10.1.0.0/21 00001010.00000001.00000 000.00000000
HostMin: 10.1.0.1 00001010.00000001.00000 000.00000001
HostMax: 10.1.7.254 00001010.00000001.00000 111.11111110
Broadcast: 10.1.7.255 00001010.00000001.00000 111.11111111
Hosts/Net: 2046 Class A, Private Internet
ipcalc
's notation here is showing on the right the binary digits that correspond with the decimal IP addresses on the left, and the space between the two strings of binary digits represents the dividing point between the network address and the host number. The main thing to notice here is that all addresses under this block must start with the binary digits 00001010.00000001.00000
, which are the first 21 digits of the 32-bit IP address.
Now let's examine one of the CIDR blocks indicated in your error messages:
$ ipcalc 10.2.0.128/26
Address: 10.2.0.128 00001010.00000010.00000000.10 000000
Netmask: 255.255.255.192 = 26 11111111.11111111.11111111.11 000000
Wildcard: 0.0.0.63 00000000.00000000.00000000.00 111111
=>
Network: 10.2.0.128/26 00001010.00000010.00000000.10 000000
HostMin: 10.2.0.129 00001010.00000010.00000000.10 000001
HostMax: 10.2.0.190 00001010.00000010.00000000.10 111110
Broadcast: 10.2.0.191 00001010.00000010.00000000.10 111111
Hosts/Net: 62 Class A, Private Internet
Let's compare the network address prefix binary digits between the two:
Address: 10.1.0.0 00001010.00000001.00000 000.00000000
Address: 10.2.0.128 00001010.00000010.00000000.10 000000
In the second example the space has moved to the right to represent that this subnet has a 21-bit address prefix, but it's only the first 21 bits that need to match, indicated by the space on the first line. However, the second address has a different value for its second octet, and so the second address does not belong to the same address range as the first.
Let's compare this with one of the ones that didn't generate an error:
Address: 10.1.0.0 00001010.00000001.00000 000.00000000
Address: 10.1.0.0 00001010.00000001.00000000.00 000000
This one is acceptable because the first 21 binary digits match between the two addresses, and all that's changed is the dividing line between network address and host number.
To get a working result, you must ensure that all of your subnets have address ranges that belong to the VPC's address range, which means that they must share the same prefix. You can select a shorter prefix if you wish to change earlier digits in the address, but note that AWS VPC in particular will not allow a VPC prefix length of smaller than /16
, and so in practice that means that subnets within a VPC must always have at least the first two octets of the IP address in common with the VPC itself.
There's some more information on IP network addressing in the Terraform documentation section Netmasks and Subnets, which is part of the documentation of Terraform's built-in functions for calculating subnet and host addresses.
HashiCorp also provides a Terraform module hashicorp/subnets/cidr
which internally uses Terraform's address-calculation functions to more conveniently allocate many subnet addresses at once, just by specifying how long a prefix each subnet will have and letting Terraform calculate the actual resulting addresses.