Hi,
I am struggling with the below code. I cannot get the last value that I pass in to be in the correct format. I think I need a set of strings, but the closest I can get is a list of set of strings.
data “aws_vpc” “this” {
tags = {
Name = "xxxx"
}
}
data “aws_subnet_ids” “bkp” {
for_each = var.bkp_eni_required != true ? : toset([var.bkp_subnet])
vpc_id = data.aws_vpc.this.id
tags = {
Name = var.bkp_subnet
}
}
data “aws_subnet” “bkp” {
for_each = var.bkp_eni_required != true ? : [for i in data.aws_subnet_ids.bkp : i.ids]
id = each.value
}
It is the data “aws_subnet” “bkp” resource and the [for i in data.aws_subnet_ids.bkp : i.ids] that needs to be fixed. With the above code I get the error
on main.tf line 40, in data “aws_subnet” “bkp”:
40: for_each = var.bkp_eni_required != true ? : [for i in data.aws_subnet_ids.bkp : i.ids]
The given “for_each” argument value is unsuitable: the “for_each” argument
must be a map, or set of strings, and you have provided a value of type list
of set of string.
Hi @jprouten,
Unfortunately there are some things missing from your example that make this a little hard to understand. In particular, I’m assuming you have some variable declarations something like this:
variable "bkp_eni_required" {
type = bool
}
variable "bkp_subnet" {
type = string
}
If I’ve guessed the wrong types for this variables then the rest of this answer probably won’t make sense.
Assuming that bkp_subnet
is a string, I further assume therefore that you’re expecting to find multiple subnets that all have the same Name
tag, and so you’re using data "aws_subnet_ids" "bkp"
to find the ID for each of those, and then use data "aws_subnet" "bkp"
to get the rest of the attributes of each of them.
With that said then, it seems like you only really need zero or one instances of data "aws_subnet_ids" "bkp"
, because a single instance of this data source returns more than one id
. I think the following should work:
data "aws_subnet_ids" "bkp" {
count = var.bkp_eni_required ? 1 : 0
vpc_id = data.aws_vpc.this.id
tags = {
Name = var.bkp_subnet
}
}
data "aws_subnet" "bkp" {
for_each = toset(flatten(data.aws_subnet_ids.bkp[*].ids))
id = each.key
}
The for_each
expression here has a few different things going on which I’ll explain separately:
-
data.aws_subnet_ids.bkp[*].ids
is a splat expression, serving as a concise way of producing a list of all of the sets of IDs across all instances of this resource. In practice there can only be zero or one instances, so this will either be an empty list or a list containing a single set. This is similar to what you were creating in your example, which led to the error because it’s a list of sets rather than just a set.
-
flatten
takes the list of sets of strings and flattens it into just a list of strings. Since the list can only have zero or one elements, this really just amounts to unwrapping the elements of the single set.
-
toset
converts the list of strings into a list of sets, as required by for_each
.