Reputation: 351
I have an example of this below from my main.tf. For some reason it forces double quotes on the template variables to wrap around on my template file while examples from other sources using below without quote wrap:
%{ for i in split(",",mylist) ~}
Here's a value: ${i}
%{ endfor }
My syntax shows no error on the file but it will error out when running it "%{ for addr in split(",",source_vpcs) ~} ${addr} %{ endfor ~}"
i am getting this error: Invalid function argument; Invalid value for "str" parameter: string required..
how can I correctly make use of the list? source_vpcs = ["vpc1212","vpc21"]
#i am trying to pass this from the main.tf to pass into aws_vpc_endpoint resource and into its policy attribute.
policy = templatefile("../templates/access_polices.tmpl",
{
s3env = "dev"
account_num = "8888888"
source_vpcs = local.source_vpcs
}
)
here is an the tmpl file ####new content###
${jsonencode(
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "xx",
"Effect": "Deny",
"Action": [
"s3:GetObject"
],
"Resource": [
"*"
],
"Condition": {
"StringNotEquals": {
"aws:SourceVpc": "${source_vpcs}",
"s3:ResourceAccount": "${account_number}"
}
}
},
]
}
)}
This is my a sample output that I want to achieve
"Condition": {
"StringNotEquals": {
"aws:SourceVpc":
[
"vpc-888888888f",
"vpc-999999999f"
]
,
"s3:ResourceAccount":
[
888888888
]
}
Upvotes: 1
Views: 5974
Reputation: 4472
You're passing source_vpcs
in as a list, then trying to split a list on ","
.
Since you're already passing in a list, you don't need to do the split; it's already in different elements. So, just get rid of the split
and try this:
"%{ for addr in source_vpcs ~} ${addr} %{ endfor ~}"
EDIT: This minimal example works fine for me, no errors.
template.txt
%{ for v in mylist ~}
Here's a value: ${v}
%{ endfor }
main.tf
resource "local_file" "template_test" {
content = templatefile("./template.txt", {
mylist = [
"value 1",
"value 2"
]
})
filename = "./output.txt"
}
output.txt
Here's a value: value 1
Here's a value: value 2
EDIT 2: I don't know what you're trying to do with this JSON, and you should really consider using the aws_iam_policy_document data source for IAM policies like this, but here's how you can create the JSON string:
locals {
source_vpcs = [
"vpc-888888888f",
"vpc-999999999f"
]
account_number = 888888888
jsonstring = jsonencode({
Version = "2012-10-17",
Statement = [
{
Sid = "xx",
Effect = "Deny",
Action = [
"s3:GetObject"
],
Resource = [
"*"
],
Condition = {
StringNotEquals = {
"aws:SourceVpc" = local.source_vpcs,
"s3:ResourceAccount" = local.account_number
}
}
}
]
})
}
output "jsonstring" {
value = local.jsonstring
}
Now you can use local.jsonstring
anywhere you want to use that string (like in an IAM policy). If you really want to output it to a file, you can add:
resource "local_file" "jsonfile" {
content = local.jsonstring
filename = "./policy.json"
}
And now policy.json
will have your JSON content.
EDIT 3: Try this:
templatedir/policytemplate.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "xx",
"Effect": "Deny",
"Action": [
"s3:GetObject"
],
"Resource": [
"*"
],
"Condition": {
"StringNotEquals": {
"aws:SourceVpc": ${jsonencode(vpc_ids)},
"s3:ResourceAccount": "${account_number}"
}
}
},
]
}
main.tf
locals {
jsonpolicy = templatefile("./templatedir/policytemplate.json", {
vpc_ids = [
"vpc_1",
"vpc_2"
]
account_number = 888888
})
}
output "jsonpolicy" {
value = local.jsonpolicy
}
Upvotes: 1