1
votes

using terraform, i'm trying to include the count in the tags of my resource using count.index, but getting this error :

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

1 Answers

2
votes

Your issue is that each loop iteration is trying to pass a string type to the tags parameter. If you break it down to just a single resource without the count (using the first element for now) then your current code is basically this:

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

If we look at the documentation for the aws_subnet resource we can see that the tags parameter wants a map, not a string as the error implies.

You could fix this by changing your list(string) variable into a list(map) so instead you have something like this instead:

variable "sn_tags" {
  type = list(map)
}

and

# 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"
    },
  ] 
}

Alternatively if you just want to add a Name tag to all the subnets and don't want more flexibility with the tags instead you could rework it like this:

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

and call it like so:

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