Search code examples
amazon-web-servicesterraformamazon-iamterraform-provider-aws

Passing List to IAM Group Policy Template file


I am creating policy based on tags. The environment value differs for each resource, so I have to add them as multiple values. Unable to pass as list. Tried join,split and for loop. None of them works. Pls help. Below code just add the value as "beta,test" which will not work as expected

main.tf

locals{
    workspaceValues = terraform.workspace == "dev" ? ["alpha", "dev"] : terraform.workspace == "test" ? ["beta", "test"] : ["prod", "staging"]
}

resource "aws_iam_group_policy" "inline_policy" {
  name   = "${terraform.workspace}_policy"
  group  = aws_iam_group.backend_admin.name
  policy = templatefile("policy.tpl", { env = join(",", local.workspaceValues), region = "${data.aws_region.current.name}", account_id = "${data.aws_caller_identity.current.account_id}" })
}

policy.tpl:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ec2:*",
            "Resource": "*",
            "Condition": {
                "ForAllValues:StringLikeIfExists": {
                    "aws:ResourceTag/Environment": "${env}"
                }
            }
        }
    ]
}

Solution

  • You can use jsonencode to properly format TF list as a list in json in your template:

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": "ec2:*",
                "Resource": "*",
                "Condition": {
                    "ForAllValues:StringLikeIfExists": {
                        "aws:ResourceTag/Environment": ${jsonencode(env)}
                    }
                }
            }
        ]
    }
    

    For that you would call the template as follows:

    resource "aws_iam_group_policy" "inline_policy" {
      name   = "${terraform.workspace}_policy"
      group  = aws_iam_group.backend_admin.name
      policy = templatefile("policy.tpl", { 
                            env = local.workspaceValues
                           })
    }
    

    You are not using region nor account_id in your template, so there is no reason to pass them in.