Data source and adding multiple dynamic resources values

I’m attempting to create a data source IAM policy document that includes three SSM Parameters as resources, but having difficulty working out the correct syntax. The code below generates the following error:

│ Error: Unsupported attribute

│ on data.tf line 36, in data “aws_iam_policy_document” “deployment_group_api”:
│ 36: for parameter in aws_ssm_parameter.deployment_group_api[*] : parameter.arn

│ This object does not have an attribute named “arn”.

resource "aws_ssm_parameter" "deployment_group_api" {
  for_each = local.envs
.
.
}

data "aws_iam_policy_document" "deployment_group_api" {
  statement {
    effect = "Allow"
    actions = [
      "ssm:GetParameter"
    ]
    resources = [
      for parameter in aws_ssm_parameter.deployment_group_api[*] : parameter.arn
    ]
  }
}

Documentation for the resource type aws_ssm_parameter states that it does have the attribute named arn, so I’m not understanding what is going wrong.

The end result I’m looking to achieve is equivalent to:

data "aws_iam_policy_document" "deployment_group_api" {
  statement {
    effect = "Allow"
    actions = [
      "ssm:GetParameter"
    ]
    resources = [
      aws_ssm_parameter.deployment_group_api["one"].arn,
      aws_ssm_parameter.deployment_group_api["two"].arn,
      aws_ssm_parameter.deployment_group_api["three"].arn
    ]
  }
}

Any help provided would be greatly appreciated.

It is not valid to use [*] with things that look like maps - like resources using for_each. The [*] operator is only for use with things that look like lists.

You need to be writing something more like

[for key, value in aws_ssm_parameter.deployment_group_api: some_expression_here]

Many thanks for the reply, maxb. Much appreciate it as it has helped me workout the right syntax.

resources = [
  for key, value in aws_ssm_parameter.deployment_group_api : aws_ssm_parameter.deployment_group_api[key].arn
]

Lack of experience, and previously only every referenced a resource via type.local_name.attribute, I hadn’t cottoned on to the fact that aws_ssm_parameter.deployment_group_api was a map. All good now.

Thanks again.

That’s a bit redundant, you could just write:

resources = [
  for key, value in aws_ssm_parameter.deployment_group_api : value.arn
]

in which case you might choose to replace key and value with more context-appropriate names:

resources = [
  for _, resource in aws_ssm_parameter.deployment_group_api : resource.arn
]

or if you prefer, you might choose to express it in this alternative form:

resources = values(aws_ssm_parameter.deployment_group_api)[*].arn

Thanks for the master class, maxb. You’ve greatly improved not only my understanding, but the cleanliness and readability of the TF scripts I’ve been creating with your pointers about making the code a bit more compact. Greatly appreciate the help.

1 Like