Why am I getting an 'Incorrect attribute value type' error when I create a variable in Terraform?

I’m getting an Incorrect attribute value type when I try to create a variable in TF.

I’m on this version of TF:

Terraform v0.14.4
+ provider registry.terraform.io/hashicorp/aws v2.70.0

This is the error that I’m getting:

λ terraform apply

Error: Incorrect attribute value type

  on main.tf line 18, in resource "aws_instance" "example":
  18:   vpc_security_group_ids = var.vpc_security_group_ids["jf-master-pd"]

Inappropriate value for attribute "vpc_security_group_ids": set of string
required.

This is the code block in my main.tf code:

resource "aws_instance" "example" {
  ami                    = var.amis["us-east-1"]
  instance_type          = "t2.micro"
  vpc_security_group_ids = var.vpc_security_group_ids["jf-master-pd"] # < --- the line causing the problem
  subnet_id              = var.subnet_id["jf-master-pd"]
  key_name               = "jf-timd-keypair"
}

These are the variables that I’m trying to set in the variables.tf file:

variable "vpc_security_group_ids" {
  type = map(string)
  default = {
    "jf-master-pd"     = "sg-0333d9eaaeb3ab1b0"
    "jf-master-pd-gov" = "sg-7f051404"
  }
}


variable "subnet_id" {
  type = map(string)
  default = {
    "jf-master-pd"     = "subnet-3ab1835d"
    "jf-master-pd-gov" = "subnet-4dad6304"
  }
}

These two lines seem functionally the same:

  vpc_security_group_ids = var.vpc_security_group_ids["jf-master-pd"] # <--- line causing the problem
  subnet_id              = var.subnet_id["jf-master-pd"]

If I replace:

vpc_security_group_ids = var.vpc_security_group_ids["jf-master-pd"] with vpc_security_group_ids = ["sg-0333d9eaaeb3ab1b0"]

The terraform code applies without error. I just don’t see what’s wrong with this line:
vpc_security_group_ids = var.vpc_security_group_ids["jf-master-pd"]

The main.tf and variables.tf files are living in the same directory.

Why am I getting this error? How do I correct it?

A set (unordered list) should be provided here, not only a single item value.

OK how do I provide an unordered list? Can you give an example? I am new to terraform.

Also why does subnet_id work but vpc_security_group_ids doesn’t work? They look functionally the same to me.

The documentation clearly describes the requirements (list vs. string):
subnet_id - (Optional) VPC Subnet ID to launch in.

vpc_security_group_ids - (Optional, VPC only) A list of security group IDs to associate with.

So you could change your input variable.

variable "vpc_security_group_ids" {
  type = map(list(string))
  default = {
    "jf-master-pd"     = ["sg-0333d9eaaeb3ab1b0"]
    "jf-master-pd-gov" = ["sg-7f051404"]
  }
}

Thank you! That worked. I will try going through the docs some more so I can get clear on that. Thanks!

One more question, of all the entries in my variables.tf only vpc_security_group_ids needed to use a list the way you pointed out. Why is that? They all seem very similar.

variable "region" {
  type = map(string)
  default = {
    "jf-master-pd"     = "us-east-1"
    "jf-master-pd-gov" = "us-gov-west-1"
  }
}

variable "amis" {
  type = map(string)
  default = {
    "us-east-1"     = "ami-0885b1f6bd170450c"
    "us-west-2"     = "ami-07dd19a7900a1f049"
    "us-gov-west-1" = "ami-84556de5"
    "us-gov-east-1" = "ami-dee008af"
  }
}

variable "vpc_security_group_ids" {
  type = map(list(string))
  default = {
    "jf-master-pd"     = ["sg-0333d9eaaeb3ab1b0"]
    "jf-master-pd-gov" = ["sg-7f051404"]
  }
}


variable "subnet_id" {
  type = map(string)
  default = {
    "jf-master-pd"     = "subnet-3ab1835d"
    "jf-master-pd-gov" = "subnet-4dad6304"
  }
}

TIA

Well, it depends on the resource implementation. So basically it’s about providing a single value (subnet_id) or multiple values (plural vpc_security_group_ids).