Terraform 中 cidrsubnet 函数的所有组件的动态插值
Dynamic interpolation of all components of cidrsubnet function in Terraform
在 Terraform 中有没有一种方法可以插入 cidrsubnet 函数的所有三个组件?我问这个的原因是因为我想创建具有不同 CIDR 前缀的 VPC,因此 cidrsubnet 函数负责为我创建子网。
据推测,VPC“prod”具有 CIDR 10.10.0.0/16
,而 VPC“dev”具有 CIDR 10.20.0.0/24
.我正在寻找一种解决方案,其中相同的代码将通过插入 cidrsubnet 函数的值来为我创建子网,如下所示:
# map for different CIDR
variable "VPC_CIDR" {
type = "map"
default = {
"dev" = "10.10.0.0/24"
"prod" = "10.10.0.0/16"
}
}
variable "PRI_SUBNET_COUNT" {
default = "1"
}
# intended logic which interpolates netnum (impractical code)
if var.VPC_CIDR = "prod"
netnum = 4
elif var.VPC_CIDR = "dev"
netnum = 3
else
netnum = 2
resource "aws_subnet" "sub-node-private" {
count = var.PRI_SUBNET_COUNT
cidr_block = cidrsubnet(var.VPC_CIDR, var.netnum, count.index + 2) #all three components interpolated
以上代码将为生产创建子网 CIDR 10.10.0.0/20
,为开发创建子网 CIDR 10.10.0.0/28
。这样我的代码保持不变,只有变量被插值。
N.B:此代码用于演示目的。众所周知,这不是 Terraform 中 if/else 的实用代码。
如果调用者可以选择 var.VPC_CIDR
的键,那么最好将 CIDR 前缀和用于其子网的新位数组合在变量中。由于命名 Terraform 变量的常规方式是小写,因此我将在以下示例中将其重命名为 vpc_cidr
。
variable "vpc_cidr" {
type = map(object({
cidr_block = string
subnet_bits = number
}))
default = {
dev = {
cidr_block = "10.10.0.0/24"
subnet_bits = 3
}
prod = {
cidr_block = "10.10.0.0/16"
subnet_bits = 4
}
}
}
variable "pri_subnet_count" {
type = number
default = 1
}
locals {
vpc_subnets = flatten([
for name, vpc in var.vpc_cidr : [
for i in count(var.pri_subnet_count) : {
name = "${name}-${i}"
vpc_name = name
cidr_block = vpc.cidr_block
subnet_bits = vpc.subnet_bits
network_num = i + 2
}
]
])
}
resource "aws_vpc" "example" {
for_each = var.vpc_cidr
cidr_block = each.value.cidr_block
}
resource "aws_subnet" "private" {
for_each = { for s in local.vpc_subnets : s.name => s }
vpc_id = aws_vpc.example[each.value.vpc_name].id
cidr_block = cidrsubnet(each.value.cidr_block, each.value.subnet_bits, each.value.network_num)
# ...
}
如果名称 "prod" 和 "dev" 是固定的,因此您的模块将假定它们将始终被指定,您可以以类似于什么的方式自动导出 subnet_bits
值你这样描述的:
variable "vpc_cidr" {
type = object({
# Force caller to provide "dev" and "prod" values, so
# that it will match up with the attributes in
# local.subnet_bits defined below.
dev = string
prod = string
})
value = {
dev = "10.10.0.0/24"
prod = "10.10.0.0/16"
}
}
variable "pri_subnet_count" {
type = number
default = 1
}
locals {
subnet_bits = {
dev = 3
prod = 4
}
vpcs = {
for name, cidr_block in var.vpc_cidr : name => {
cidr_block = cidr_block
subnet_bits = local.subnet_bits[name]
}
}
vpc_subnets = flatten([
for name, vpc in local.vpcs : [
for i in count(var.pri_subnet_count) : {
name = "${name}-${i}"
vpc_name = name
cidr_block = vpc.cidr_block
subnet_bits = vpc.subnet_bits
network_num = i + 2
}
]
])
}
resource "aws_vpc" "example" {
for_each = local.vpcs
cidr_block = each.value.cidr_block
}
resource "aws_subnet" "private" {
for_each = { for s in local.vpc_subnets : s.name => s }
vpc_id = aws_vpc.example[each.value.vpc_name].id
cidr_block = cidrsubnet(each.value.cidr_block, each.value.subnet_bits, each.value.network_num + 2)
# ...
}
上面说明的一般模式是构建数据结构 local.vpc_subnets
,其中包含您要创建的每个子网的一个元素。然后允许为每个元素重复 aws_subnet.private
,并将填充子网上的 vpc_id
和 cidr_block
参数所需的所有值聚集在一起。
在 Terraform 中有没有一种方法可以插入 cidrsubnet 函数的所有三个组件?我问这个的原因是因为我想创建具有不同 CIDR 前缀的 VPC,因此 cidrsubnet 函数负责为我创建子网。
据推测,VPC“prod”具有 CIDR 10.10.0.0/16
,而 VPC“dev”具有 CIDR 10.20.0.0/24
.我正在寻找一种解决方案,其中相同的代码将通过插入 cidrsubnet 函数的值来为我创建子网,如下所示:
# map for different CIDR
variable "VPC_CIDR" {
type = "map"
default = {
"dev" = "10.10.0.0/24"
"prod" = "10.10.0.0/16"
}
}
variable "PRI_SUBNET_COUNT" {
default = "1"
}
# intended logic which interpolates netnum (impractical code)
if var.VPC_CIDR = "prod"
netnum = 4
elif var.VPC_CIDR = "dev"
netnum = 3
else
netnum = 2
resource "aws_subnet" "sub-node-private" {
count = var.PRI_SUBNET_COUNT
cidr_block = cidrsubnet(var.VPC_CIDR, var.netnum, count.index + 2) #all three components interpolated
以上代码将为生产创建子网 CIDR 10.10.0.0/20
,为开发创建子网 CIDR 10.10.0.0/28
。这样我的代码保持不变,只有变量被插值。
N.B:此代码用于演示目的。众所周知,这不是 Terraform 中 if/else 的实用代码。
如果调用者可以选择 var.VPC_CIDR
的键,那么最好将 CIDR 前缀和用于其子网的新位数组合在变量中。由于命名 Terraform 变量的常规方式是小写,因此我将在以下示例中将其重命名为 vpc_cidr
。
variable "vpc_cidr" {
type = map(object({
cidr_block = string
subnet_bits = number
}))
default = {
dev = {
cidr_block = "10.10.0.0/24"
subnet_bits = 3
}
prod = {
cidr_block = "10.10.0.0/16"
subnet_bits = 4
}
}
}
variable "pri_subnet_count" {
type = number
default = 1
}
locals {
vpc_subnets = flatten([
for name, vpc in var.vpc_cidr : [
for i in count(var.pri_subnet_count) : {
name = "${name}-${i}"
vpc_name = name
cidr_block = vpc.cidr_block
subnet_bits = vpc.subnet_bits
network_num = i + 2
}
]
])
}
resource "aws_vpc" "example" {
for_each = var.vpc_cidr
cidr_block = each.value.cidr_block
}
resource "aws_subnet" "private" {
for_each = { for s in local.vpc_subnets : s.name => s }
vpc_id = aws_vpc.example[each.value.vpc_name].id
cidr_block = cidrsubnet(each.value.cidr_block, each.value.subnet_bits, each.value.network_num)
# ...
}
如果名称 "prod" 和 "dev" 是固定的,因此您的模块将假定它们将始终被指定,您可以以类似于什么的方式自动导出 subnet_bits
值你这样描述的:
variable "vpc_cidr" {
type = object({
# Force caller to provide "dev" and "prod" values, so
# that it will match up with the attributes in
# local.subnet_bits defined below.
dev = string
prod = string
})
value = {
dev = "10.10.0.0/24"
prod = "10.10.0.0/16"
}
}
variable "pri_subnet_count" {
type = number
default = 1
}
locals {
subnet_bits = {
dev = 3
prod = 4
}
vpcs = {
for name, cidr_block in var.vpc_cidr : name => {
cidr_block = cidr_block
subnet_bits = local.subnet_bits[name]
}
}
vpc_subnets = flatten([
for name, vpc in local.vpcs : [
for i in count(var.pri_subnet_count) : {
name = "${name}-${i}"
vpc_name = name
cidr_block = vpc.cidr_block
subnet_bits = vpc.subnet_bits
network_num = i + 2
}
]
])
}
resource "aws_vpc" "example" {
for_each = local.vpcs
cidr_block = each.value.cidr_block
}
resource "aws_subnet" "private" {
for_each = { for s in local.vpc_subnets : s.name => s }
vpc_id = aws_vpc.example[each.value.vpc_name].id
cidr_block = cidrsubnet(each.value.cidr_block, each.value.subnet_bits, each.value.network_num + 2)
# ...
}
上面说明的一般模式是构建数据结构 local.vpc_subnets
,其中包含您要创建的每个子网的一个元素。然后允许为每个元素重复 aws_subnet.private
,并将填充子网上的 vpc_id
和 cidr_block
参数所需的所有值聚集在一起。