Reputation: 1557
I've got a CloudFormation template that creates an SNS topic and subscription
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources" : {
"EmailSNSTopic": {
"Type" : "AWS::SNS::Topic",
"Properties" : {
"DisplayName" : "${display_name}"
}
},
"MySubscription": {
"Type": "AWS::SNS::Subscription",
"Properties": {
"TopicArn" : { "Ref" : "EmailSNSTopic" },
"${details}"
}
}
},
"Outputs" : {
"ARN" : {
"Description" : "Email SNS Topic ARN",
"Value" : { "Ref" : "EmailSNSTopic" }
}
}
}
Which I'm trying to call via terrform.
But I keep getting this error
Error: "template_body" contains an invalid JSON: invalid character '{' looking for beginning of object key string
My Terraform configuration looks like this.
provider "aws" {
region = "eu-west-2"
}
data "template_file" "sns_stack" {
template = file("${path.module}/templates/email-sns-stack.json.tpl")
vars = {
display_name = var.display_name
details = join(",", formatlist("{ \"Endpoint\": \"%s\", \"Protocol\": \"%s\" }", var.email_list, var.protocol))
}
}
resource "aws_cloudformation_stack" "sns_topic" {
name = var.stack_name
template_body = data.template_file.sns_stack.rendered
tags = merge(
map("Name", var.stack_name)
)
}
And my variables.tf
looks like this
default = "Admin"
}
variable "email_list" {
default = [
"[email protected]",
"[email protected]"
]
}
variable "protocol" {
default = "email"
}
variable "stack_name" {
default = "sns-test"
}
I expect that ${details}
should spit out my Endpoint and Protocol but it doesn't.
What am I doing wrong?
Upvotes: 1
Views: 3729
Reputation: 238199
What you want to achieve is rather complex, but doable. You can do this using the following template:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources" : ${jsonencode(
merge({for idx, email_address in email_list:
"EmailSubs${idx}" => {
Type = "AWS::SNS::Subscription"
Properties = {
"Endpoint" = email_address
"Protocol" = protocol
"TopicArn" = { "Ref" = "EmailSNSTopic" }
}
}},
{
"EmailSNSTopic" = {
"Type" = "AWS::SNS::Topic",
"Properties" = {
"DisplayName" = "${display_name}"
}
}}
))},
"Outputs" : {
"ARN" : {
"Description" : "Email SNS Topic ARN",
"Value" : { "Ref" : "EmailSNSTopic" }
}
}
}
and TF code:
locals {
template_body = templatefile("./email-sns-stack2.json.tpl", {
display_name = var.display_name
email_list = var.email_list
protocol = var.protocol
})
}
resource "aws_cloudformation_stack" "sns_topic" {
name = var.stack_name
template_body = local.template_body
tags = merge(
map("Name", var.stack_name)
)
}
Upvotes: 1