Preformatted textOn Terraform Cloud, I am working on setting up an S3 bucket policy targeted for Cloud Trail service logging, which is why I would like to list multiple related accounts in the “Resources” section like this:
# Log bucket policy
resource "aws_s3_bucket_policy" "log-bucket-policy" {
bucket = aws_s3_bucket.log-bucket.id
policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
... # Some more statements going here
"Action": "s3:PutObject",
"Resource": "${[formatlist("%v", ["a", "b"])]}",
]
}
POLICY
}
This configuration gives me “Cannot include the given value in a string template: string required.” Any clue as to what I am doing wrong?
P.s.: Interestingly enough, if I leave out the ${...}
and go with formatlist(...)
directly, as I understand I should be able to in the most recent version of Terraform, it tells me that I am providing a wrong character in a json structure (“o”, while “a” is expected, hinting at the parser expecting “false” instead of “formatlist”)
The expression inside a ${ ... }
must always return something that can be converted to a string, because otherwise Terraform can’t concatenate it with the literal string before and after in order to produce a single string result.
To include that result in your output would require converting it to string in some way, such as using jsonencode
. However, since this entire value is JSON, I’d suggest generating the whole thing using jsonencode
rather than trying to build JSON using string templates:
policy = jsonencode({
"Version": "2012-10-17",
"Statement": [
# ...some more statements going here
"Action": "s3:PutObject",
"Resource": ["a", "b"],
],
})
By using jsonencode
you can let Terraform worry about the JSON encoding and just write out the data structure you want to encode. I just used ["a", "b"]
literally there because I guessed that your goal was to just generate a plain array of strings as IAM expects, but you can put any expression that returns a list of strings in that position, such as a reference to an arn
attribute of some other resource that you want to grant access to/from.
1 Like
Using jsonecode() did the trick, many thanks, Martin!