Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

how to access all elements of a list variable in the policy argument of aws_iam_user_policy resource in terraform

I have an aws_iam_user_policy resource in terraform as follows:

resource "aws_iam_user_policy" "pol" {
  name = "policy"
  user = aws_iam_user.singleuser.name

  policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "s3:List*"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::toybucket-development/*",
        "arn:aws:s3:::toybucket-staging/*",
        "arn:aws:s3:::toybucket-production/*"
      ]
    }
  ]
}
EOF
}

The resources with development, staging and production are something I’m hoping to put in one line through using a list variable with the values development, staging and production and somehow looping through them, but I’m unsure of how to do this within the EOF. I know normally you can loop through such list variable but that’s in normal terraform and not when you have this EOF with a string that represents a json. Would anyone know of a solution?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You can do this most easily with a Terraform template, and the templatefile function. The templatefile function invocation would appear like:

resource "aws_iam_user_policy" "pol" {
  name = "policy"
  user = aws_iam_user.singleuser.name

  policy = templatefile("${path.module}/policy.tmpl", { envs = ["development", "staging", "production"] }
}

The documentation for the function is probably helpful.

The template would appear like:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "s3:List*"
      ],
      "Effect": "Allow",
      "Resource": [
        %{~ for env in envs ~}
        "arn:aws:s3:::toybucket-${env}/*"%{ if env != envs[length(envs) - 1] },%{ endif }
        %{~ endfor ~}
      ]
    }
  ]
}

That check at the end for adding a comma only if it is not the last element to ensure JSON format syntax is not super great. However, there is no easy check in Terraform DSL for whether a list/slice (latter being implicitly derived from Golang) is the last element, and using jsonencode would require placing the entire ARN in the variable list.

If envs = ["arn:aws:s3:::toybucket-development/*", "arn:aws:s3:::toybucket-staging/*", "arn:aws:s3:::toybucket-production/*"], then you could jsonencode(envs).

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading