Terraform 使用 count.index 和标签

Terraform using count.index with tags

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

Error: Incorrect attribute value type │ │ on ..\modules\sn\ressources.tf line 16, in resource "aws_subnet" "prod_sn": │ 16: tags = var.sn_tags[count.index] │ ├──────────────── │ │ count.index is a number, known only after apply │ │ var.sn_tags is a list of string, known only after apply │ │ Inappropriate value for attribute "tags": map of string required.

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] 
}

main.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"]
  
}

您的问题是每个循环迭代都试图将 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 we can see that the 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"]
}