skip to Main Content

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


  1. Chosen as BEST ANSWER

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

  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search