Your toset(local.a) in the example shown is also not a valid argument for for_each and would result in the same error. The result must be a map or set of string values, and you would have a set of tuples.
Can you describe what you actually want to use as the keys for the aws_efs_mount_target resource instances?
I want to use a Kubernetes cluster name (AWS EKS) as a key for aws_efs_mount_target, so aws-dev-us-west-2-infra1 is the name of the Kubernetes cluster.
kubernetes = {
aws-dev-us-west-2-infra1 = { <-- this is Kubernetes cluster name
...
eks = { <-- EKS I want to plug-in to the cluster
aws-dev-us-west-2-infra1-eks = {}
}
...
}
}
In the example above, it’s just a single cluster to make it simpler. Now, I want to be able “connect” AWS EFS to the clusters.
But the problem with the code above is the resource aws_efs_mount_target argument subnet_id accepts string only while data.aws_subnets.compute.ids returns a list .
If I’m understanding correctly, it seems like your current value has three levels of nesting and you intend to reduce it to only two levels of nesting.
In your current example there’s only one element in both the top-level sequences and in the mid-level sequence, so it isn’t clear whether you want to remove the first level of nesting or the second level of nesting, since both of those operations would produce the same result with this particular example input.
However, noting that your goal is to populate a for_each argument I think I would suggest a different goal instead: for_each wants a map whose keys will be the unique identifiers for each instance of the resource, and so I might suggest something like this instead:
locals {
aws_efs_mount_targets = toset(flatten([
for k, v in var.kubernetes : [
for pair in setproduct([k], local.kubernetes_network[v.network]) : {
key = pair[0]
cluster = v
subnet_id = pair[1]
}
]
]))
}
resource "aws_efs_mount_target" "example" {
for_each = {
for mt in local.aws_efs_mount_targets : mt.key => mt
}
subnet_id = each.value.subnet_id
# ...
}
The main modification I made here is to first construct a list of lists of objects, because then flatten is a convenient way to discard the extra level of nesting and just get a flat list of objects. I included in each object a key property that will eventually be the instance key.
In the for_each expression I did one more projection from set to map, hoisting the key attribute out to populate the keys of the map elements, and therefore giving for_each a valid map value.
Inside that resource block the each.value reference refers to the entire object, so along with the each.value.subnet_id I showed it would also be valid to refer to (for example) each.value.cluster.autoscale_group to get the autoscaling group from the original var.kubernetes collection. I didn’t show a full example because it isn’t clear to me how you intend to populate the file_system_id argument, but hopefully this is enough for you to infer the remaining steps yourself.