如何使用 cidrsubnet 函数在 Terraform 中细分 CIDR 子网?

问题描述 投票:0回答:2

我希望 AWS 区域内的子网有这样的地址:

10.0.0.0/21
10.0.8.0/21
10.0.16.0/21
10.0.24.0/21
10.0.32.0/21
...

基本上,将第二个数字增加 8。

我还将为每个区域提供一个 VPN,并且它们应该共享相同的网络。所以我想要这样的:

10.1.0.0/16
10.2.0.0/16
10.3.0.0/16
10.4.0.0/16
10.5.0.0/16
...

基本上每次将第三个数字加 1。如果不可能每步走 1,那么也可以走 8。

我已经深入了解了 CIDR 块,但仍然不太清楚如何应用,特别是在以下上下文中。

我想要一套以 1 CIDR 块开始的嵌套 Terraform 模块,并将其子网划分为越来越小的块。首先,它将按区域(第三个数字)细分,然后按可用区域(第二个数字)细分。一切都将是动态的,因此您只需按字面意思提供初始 CIDR 块。

看来我应该使用

cidrsubnet
:

cidrsubnet(prefix, newbits, netnum)

我已经走到这一步了:

cidrsubnet(var.cidr_block, 13, netnum?)

我知道的

13
将从
/8
变为
/21
。但这会直接进入可用区(我不知道该怎么办
netnum
)。我想做这样的事情:

# main.tf
variable "cidr_block" {
  default = "10.0.0.0/8"
}

module "region1" {
  source = "./region" # ./region/main.tf
  cidr_block = cidrsubnet(var.cidr_block, 8?, count.index?) # 10.0.0.0/16?
}

module "region2" {
  source = "./region" # ./region/main.tf
  cidr_block = cidrsubnet(var.cidr_block, 8?, count.index?) # 10.1.0.0/16?
}

// ...

然后在区域子模块中:

# region/main.tf
module "availability_zone1" {
  source = "./availability_zone" # ./availability_zone/main.tf
  cidr_block = cidrsubnet(var.cidr_block, 5?, count.index?) # 10.1.0.0/21
}

module "availability_zone2" {
  source = "./availability_zone" # ./availability_zone/main.tf
  cidr_block = cidrsubnet(var.cidr_block, 5?, count.index?) # 10.1.8.0/21
}

module "availability_zone3" {
  source = "./availability_zone" # ./availability_zone/main.tf
  cidr_block = cidrsubnet(var.cidr_block, 5?, count.index?) # 10.1.16.0/21
}

// ...

所以基本上,从

/8 -> /16
细分一次,然后再从
/16 -> /21
细分。我还没有使用过
count.index
,但不知何故我希望它知道它在调用序列中的位置。如果不可能,那很好,我可以将索引与模块一起传递。

如何使用

cidrsubnet
函数编写此内容?这个问题最重要的部分是我应该在函数的每个槽中放入什么:
cidrsubnet(prefix, newbits, netnum)
,我不知道
netnum
具体应该是什么样的。

network-programming terraform ip-address subnet cidr
2个回答
5
投票

在我写这个答案时,Terraform 0.13.0 处于候选版本 1,并将在几周内发布。 Terraform 0.13.0 包含对模块使用

for_each
count
的能力,这使得使用
hashicorp/subnets/cidr
模块
来实现这样的多级寻址计划变得更加简单。与直接执行单独的
cidrsubnet
调用相比,该模块的一个优点是,它允许您为每个网络分配符号名称,并且它有一些约定来帮助弃用和稍后重用部分地址空间,而无需重新分配所有地址空间邻近网络。

您在示例中提到了 AWS 区域和子网,因此为了展示这一点,我将使用 AWS 区域名称和可用区作为网络的符号名称,但您可以使用对您的架构有意义的任何名称因为每个网络最终都有一个唯一的标识符。

locals {
  aws_region_zones = tolist([
    {
      region = "us-west-2"
      zones  = ["us-west-2a", "us-west-2b"]
    },
    {
      region = "us-east-1"
      zones  = ["us-east-1a", "us-east-2f"]
    },
    # When allocating new regions or zones,
    # always add them at the end of their
    # respective list to avoid renumbering
    # the existing address allocations.
  ])
}

module "regional" {
  source = "hashicorp/subnets/cidr"

  base_cidr_block = "10.0.0.0/8"
  networks = [
    for regional in local.aws_region_zones : {
      name     = regional.region
      new_bits = 8
    }
  ]
}

module "zonal" {
  source   = "hashicorp/subnets/cidr"
  for_each = {
    for net in module.regional.networks : net.name => net
  }

  base_cidr_block = each.value.cidr_block
  networks = [
    for zone_name in local.aws_region_zones[each.key].zones : {
      name     = regional.region
      new_bits = 5
    }
  ]
}

output "region_cidr_blocks" {
  value = tomap({
    for net in module.regional.networks : net.name => {
      cidr_block = net.cidr_block
      zones = tomap({
        for subnet in module.zonal[net.name].networks : subnet.name => {
          cidr_block = subnet.cidr_block
        }
      })
    }
  })
}

region_cidr_blocks
输出值将是一个对象映射,其中每个对象代表一个区域,然后是每个可用区域的嵌套映射。


1
投票

你已经拥有的是正确的。

count.index
只会增加 1。

您可以按如下方式计算和验证块(terraform 0.12):

provider "aws" {
  region = "us-east-1"
}


variable "cidr_block" {
    default = "10.0.0.0/8"
}

output "cidr1" {
    value = [for index in range(8):
             cidrsubnet(var.cidr_block, 8, index)]
}

output "cidr2" {
    value = [for index in range(8):
             cidrsubnet(var.cidr_block, 13, index)]
}

这些将输出:

cidr1 = [
  "10.0.0.0/16",
  "10.1.0.0/16",
  "10.2.0.0/16",
  "10.3.0.0/16",
  "10.4.0.0/16",
  "10.5.0.0/16",
  "10.6.0.0/16",
  "10.7.0.0/16",
]
cidr2 = [
  "10.0.0.0/21",
  "10.0.8.0/21",
  "10.0.16.0/21",
  "10.0.24.0/21",
  "10.0.32.0/21",
  "10.0.40.0/21",
  "10.0.48.0/21",
  "10.0.56.0/21",
]

要查看所有组合,您可以执行以下操作:

provider "aws" {
  region = "us-east-1"
}


variable "cidr_block" {
    default = "10.0.0.0/8"
}


output "all_cidrs" {
    value = [for index1 in range(8):
             {
                 cidrsubnet(var.cidr_block, 8, index1) = [
                     for index2 in range(8): cidrsubnet(cidrsubnet(var.cidr_block, 8, index1), 5, index2)
                 ]
             }
    ]
}

这给出了:

all_cidrs = [
  {
    "10.0.0.0/16" = [
      "10.0.0.0/21",
      "10.0.8.0/21",
      "10.0.16.0/21",
      "10.0.24.0/21",
      "10.0.32.0/21",
      "10.0.40.0/21",
      "10.0.48.0/21",
      "10.0.56.0/21",
    ]
  },
  {
    "10.1.0.0/16" = [
      "10.1.0.0/21",
      "10.1.8.0/21",
      "10.1.16.0/21",
      "10.1.24.0/21",
      "10.1.32.0/21",
      "10.1.40.0/21",
      "10.1.48.0/21",
      "10.1.56.0/21",
    ]
  },
  {
    "10.2.0.0/16" = [
      "10.2.0.0/21",
      "10.2.8.0/21",
      "10.2.16.0/21",
      "10.2.24.0/21",
      "10.2.32.0/21",
      "10.2.40.0/21",
      "10.2.48.0/21",
      "10.2.56.0/21",
    ]
  },
  {
    "10.3.0.0/16" = [
      "10.3.0.0/21",
      "10.3.8.0/21",
      "10.3.16.0/21",
      "10.3.24.0/21",
      "10.3.32.0/21",
      "10.3.40.0/21",
      "10.3.48.0/21",
      "10.3.56.0/21",
    ]
  },
  {
    "10.4.0.0/16" = [
      "10.4.0.0/21",
      "10.4.8.0/21",
      "10.4.16.0/21",
      "10.4.24.0/21",
      "10.4.32.0/21",
      "10.4.40.0/21",
      "10.4.48.0/21",
      "10.4.56.0/21",
    ]
  },
  {
    "10.5.0.0/16" = [
      "10.5.0.0/21",
      "10.5.8.0/21",
      "10.5.16.0/21",
      "10.5.24.0/21",
      "10.5.32.0/21",
      "10.5.40.0/21",
      "10.5.48.0/21",
      "10.5.56.0/21",
    ]
  },
  {
    "10.6.0.0/16" = [
      "10.6.0.0/21",
      "10.6.8.0/21",
      "10.6.16.0/21",
      "10.6.24.0/21",
      "10.6.32.0/21",
      "10.6.40.0/21",
      "10.6.48.0/21",
      "10.6.56.0/21",
    ]
  },
  {
    "10.7.0.0/16" = [
      "10.7.0.0/21",
      "10.7.8.0/21",
      "10.7.16.0/21",
      "10.7.24.0/21",
      "10.7.32.0/21",
      "10.7.40.0/21",
      "10.7.48.0/21",
      "10.7.56.0/21",
    ]
  },
]
© www.soinside.com 2019 - 2024. All rights reserved.