Terraform 地形中cidrsubnet函数所有分量的动态插值

Terraform 地形中cidrsubnet函数所有分量的动态插值,terraform,terraform-provider-aws,Terraform,Terraform Provider Aws,在Terraform中是否有一种方法可以插值cidrsubnet函数的所有三个分量?我问这个问题的原因是因为我想创建具有不同CIDR前缀的VPC,因此cidrsubnet函数负责为我创建子网 假设VPC“prod”具有CIDR10.10.0.0/16,而VPC“dev”具有CIDR10.20.0.0/24。我正在寻找一种解决方案,其中相同的代码将通过插值cidrsubnet函数的值为我创建子网,如下所示: # map for different CIDR variable "VPC_CIDR"

在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
上面的代码将为prod和dev分别创建子网CIDR
10.10.0.0/20和
10.10.0.0/28
。这样,我的代码保持不变,只对变量进行插值


注:此代码用于演示。众所周知,这不是地形中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”是固定的,因此您的模块将假定始终指定它们,则您可以以类似于您描述的方式自动派生
子网\u位
值,如下所示:

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\u子网
,其中包含要创建的每个子网的一个元素。然后允许对每个元素重复
aws\u subnet.private
,并收集子网上填充
vpc_id
cidr_块
参数所需的所有值。

如果调用方可以选择
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”是固定的,因此您的模块将假定始终指定它们,则您可以以类似于您描述的方式自动派生
子网\u位
值,如下所示:

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\u子网
,其中包含要创建的每个子网的一个元素。然后允许对每个元素重复
aws\u subnet.private
,并将填充子网上的
vpc\u id
cidr\u块
参数所需的所有值聚集在一起。

这就是我要找的。谢谢。这就是我要找的。谢谢