AWS 和 Terraform - cidrsubnet 函数中的 netnum

AWS and Terraform - netnum in cidrsubnet function

我最近开始使用 Terraform,作为 VPC 配置的一部分,我在理解 cidrsubnet() 函数中的 netnum 时遇到了一些困难。

我调查了 Terraform documentation,它说:

netnum (the third parameter) is a whole number that can be represented as a binary integer with no more than newbits binary digits, which will be used to populate the additional bits added to the prefix - still had some difficulties to understand it.

例如:

cidrsubnet("100.121.0.0/20", 8,64) --> 100.121.4.0/28

cidrsubnet("10.1.2.0/24", 4, 15)  --> 10.1.2.240/28

如果您能解释一下 netnum 参数,我们将不胜感激。

非常感谢,

塔尔

使用 cidrsubnet 需要熟悉一些网络寻址概念。

最重要的思想是 IP 地址(无论是 IPv4 还是 IPv6)基本上都是由二进制数字构成的,尽管我们通常将其表示为四个十进制八位字节(对于 IPv4)或一串 16 位十六进制数字(对于 IPv6)。

以我们上面的例子 cidrsubnet("10.1.2.0/24", 4, 15) 为例,该函数首先将给定的 IP 地址字符串转换为等效的二进制表示形式:

      10 .        1 .        2 .        0
00001010   00000001   00000010 | 00000000
         network               |   host

前缀字符串末尾的/24指定前24位 地址的位——或者前三个八位字节——标识网络 而其余位(在本例中为 32 - 24 = 8 位)标识主机 在网络内。

CLI 工具 ipcalc 对 将 CIDR 前缀可视化为二进制数。我们可以确认转换 通过向 ipcalc:

提供相同的前缀字符串
$ ipcalc 10.1.2.0/24
Address:   10.1.2.0             00001010.00000001.00000010. 00000000
Netmask:   255.255.255.0 = 24   11111111.11111111.11111111. 00000000
Wildcard:  0.0.0.255            00000000.00000000.00000000. 11111111
=>
Network:   10.1.2.0/24          00001010.00000001.00000010. 00000000
HostMin:   10.1.2.1             00001010.00000001.00000010. 00000001
HostMax:   10.1.2.254           00001010.00000001.00000010. 11111110
Broadcast: 10.1.2.255           00001010.00000001.00000010. 11111111
Hosts/Net: 254                   Class A, Private Internet

这给了我们一些额外的信息,但也证实了(使用稍微 不同的表示法)从十进制到二进制的转换并显示范围 此网络中可能的主机地址数。

虽然 cidrhost 允许计算单个主机 IP 地址, 另一方面,cidrsubnet 在给定的 范围内创建一个新的网络前缀 网络前缀。换句话说,它创建了一个子网。

当我们调用 cidrsubnet 时,我们还传递了两个额外的参数:newbitsnetnumnewbits 决定结果前缀的长度 位;在我们的示例中,我们指定了 4,这意味着结果 子网的前缀长度为 24 + 4 = 28 位。我们可以想象这些 位细分如下:

      10 .        1 .        2 .    ?        0
00001010   00000001   00000010 |   XXXX | 0000
         parent network        | netnum | host

原来是 "host number" 的八位中的四位现在正在 重新用作子网号。网络前缀不再落在 精确的八位字节边界,所以实际上我们现在正在拆分最后一个十进制数 在IP地址中分成两部分,用一半来表示子网 数字,另一半代表主机号。

netnum 参数然后决定将什么数值编码到那些 四个新的子网位。在我们当前的示例中,我们传递了 15,即 用二进制表示为 1111,允许我们填写 XXXX 段 在上面:

      10 .        1 .        2 .    15       0
00001010   00000001   00000010 |   1111 | 0000
         parent network        | netnum | host

要将其转换回正常的十进制表示法,我们需要重新组合 最后八位字节的两个部分。将 11110000 从二进制转换为十进制 给出 240,然后可以将其与我们的新前缀长度 28 组合为 产生结果 10.1.2.240/28。我们可以再次将这个前缀字符串传递给 ipcalc 形象化:

$ ipcalc 10.1.2.240/28
Address:   10.1.2.240           00001010.00000001.00000010.1111 0000
Netmask:   255.255.255.240 = 28 11111111.11111111.11111111.1111 0000
Wildcard:  0.0.0.15             00000000.00000000.00000000.0000 1111
=>
Network:   10.1.2.240/28        00001010.00000001.00000010.1111 0000
HostMin:   10.1.2.241           00001010.00000001.00000010.1111 0001
HostMax:   10.1.2.254           00001010.00000001.00000010.1111 1110
Broadcast: 10.1.2.255           00001010.00000001.00000010.1111 1111
Hosts/Net: 14                    Class A, Private Internet

新子网有四位可用于主机编号,这意味着 一旦我们减去,就有 14 个主机地址可供分配 网络自己的地址和广播地址。因此你可以使用 cidrhost 计算主机地址的函数 为其提供 1 到 14 之间的值:

> cidrhost("10.1.2.240/28", 1)
10.1.2.241
> cidrhost("10.1.2.240/28", 14)
10.1.2.254

有关 CIDR 表示法和子网划分的详细信息,请参阅 Classless Inter-domain Routing.


(我在 PR #20828 中将以上内容添加到 Terraform 的 cidrsubnet 文档中;它应该在下一个 Terraform 版本发布后反映在主 Terraform 文档中。)