Terraform 使用带有标签的 count.index

Posted

技术标签:

【中文标题】Terraform 使用带有标签的 count.index【英文标题】:Terraform using count.index with tags 【发布时间】:2021-08-06 12:05:28 【问题描述】:

使用 terraform,我正在尝试使用 count.index 将计数包含在我的资源标签中,但出现此错误:

错误:属性值类型不正确 │ │ 在 ..\modules\sn\ressources.tf 第 16 行,资源“aws_subnet”“prod_sn”中: │ 16: tags = var.sn_tags[count.index] │ ├──────────────── │ │ count.index 是一个数字,只有 apply 后才知道 │ │ var.sn_tags 是一个字符串列表,只有在apply之后才知道 │ │ 属性“tags”的值不合适:需要字符串映射。

vars.tf

variable "sn_tags" 
  type        = list (string)
  default     = ["aa", "bb"]

ressources.tf

resource "aws_subnet" "prod_sn" 
  count                   = length(var.sn_cidr)
  vpc_id                  = var.vpc_id
  cidr_block              = var.sn_cidr[count.index]
  availability_zone       = data.aws_availability_zones.azs.names[count.index]
  tags                    = var.sn_tags[count.index] 

ma​​in.tf

# Create Public Subnet on availability_zone "3a"
module "publicSn-a" 
  source            = "../modules/sn"
  vpc_id            = module.vpc.vpcId 
  sn_cidr           = ["10.0.1.0/24", "10.0.2.0/24"]
  sn_tags           = ["prodPublicA","prodPublicB"]
  

【问题讨论】:

【参考方案1】:

您的问题是每个循环迭代都试图将string 类型传递给tags 参数。如果您将其分解为没有计数的单个资源(现在使用第一个元素),那么您当前的代码基本上是这样的:

resource "aws_subnet" "prod_sn" 
  vpc_id                  = var.vpc_id
  cidr_block              = "10.0.1.0./24"
  availability_zone       = "eu-west-1a" # Note may not be this but the data source and the index will at least resolve to a single string AZ
  tags                    = "prodPublicA"

如果我们查看the documentation for the aws_subnet resource,我们可以看到tags parameter 需要map,而不是错误所暗示的string

您可以通过将您的 list(string) 变量更改为 list(map) 来解决此问题,这样您就可以改为:

variable "sn_tags" 
  type = list(map)

# Create Public Subnet on availability_zone "3a"
module "publicSn-a" 
  source            = "../modules/sn"
  vpc_id            = module.vpc.vpcId 
  sn_cidr           = ["10.0.1.0/24", "10.0.2.0/24"]
  sn_tags           = [
    
      name = "prodPublicA"
    ,
    
      name = "prodPublicB"
    ,
  ] 

或者,如果您只想将Name 标签添加到所有子网并且不希望标签具有更大的灵活性,您可以像这样对其进行修改:

variable "sn_names" 
  type = list(string)


resource "aws_subnet" "prod_sn" 
  count                   = length(var.sn_cidr)
  vpc_id                  = var.vpc_id
  cidr_block              = var.sn_cidr[count.index]
  availability_zone       = data.aws_availability_zones.azs.names[count.index]
  tags                    = 
    Name = var.sn_names[count.index]
  

然后这样称呼它:

# Create Public Subnet on availability_zone "3a"
module "publicSn-a" 
  source            = "../modules/sn"
  vpc_id            = module.vpc.vpcId 
  sn_cidr           = ["10.0.1.0/24", "10.0.2.0/24"]
  sn_names          = ["prodPublicA","prodPublicB"]

【讨论】:

以上是关于Terraform 使用带有标签的 count.index的主要内容,如果未能解决你的问题,请参考以下文章

Terraform - 如何将列表转换为地图(如何使用 terraform 获取 AMI 标签)

如何在 aws 检查器资源组上多次使用相同的标签

使用模块和计数时如何在 terraform 中包含标签

带有 Terraform 的 Google Cloud 凭据

使用 Terraform 强制执行标签及其价值 Azure Policy

使用 terraform 添加带有 GPU 的 GKE 节点池