'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?
Solution 1:[1]
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).
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Matt Schuchard |
