Can you add an output of resource inside a variable?

Hi Discuss @Hasicorp.

Just another TF question…

Are you able to add aws_iam_policy.PolicyIAMManageOwnMFA.id to my variable stated below. I’m having issues when passing it as a string via “for_each toset()” in aws_iam_group_policy_attachment. I plan to add an AWS of the shelf policy & a custom created one and attach them both to my “Administrator” IAM group.

  resource "aws_iam_policy" "PolicyIAMManageOwnMFA" {
      name   = "test_PolicyIAMManageOwnMFA"
      policy = file("${path.module}/policies/PolicyIAMManageOwnMFA.json")
    }

resource "aws_iam_group_policy_attachment" "adminstrator-attach" {
  for_each   = toset(var.admin-policies)
  group      = "Administrators"
  policy_arn = each.key
}


variable admin-policies {
  default = [""arn:aws:iam::aws:policy/AdministratorAccess", "aws_iam_policy.PolicyIAMManageOwnMFA.id"]
}

Can anyone shed any light on my dilemma.

Thanks

Samit Patel

Hi @samitpatel55,

Input variables are for values provided by the calling module (or the -var and -var-file command line options, if this is a root module). For values you want to compute inside your module you can use Local Values, like this:

locals {
  admin_policies = [
    "arn:aws:iam::aws:policy/AdministratorAccess", 
    aws_iam_policy.PolicyIAMManageOwnMFA.id,
  ]
}

To refer to this one you’d use local.admin_policies instead of var.admin_policies.

resource "aws_iam_policy" "PolicyIAMManageOwnMFA" {
  name = "test_PolicyIAMManageOwnMFA"
  policy = file("${path.module}/policies/PolicyIAMManageOwnMFA.json")
}

resource "aws_iam_group_policy_attachment" "adminstrator_attach" {
  for_each   = toset(local.admin_policies)
  group      = "Administrators"
  policy_arn = each.key
  depends_on = [aws_iam_policy.PolicyIAMManageOwnMFA]
}

locals {
  admin_policies = concat(var.admin_policies, [aws_iam_policy.PolicyIAMManageOwnMFA.arn])
}

variable admin_policies {
  type = list(string)
  default = ["arn:aws:iam::aws:policy/AdministratorAccess"]
}

This code crash with the error

  on main.tf line 21, in resource "aws_iam_group_policy_attachment" "adminstrator_attach":
  21:   for_each   = toset(local.admin_policies)

The "for_each" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the for_each depends on.

I would recommend to do it like this

#---------------------------------------------------#
# default MFA Policy
#---------------------------------------------------#

resource "aws_iam_policy" "PolicyIAMManageOwnMFA" {
  name = "test_PolicyIAMManageOwnMFA"
  policy = file("${path.module}/policies/PolicyIAMManageOwnMFA.json") 
}

resource "aws_iam_group_policy_attachment" "OwnMFA" {
  group      = "Administrators"
  policy_arn = aws_iam_policy.PolicyIAMManageOwnMFA.arn
  depends_on = [aws_iam_policy.PolicyIAMManageOwnMFA]
}

#---------------------------------------------------#
# additonal policies
#---------------------------------------------------#

resource "aws_iam_group_policy_attachment" "adminstrator_attach" {
  for_each   = toset(var.admin_policies)
  group      = "Administrators"
  policy_arn = each.key
}

variable admin_policies {
  type = list(string)
  default = ["arn:aws:iam::aws:policy/AdministratorAccess"]
}

Thanks both @apparentlymart & @yamb00 for you responses.

This is what eventually worked for me

resource "aws_iam_group_policy_attachment" "adminstrator_attach" {
  depends_on = [aws_iam_group.aws_groups]
  for_each   = toset(var.admin-policies)
  group      = "Administrators"
  policy_arn = each.key
}

resource "aws_iam_group_policy_attachment" "administrator_own_mfa" {
  depends_on = [aws_iam_policy.PolicyIAMManageOwnMFA, aws_iam_policy.CodeCommitPortalAccess]
  count = length(local.admin-custom-p)
  group      = "Administrators"
  policy_arn = local.admin-custom-p[count.index]
}

variable admin-policies {
  default = ["arn:aws:iam::aws:policy/AdministratorAccess", "arn:aws:iam::aws:policy/AWSCodeCommitPowerUser"]
}

locals  {
  admin-custom-p = [aws_iam_policy.PolicyIAMManageOwnMFA.id, aws_iam_policy.CodeCommitPortalAccess.id]
}  

I would be grateful for your feedback on using “count” for attach my local values, as it seems to work for me over “for_each”.

Using count here is okay but has an important consequence: if you ever add new elements to local.admin-custom-p then you must always add them to the end of the list, because the aws_iam_group_policy_attachment.administrator_own_mfa instances will be identified by the numeric positions of the elements in the list.

Similarly, you won’t be able to remove any elements from the list unless they are at the end of the list, because that would renumber all of the elements after it.

The typical advantage of using for_each is that you get to define which tracking key Terraform should use for each of the instances, and so you can freely add and remove instances as long as they all have unique keys.