使用Terraform的aws子网的子网范围无效



在尝试使用terraform创建子网时,不断出现以下错误。使用aws控制台创建子网没有问题。有人能帮我吗?

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

我正在为VPC和子网使用以下CIDR范围

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"
}

假设您试图在VPC块10.1.0.0/21内声明具有给定地址范围的子网,这是无效的,因为您声明的子网地址并非都属于该VPC地址前缀。

命令行工具ipcalc有助于对此进行可视化。有一些在线工具具有类似的功能,但在这个答案中,这个工具的输出最容易共享。

首先,让我们检查VPC CIDR块:

$ 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的符号在右边显示了与左边的十进制IP地址相对应的二进制数字,两个二进制数字串之间的空格表示网络地址和主机号之间的分界点。这里需要注意的是,该块下的所有地址都必须以二进制数字00001010.00000001.00000开头,这是32位IP地址的前21位数字。

现在,让我们检查错误消息中指示的CIDR块之一:

$ 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

让我们比较一下两者之间的网络地址前缀二进制数字:

Address:   10.1.0.0             00001010.00000001.00000 000.00000000
Address:   10.2.0.128           00001010.00000010.00000000.10 000000

在第二个例子中,空格向右移动,表示该子网具有21位地址前缀,但只有前21位需要匹配,由第一行上的空格表示。然而,第二地址的第二个八位位组具有不同的值,因此第二地址不属于与第一地址相同的地址范围。

让我们将其与没有生成错误的进行比较

Address:   10.1.0.0             00001010.00000001.00000 000.00000000
Address:   10.1.0.0             00001010.00000001.00000000.00 000000

这一个是可以接受的,因为前21个二进制数字在两个地址之间匹配,所改变的只是网络地址和主机号之间的分界线。

要获得工作结果,您必须确保所有子网的地址范围都属于VPC的地址范围,这意味着它们必须共享相同的前缀。如果您希望更改地址中较早的数字,您可以选择较短的前缀,但请注意,AWS VPC特别不允许VPC前缀长度小于/16,因此在实践中,这意味着VPC内的子网必须始终具有至少IP地址的前两个八位字节,与VPC本身相同。


Terraform文档中的"网络掩码和子网"部分提供了有关IP网络寻址的更多信息,这是Terraform用于计算子网和主机地址的内置功能文档的一部分。

HashiCorp还提供了Terraform模块hashicorp/subnets/cidr,该模块在内部使用Terraform的地址计算功能,只需指定每个子网的前缀长度,并让Terraform计算实际产生的地址,就可以更方便地同时分配多个子网地址。

最新更新