terraform using for_each to find data source
Emily Wong
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.
2As 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 ] } ]
}