Okay! I think I understand this now. Thanks for working through this with me.
From your earlier examples it seems like your lambda functions are defined by local.restapi.options.restapi.lambdas. For the sake of focusing only on the task at hand here I’m going to shorten that just to local.lambdas here but still keep your shown structure where each element of lambdas has an attribute function giving the function name and an attribute signing indicating whether it should have a signing object.
So for my simplified example, we’ll say there’s a data structure like this:
locals {
lambdas = [
{
function = "auth"
signing = true
},
{
function = "get"
signing = false
},
]
}
This data structure seems to meet the first requirement for a for_each expression: it has one element per lambda function instance we want to declare, and each one has a unique key in the form of the function attribute value. Threfore we should be able to use this in the for_each of the lambda function with just one more projection to make it be a map instead of a list, as for_each requires:
resource "aws_lambda_function" "example" {
for_each = { for l in local.lambdas : l.function => l }
name = each.value.function
# ...
}
Your other requirement was to declare one aws_lambda_code_signing_config per function, but only if its corresponding definition has signing set. You can achieve that by copying the for expression from the previous resource and adding an if clause to it:
resource "aws_lambda_code_signing_config" "example" {
for_each = {
for l in local.lambdas : l.function => l
if l.signing
}
# ...
}
Writing for l in local.lambdas means that inside the body of the for expression there is a temporary symbol l that refers to each of the element values of local.lambdas in turn. In the original example we used that to access l.function to get the function name, and in this second resource I’ve also added if l.signing, which accesses the signing attribute of the current object. The result then will be a filtered version of the collection which keeps only the elements where l.signing is true.
In a sense we could say that l inside this expression serves a similar function as each.value in the rest of the resource configuration. That follows here because the for expression projects to l.function => l and so the values of the resulting map exactly match the values of the input list. But we can’t use each.value directly inside the for expression, because as I was noting previously it’s this expression that decides what values each.value would take, and so we don’t yet know what value that should return.
Likewise it wouldn’t be valid to use l in the expression that comes directly after in, because that expression is deciding which values l will take. We have to identify a specific single collection here, which the for expression will then take values from.
I hope that makes sense! I tried to cut down the example here so we could focus only on the for expressions and the for_each arguments and not on all of the other seeminly-unrelated parts generating the big local.restapi data structure, although if you have success with my examples here but aren’t sure how to adapt them to work with your existing configuration then I’d be happy to help with that if you can again explain what the goal of each part is, so that I can then suggest a solution that will meet the goal.