Home > Software design >  terraform using for_each to find data source
terraform using for_each to find data source

Time:11-02

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 ?

CodePudding user response:

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.

CodePudding user response:

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 ]
    }
  ]
}
  • Related