Terraform Using For_Each to Find Data Source

Terraform Using For_Each to Find Data Source

In a aws_ssoadmin_permission_set_inline_policy ressource, i'm using a for_each to parse a list of name corresponding to my data source name. It doesn't work when using the each.key but wokring when hard coding the value inline_policy = data.aws_iam_policy_document.emobg-sso-billing-admin.json

data "aws_iam_policy_document" "emobg-sso-billing-admin" {
  statement {
    sid    = "VisualEditor0"
    effect = "Allow"
    actions = [
      "aws-marketplace:*",
      "aws-portal:*",
      "budgets:*"
    ]
    resources = [
      "*",
    ]
  }
}

data "aws_iam_policy_document" "emobg-sso-billing-audit" {
  statement {
    sid    = "VisualEditor0"
    effect = "Allow"
    actions = [
      "support:*",
      "tag:*",
      "s3:*"
    ]
    resources = [
      "*",
    ]
  }
}

resource "aws_ssoadmin_permission_set" "emobg" {
  for_each = toset(local.permission_sets_name)

  name             = each.key
  description      = each.key
  instance_arn     = local.sso_instance_arn
  session_duration = local.session_duration
}

resource "aws_ssoadmin_permission_set_inline_policy" "emobg" {
  for_each           = toset(local.permission_sets_name)

  inline_policy      = format("data.aws_iam_policy_document.%s.json", each.key) # <-- doesn't works
#  inline_policy      = data.aws_iam_policy_document.emobg-sso-billing-admin.json # <-- works
  instance_arn       = local.sso_instance_arn
  permission_set_arn = aws_ssoadmin_permission_set.emobg[each.key].arn
}

locals {
  session_duration    = "PT8H"

  permission_sets_name = [
    "emobg-sso-billing-admin",
    "emobg-sso-billing-audit",
  ]
}

The error message is:

2022-11-01T01:19:43.923+0100 [ERROR] vertex "aws_ssoadmin_permission_set_inline_policy.emobg[\"emobg-sso-billing-admin\"]" error: "inline_policy" contains an invalid JSON policy
2022-11-01T01:19:43.923+0100 [ERROR] vertex "aws_ssoadmin_permission_set_inline_policy.emobg (expand)" error: "inline_policy" contains an invalid JSON policy
╷
│ Error: "inline_policy" contains an invalid JSON policy
│
│   with aws_ssoadmin_permission_set_inline_policy.emobg["emobg-sso-billing-admin"],
│   on permission_set.tf line 13, in resource "aws_ssoadmin_permission_set_inline_policy" "emobg":
│   13:   inline_policy      = format("data.aws_iam_policy_document.%s.json", each.value)

I really don't understand what's wrong with the JSON policy because it's the same. Maybe I missed something ?

2 Answers

Because you are using format("data.aws_iam_policy_document.%s.json", each.key), the policy will be literal string "data.aws_iam_policy_document.%s.json".

You have only single policy, so you have to use it directly:

 inline_policy      = data.aws_iam_policy_document.emobg-sso-billing-admin.json 

that's why it works. You do not have more then one aws_iam_policy_document in your code.

Thanks to Marcin, who give me the anser in comment: You can't do what you want. TF does not support dynamic references to different resources.

2

As it was mentioned, it's not allowed from terraform to make a dynamic references, so I finally used a map even if the name of the policy is the same of the base name.

data "aws_iam_policy_document" "emobg-sso-billing-admin" {
  statement {
    sid    = "VisualEditor0"
    effect = "Allow"
    actions = [
      "aws-marketplace:*",
      "aws-portal:*",
      "budgets:*"
    ]
    resources = [
      "*",
    ]
  }
}

data "aws_iam_policy_document" "emobg-sso-billing-audit" {
  statement {
    sid    = "VisualEditor0"
    effect = "Allow"
    actions = [
      "support:*",
      "tag:*",
      "s3:*"
    ]
    resources = [
      "*",
    ]
  }
}

... [ ALL OTHERS DATA SOURCES POLICIES ARE LISTED HERE ]

resource "aws_ssoadmin_permission_set" "emobg" {
  for_each = local.permission_set_map

  name             = each.key
  description      = each.key
  instance_arn     = local.sso_instance_arn
  session_duration = local.session_duration
}

resource "aws_ssoadmin_permission_set_inline_policy" "emobg" {
  for_each = local.inline_policies_map

  inline_policy      = each.value
  instance_arn       = local.sso_instance_arn
  permission_set_arn = aws_ssoadmin_permission_set.emobg[each.key].arn
}

locals {
  session_duration = "PT8H"
  permission_set_map  = { for ps in local.permission_sets : ps.name => ps }
  inline_policies_map = { for ps in local.permission_sets : ps.name => ps.inline_policy if ps.inline_policy != "" }
}

locals {
  permission_sets = [
    {
      name          = "emobg-sso-billing-admin",
      inline_policy = data.aws_iam_policy_document.emobg-sso-billing-admin.json
    },
    {
      name          = "emobg-sso-billing-audit",
      inline_policy = data.aws_iam_policy_document.emobg-sso-billing-audit.json
    },
    {
      ... [ All MY POLICIES ARE LISTED HERE ]
    }
  ]
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

David Miller
Author

David Miller

David Miller brings 15 years of experience in global economics, personal finance strategy, and market dynamics. He specializes in turning complex economic trends into actionable insights for everyday readers.