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

Posted

技术标签:

【中文标题】使用 Terraform 的 aws 子网的子网范围无效【英文标题】:Invalid subnet range for aws subnet using Terraform 【发布时间】:2022-01-17 02:25:06 【问题描述】:

在我尝试使用 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"

【问题讨论】:

10.1.0.1/21 仅涵盖地址范围10.1.0.1-10.1.7.254,但您正试图在此范围之外分配地址。我建议使用子网计算器。 【参考方案1】:

假设您尝试在 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 文档部分Netmasks and Subnets 中提供了有关 IP 网络寻址的更多信息,该部分是 Terraform 用于计算子网和主机地址的内置函数文档的一部分。

HashiCorp 还提供了a Terraform module hashicorp/subnets/cidr,它在内部使用 Terraform 的地址计算功能更方便地一次分配多个子网地址,只需指定每个子网的前缀长度并让 Terraform 计算实际结果地址。

【讨论】:

以上是关于使用 Terraform 的 aws 子网的子网范围无效的主要内容,如果未能解决你的问题,请参考以下文章

在另一个模块中为 EC2 添加指定子网 - AWS Terraform -

如何在带有 Terraform 的 AWS VPC 中的两个子网之间进行路由?

如何在多个子网上运行 AWS EMR 集群?

Terraform 一个具有两个子网的 EC2 实例

aws_lb 的动态子网映射

terraform - 将 vpc_id 参数从不同的 VPC 传递到多个子网