For_each on map datatype with "data"

Hello,
and yet again, this same " for_each on maps of complex objects" issue :man_facepalming:

The desire here is to supply ( tfvars) name(s) of security groups while building out a vm.

variables.tfvars:
vms = {
  DS1 = {
...
    instance_type        = "r6i.large"
...
    security_group_name = [
      "DSsg",
    ]
 ....
  }
  DS2 = {
   ...
   instance_type        = "r6i.large"
   ...
    security_group_name = [
      "DSsg",
    ]
....
  }


vars.tf:

variable "vms" {
  type = map(object({
...
   instance_type        =  string
....
    security_group_name = list (string)
...
  }))
}

and the code :

data aws_security_group sg-name {
  for_each = var.vms
  name = each.value.security_group_name
}

resource "aws_instance" "this" {
  for_each = var.vms
  vpc_security_group_ids = [ data.aws_security_group.sg-name[each.key].id ]
# vpc_security_group_ids = ["${join(",", data.aws_security_group.sg-name[each.key].id ) }" ]
#  vpc_security_group_ids = [each.value.security_group_id]

...
}

needless to say that all lines (vpc_security_group_ids ) are failing with different errors.

in the current version, the error is :

Error: Incorrect attribute value type
β”‚ 
β”‚   on ec2.tf line 24, in data "aws_security_group" "sg-name":
β”‚   24:   name = each.value.security_group_name
β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     β”‚ each.value.security_group_name is list of string with 1 element
β”‚ 
β”‚ Inappropriate value for attribute "name": string required

if i change the code to:

  vpc_security_group_ids = ["${join(",", data.aws_security_group.sg-name[each.key].id ) }" ]

the error is :

Error: Incorrect attribute value type
β”‚ 
β”‚   on ec2.tf line 24, in data "aws_security_group" "sg-name":
β”‚   24:   name = each.value.security_group_name
β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     β”‚ each.value.security_group_name is list of string with 2 elements
β”‚ 
β”‚ Inappropriate value for attribute "name": string required.

Clearly i’m not understanding how the loop on the complex objects with a β€œlook up into data resource” work in this scenario.

Appreciate your guidance.

You are jumping ahead of yourself, by trying to get the resource block working, when the data block is still itself broken!

In your post you have described trying various things in the resource block, yet if you look at both of the errors you have posted, they are identical, and refer to the data block.

It seems like your intent is to look up each security_group_name value. However you have not written code to do that.

I think something like

data "aws_security_group" "sg-name" {
  for_each = toset(concat(values(var.vms)[*].security_group_name...))
  name     = each.value
}

is closer to what you are looking for.

Only once you have your lookup working, is it time to make use of that data…

This is using a VM name each.key not a security group name to index into sg-name.

This layers some terrifyingly obsolete Terraform 0.11 and earlier legacy syntax on top of things, making it very hard to read.

This is accessing something (security_group_id) that doesn’t exist in your input tfvars.

You want something like:

  vpc_security_group_ids = [
    for sg_name in each.value.security_group_name :
    data.aws_security_group.sg-name[sg_name].id
  ]

@maxb ,
thank you for helping out. You are right - the β€œdata” is not correct.
Maybe i can flatten the var.vms, since security_groups are common across all vms in a vpc. // There is one vpc per account, so i can get away with this.