Search code examples
amazon-web-servicesterraformamazon-snsterraform-provider-aws

How to create a template using terraform loop


I want to create CFT using terraform template_file by loping based on a list variable(email_addresses). Below are the variables and template I am trying to generate.

variables:-

emails_addresses = ["sample-1@gmail.com", "sample-2@gmail.com"]
sns_arn = "arn:aws:sns:us-east-1:xxxxxx:xxxx"
protocol = "email"

Expecting template:

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Resources": {
        "sample-1": {
            "Type": "AWS::SNS::Subscription",
            "Properties": {
                "Endpoint": "sample-1@gmail.com",
                "Protocol": "email",
                "TopicArn": "arn:aws:sns:us-east-1:xxxx:xxxxx"
            }
        },
        "sample-2": {
            "Type": "AWS::SNS::Subscription",
            "Properties": {
                "Endpoint": "sample-2@gmil.com",
                "Protocol": "email",
                "TopicArn": "arn:aws:sns:us-east-1:xxx:xxxx"
            }
        }
    }
}

The resource name in CFT can be some random string but it should be the same per mail in case of multiple plans/apply.


Solution

  • This one is a bit tricky due to json. Also I would use templatefile instead of template_file as you can pass lists into it.

    variable "emails_addresses" {
      default = ["sample-1@gmail.com", "sample-2@gmail.com"]
    }
    
    variable "sns_arn" {
      default = "arn:aws:sns:us-east-1:xxxxxx:xxxx"
    }
    
    variable "protocol" {
      default = "email"
    }
    
    output "test" {
       value = templatefile("./email-sns-stack.json.tpl", {
         emails_addresses = var.emails_addresses,
         sns_arn = var.sns_arn,
         protocol = var.protocol  
       })
     }
    

    where email-sns-stack.json.tpl is:

    {
        "AWSTemplateFormatVersion": "2010-09-09",
        "Resources": ${jsonencode(
            {for email_address in emails_addresses: 
            split("@",email_address)[0] => {
              Type = "AWS::SNS::Subscription"
              Properties = {
                    "Endpoint" = email_address
                    "Protocol" = protocol
                    "TopicArn" = sns_arn          
              }
            }})}
    }
    

    The output, after pretty json formatting for readability:

    {
      "AWSTemplateFormatVersion": "2010-09-09",
      "Resources": {
        "sample-1": {
          "Properties": {
            "Endpoint": "sample-1@gmail.com",
            "Protocol": "email",
            "TopicArn": "arn:aws:sns:us-east-1:xxxxxx:xxxx"
          },
          "Type": "AWS::SNS::Subscription"
        },
        "sample-2": {
          "Properties": {
            "Endpoint": "sample-2@gmail.com",
            "Protocol": "email",
            "TopicArn": "arn:aws:sns:us-east-1:xxxxxx:xxxx"
          },
          "Type": "AWS::SNS::Subscription"
        }
      }
    }