<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[A Walk in the Clouds]]></title><description><![CDATA[Trying my best to share knowledge]]></description><link>https://reshma-cloud.com</link><generator>RSS for Node</generator><lastBuildDate>Sat, 01 Aug 2026 13:25:38 GMT</lastBuildDate><atom:link href="https://reshma-cloud.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Security Group with My IP]]></title><description><![CDATA[Security is of paramount importance. How many times have we seen or heard that we should “NEVER” allow complete internet access to our security group??
So now you are doing AWS Hands-on and would like to create and attach a security group to your ec2...]]></description><link>https://reshma-cloud.com/security-group-with-my-ip</link><guid isPermaLink="true">https://reshma-cloud.com/security-group-with-my-ip</guid><category><![CDATA[#Terraform #AWS #InfrastructureAsCode #Provisioning #Automation #CloudComputing]]></category><dc:creator><![CDATA[Reshma A]]></dc:creator><pubDate>Mon, 28 Oct 2024 12:23:58 GMT</pubDate><content:encoded><![CDATA[<p>Security is of paramount importance. How many times have we seen or heard that we should <strong>“NEVER”</strong> allow complete internet access to our security group??</p>
<p>So now you are doing AWS Hands-on and would like to create and attach a security group to your ec2 instance where you can login only from <strong>YOUR IP</strong>. How is that achieved?</p>
<p>Its simple now</p>
<p>Begin with writing a Bash script to read your current IP and lets call it "my-ip.sh”</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-comment"># Fetch the public IP address using an external service</span>
ip_address=$(curl -s https://api.ipify.org)

<span class="hljs-comment"># Output the public IP address</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"{\"ip\": \"<span class="hljs-variable">${ip_address}</span>\"}"</span>
</code></pre>
<p>Don’t forget to make it an executable file</p>
<pre><code class="lang-bash">$ chmod +x my-ip.sh
</code></pre>
<p>Next lets write simple Terraform code where we create a VPC and add Security Groups with one ingress rule of type SSH and the source to be my IP.</p>
<pre><code class="lang-bash">terraform {
  required_providers {
    aws = {
      <span class="hljs-built_in">source</span>  = <span class="hljs-string">"hashicorp/aws"</span>
      version = <span class="hljs-string">"~&gt; 5.0.0"</span>
    }
  }
}

provider <span class="hljs-string">"aws"</span> {
  region  = var.region
  profile = var.profile
}

provider <span class="hljs-string">"local"</span> {}
</code></pre>
<p>Let’s add variables too</p>
<pre><code class="lang-bash">variable <span class="hljs-string">"region"</span> {
  <span class="hljs-built_in">type</span>    = string
  default = <span class="hljs-string">"us-east-1"</span>
}

variable <span class="hljs-string">"profile"</span> {
  <span class="hljs-built_in">type</span>    = string
  default = <span class="hljs-string">"default"</span>
}
</code></pre>
<p>Now adding the data file</p>
<pre><code class="lang-bash">data <span class="hljs-string">"aws_caller_identity"</span> <span class="hljs-string">"current"</span> {}

data <span class="hljs-string">"aws_region"</span> <span class="hljs-string">"current"</span> {}

data <span class="hljs-string">"aws_vpc"</span> <span class="hljs-string">"get_vpc_id"</span> {
  filter {
    name   = <span class="hljs-string">"tag:Name"</span>
    values = [<span class="hljs-string">"ANW-VPC"</span>]
  }
  depends_on = [aws_vpc.hands_on_VPC]
}

data <span class="hljs-string">"external"</span> <span class="hljs-string">"my_ip"</span> {
  program = [<span class="hljs-string">"bash"</span>, <span class="hljs-string">"<span class="hljs-variable">${path.module}</span>/my-ip.sh"</span>]
}
</code></pre>
<p>Now creating a very simple VPC</p>
<pre><code class="lang-bash">resource <span class="hljs-string">"aws_vpc"</span> <span class="hljs-string">"hands_on_VPC"</span> {
  cidr_block           = <span class="hljs-string">"10.0.0.0/16"</span>
  enable_dns_support   = <span class="hljs-literal">true</span>
  enable_dns_hostnames = <span class="hljs-literal">true</span>

  tags = {
    Name = <span class="hljs-string">"ANW-VPC"</span>
  }
}
</code></pre>
<p>Time to create Security Groups of both default and a custom one with my ip as one ingress rule</p>
<pre><code class="lang-bash">resource <span class="hljs-string">"aws_default_security_group"</span> <span class="hljs-string">"default"</span> {
  vpc_id = data.aws_vpc.get_vpc_id.id
  ingress {
    protocol  = -1
    self      = <span class="hljs-literal">true</span>
    from_port = 0
    to_port   = 0
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = <span class="hljs-string">"-1"</span>
    cidr_blocks = [<span class="hljs-string">"0.0.0.0/0"</span>]
  }
  tags = {
    Name = <span class="hljs-string">"default"</span>
  }
}

resource <span class="hljs-string">"aws_security_group"</span> <span class="hljs-string">"sg-ssh"</span> {
  vpc_id = data.aws_vpc.get_vpc_id.id
  name   = <span class="hljs-string">"new"</span>
  tags = {
    Name = <span class="hljs-string">"new"</span>
  }
}

resource <span class="hljs-string">"aws_vpc_security_group_ingress_rule"</span> <span class="hljs-string">"ssh"</span> {
  ip_protocol       = <span class="hljs-string">"tcp"</span>
  to_port           = 22
  from_port         = 22
  cidr_ipv4         = <span class="hljs-string">"<span class="hljs-variable">${data.external.my_ip.result["ip"]}</span>/32"</span>
  security_group_id = aws_security_group.sg-ssh.id
}
</code></pre>
<p>Since the Security Group requires a proper CIDR notation, we use</p>
<pre><code class="lang-bash"><span class="hljs-string">"<span class="hljs-variable">${data.external.my_ip.result["ip"]}</span>/32"</span>
</code></pre>
<p>And thats the end of it……. Try it and let me know</p>
]]></content:encoded></item><item><title><![CDATA[EC2 instance - without "hardcoding" AMI]]></title><description><![CDATA[What can be the greatest nightmare for any DevOps consultant?
Ans : Ever changing AMI id of EC2 instances and the constant need to change them in the Terraform template.
There is a fix for this too.
All that needs to be done is get the "latest" AMI d...]]></description><link>https://reshma-cloud.com/ec2-instance-without-hardcoding-ami</link><guid isPermaLink="true">https://reshma-cloud.com/ec2-instance-without-hardcoding-ami</guid><dc:creator><![CDATA[Reshma A]]></dc:creator><pubDate>Fri, 17 Nov 2023 16:17:43 GMT</pubDate><content:encoded><![CDATA[<p>What can be the greatest nightmare for any DevOps consultant?</p>
<p>Ans : Ever changing AMI id of EC2 instances and the constant need to change them in the Terraform template.</p>
<p>There is a fix for this too.</p>
<p>All that needs to be done is get the "latest" AMI dynamically into your code base.</p>
<pre><code class="lang-go">data <span class="hljs-string">"aws_ami"</span> <span class="hljs-string">"amazon-linux-2"</span> {
  most_recent = <span class="hljs-literal">true</span>

  filter {
    name   = <span class="hljs-string">"owner-alias"</span>
    values = [<span class="hljs-string">"amazon"</span>]
  }

  filter {
    name   = <span class="hljs-string">"name"</span>
    values = [<span class="hljs-string">"amzn2-ami-hvm-*-x86_64*"</span>]
  }
}

resource <span class="hljs-string">"aws_instance"</span> <span class="hljs-string">"amzn2_linux_instance"</span> {
  ami           = data.aws_ami.amazon-linux<span class="hljs-number">-2.i</span>d
  instance_type = <span class="hljs-string">"t2.micro"</span>
}
</code></pre>
<p>Data Source is used to query and select the latest AMI. Let me explain the parameters here</p>
<ul>
<li><p>most_recent - Returns the most recent AMI, if there are more than one result</p>
</li>
<li><p>filter1 - name is "owner-alias" is "amazon". As Amazon is the owner of Amazon2 Linux owner</p>
</li>
<li><p>filter2 - "name" is the variable for the Amazon AMI name.</p>
</li>
</ul>
<p>Pass these filtered values to "aws_instance" resource and you will have created your ec2 instance without having to hard code the ami.</p>
<pre><code class="lang-plaintext">Note: The AMI will be pulled from the default region 
configured using aws configure or by explicitly 
mentioning them in your providers.tf file
</code></pre>
<p>You can find more of them at <a target="_blank" href="https://www.hashicorp.com/blog/hashicorp-terraform-supports-amazon-linux-2">https://www.hashicorp.com/blog/hashicorp-terraform-supports-amazon-linux-2</a></p>
<p>I will be following this by ways to dynamically bring other Operating Systems AMI.</p>
]]></content:encoded></item><item><title><![CDATA[Random Strings as Parameters]]></title><description><![CDATA[The most dreaded word that scares the Developer community "Hard Coding Parameters".
Well, in the words of ChatGPT this is why hard coding considered a bad practice

Hard coding is considered a bad practice in software development for several reasons:...]]></description><link>https://reshma-cloud.com/random-strings-as-parameters</link><guid isPermaLink="true">https://reshma-cloud.com/random-strings-as-parameters</guid><category><![CDATA[hashicorp]]></category><category><![CDATA[Terraform]]></category><category><![CDATA[AWS]]></category><category><![CDATA[Infrastructure as code]]></category><dc:creator><![CDATA[Reshma A]]></dc:creator><pubDate>Wed, 07 Jun 2023 09:54:58 GMT</pubDate><content:encoded><![CDATA[<p>The most dreaded word that scares the Developer community "Hard Coding Parameters".</p>
<p>Well, in the words of ChatGPT this is why hard coding considered a bad practice</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686125819242/663e0ea4-a23d-43f8-964c-97b51290695e.png" alt class="image--center mx-auto" /></p>
<p><em>Hard coding is considered a bad practice in software development for several reasons:</em></p>
<ol>
<li><p><em>Lack of Flexibility: Hard coding refers to embedding specific values or configurations directly into the code, without using variables or configurable options. This approach makes it difficult to modify or adapt the code to different scenarios or requirements. Any changes to the hardcoded values require modifying the source code itself, which can be time-consuming and error-prone. It limits the code's flexibility and makes it less maintainable.</em></p>
</li>
<li><p><em>Code Duplication: Hard coding often leads to code duplication, where the same values or configurations are repeated multiple times in different parts of the codebase. This violates the DRY (Don't Repeat Yourself) principle, which promotes reusability and maintainability. Code duplication increases the chances of inconsistencies and bugs, as any modifications or updates must be made in multiple places.</em></p>
</li>
<li><p><em>Reduced Readability: Hardcoded values are typically represented as literal values directly in the code, which can make the code more difficult to read and understand. When the purpose or meaning of a particular value is not evident from the code itself, it requires additional effort to comprehend the code's behavior. Using variables or constants with meaningful names improves code readability and makes it easier for developers to understand the intent.</em></p>
</li>
<li><p><em>Maintenance Challenges: Hardcoding values makes code maintenance more challenging. When a change is needed, such as updating a configuration or modifying a value, it often requires modifying the code and recompiling the application. This process can be cumbersome, especially in larger projects or when the code is distributed across multiple systems. It is preferable to have configurations stored separately, allowing changes to be made without modifying the source code.</em></p>
</li>
<li><p><em>Testing and Debugging Issues: Hardcoding values can introduce difficulties in testing and debugging. For testing purposes, it is often necessary to simulate different scenarios or inputs. Hardcoded values can make it harder to vary inputs or configure the system for different test cases. Additionally, if an error occurs related to a hardcoded value, identifying and fixing the problem becomes more complicated.</em></p>
</li>
<li><p><em>Lack of Scalability: Hardcoded values are typically tied to specific contexts or environments. When the code needs to be scaled to handle larger data sets, increased load, or different configurations, hardcoding becomes a significant obstacle. Flexible and configurable code is essential for building scalable applications that can adapt to changing requirements.</em></p>
</li>
</ol>
<p><em>Overall, hard coding limits flexibility, reusability, readability, maintainability, and scalability of the codebase. It is considered a bad practice because it makes code more rigid, error-prone, and difficult to maintain and evolve over time. Instead, it is recommended to use variables, constants, configuration files, or other techniques to decouple values from the code and make it more adaptable and maintainable.</em></p>
<p>So what do we do? Do we have a solution for this in Terraform?</p>
<p>The answer is "YES".</p>
<p>Instead of passing hard-coded AWS Resource names, there is a way to generate a random string and then pass on the same to the variables.  </p>
<p>Using <a target="_blank" href="https://registry.terraform.io/providers/hashicorp/random/latest/docs">"random provider"</a></p>
<p>As a person who loves their pets, I am drawn towards using the provider "<strong>random_pet</strong>"</p>
<p>[Please add your own provider section for this]</p>
<ol>
<li><p>provider</p>
</li>
<li><p>Generate Random parameter: The variable "length" here is - The length (in words) of the pet name. In the below example "length = 2" is the 2 complete words separated by "_".</p>
</li>
</ol>
<pre><code class="lang-go"># ******************************************************
#                    Random Generation
# ******************************************************
resource <span class="hljs-string">"random_pet"</span> <span class="hljs-string">"name"</span> {
  length  = <span class="hljs-number">2</span>
}

locals {
  prefix = <span class="hljs-string">"random-${random_pet.name.id}"</span>
}
</code></pre>
<ol>
<li>S3 bucket</li>
</ol>
<pre><code class="lang-go"># ******************************************************
#                    S3 Bucket
# ******************************************************

resource <span class="hljs-string">"aws_s3_bucket"</span> <span class="hljs-string">"demo-s3"</span> {
  bucket = <span class="hljs-string">"${local.prefix}-s3"</span>
}
</code></pre>
<ol>
<li><p>Lamda function with IAM Role</p>
</li>
<li><pre><code class="lang-go"> # ******************************************************
 #                    Lambda functions
 # ******************************************************

 data <span class="hljs-string">"archive_file"</span> <span class="hljs-string">"lambda_zip"</span> {
   <span class="hljs-keyword">type</span>        = <span class="hljs-string">"zip"</span>
   source_dir  = <span class="hljs-string">"lambda"</span>
   output_path = <span class="hljs-string">"lambda.zip"</span>
 }

 resource <span class="hljs-string">"aws_lambda_function"</span> <span class="hljs-string">"lambda"</span> {
   filename         = data.archive_file.lambda_zip.output_path
   function_name    = <span class="hljs-string">"${local.prefix}-lambda"</span>
   role             = aws_iam_role.iam_for_lambda.arn
   handler          = <span class="hljs-string">"lambda.lambda_handler"</span>
   source_code_hash = data.archive_file.lambda_zip.output_base64sha256
   runtime          = <span class="hljs-string">"python3.9"</span>
   timeout          = <span class="hljs-number">900</span>
 }

 # ******************************************************
 #                    IAM Role - Lambda
 # ******************************************************

 data <span class="hljs-string">"aws_iam_policy_document"</span> <span class="hljs-string">"assume_role"</span> {
   statement {
     effect = <span class="hljs-string">"Allow"</span>

     principals {
       <span class="hljs-keyword">type</span>        = <span class="hljs-string">"Service"</span>
       identifiers = [<span class="hljs-string">"lambda.amazonaws.com"</span>]
     }

     actions = [<span class="hljs-string">"sts:AssumeRole"</span>]
   }
 }

 resource <span class="hljs-string">"aws_iam_role"</span> <span class="hljs-string">"iam_for_lambda"</span> {
   name               = <span class="hljs-string">"${local.prefix}-iam-lambda"</span>
   assume_role_policy = data.aws_iam_policy_document.assume_role.json
 }
</code></pre>
<p> 5. Now lets see before hand what would my "pet" name before we see the name in the AWS Resources.</p>
</li>
</ol>
<pre><code class="lang-go"># ***************************************************
#                    Output
# ***************************************************

output <span class="hljs-string">"s3_bucket"</span> {
  value = aws_s3_bucket.demo-s3.bucket
}
</code></pre>
<p>Well the pet name is</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686131006225/a0b8b606-5525-44bb-b1fa-43fbcadd7984.png" alt class="image--center mx-auto" /></p>
<p>Let's check them out in the AWS Console</p>
<p>S3 Bucket</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686131078368/3a63a349-6d54-4819-8437-686c78edef7c.png" alt class="image--center mx-auto" /></p>
<p>IAM Role</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686131131591/575347e7-1464-4358-ad26-4caf48b155cf.png" alt class="image--center mx-auto" /></p>
<p>Lambda function</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686131203226/da7a635a-469f-41ee-a567-4e0b6fd59f4b.png" alt class="image--center mx-auto" /></p>
<p>As you can see that the pet name "chief-hound" (with length = 2 ) has been added to the names of S3, IAM and Lambda Resources.</p>
<p>The word "random" can be switched with the name that is needed in the project. For eg. Application name.</p>
]]></content:encoded></item><item><title><![CDATA[Target Resource Creation]]></title><description><![CDATA[You are a Platform Engineer and are responsible to maintain the Cloud Infrastructure with many limitations, with one being not to destroy the current infrastructure. What would you do if you have been asked to modify or create a new resource BUT with...]]></description><link>https://reshma-cloud.com/target-resource-creation</link><guid isPermaLink="true">https://reshma-cloud.com/target-resource-creation</guid><category><![CDATA[Terraform]]></category><category><![CDATA[AWS]]></category><category><![CDATA[#IaC]]></category><dc:creator><![CDATA[Reshma A]]></dc:creator><pubDate>Wed, 12 Apr 2023 16:39:39 GMT</pubDate><content:encoded><![CDATA[<p>You are a Platform Engineer and are responsible to maintain the Cloud Infrastructure with many limitations, with one being not to destroy the current infrastructure. What would you do if you have been asked to modify or create a new resource <strong>BUT</strong> without creating a new terraform template???<br />The answer is <strong>TARGET</strong> resource creation.</p>
<p>All you have to do is add the resource code and use the format mentioned in the sections below to run plan/apply or destroy.</p>
<pre><code class="lang-go"># providers.tf
terraform {
  required_providers {
    aws = {
      source  = <span class="hljs-string">"hashicorp/aws"</span>
      version = <span class="hljs-string">"4.60.0"</span>
    }
  }
}

provider <span class="hljs-string">"aws"</span> {
  region  = <span class="hljs-keyword">var</span>.region
  profile = <span class="hljs-keyword">var</span>.profile
}
</code></pre>
<pre><code class="lang-go"># variables.tf
variable <span class="hljs-string">"region"</span> {}
variable <span class="hljs-string">"profile"</span> {}

variable <span class="hljs-string">"ec2-role-name"</span> {}
</code></pre>
<pre><code class="lang-go"># iam.tf
resource <span class="hljs-string">"aws_iam_role"</span> <span class="hljs-string">"ec2-iam-role"</span> {
    name = <span class="hljs-string">"my-ec2-iam-role"</span>
    assume_role_policy = jsonencode({
        Version = <span class="hljs-string">"2012-10-17"</span>
        Statement = [
            {
                Action = <span class="hljs-string">"sts:AssumeRole"</span>
                Effect = <span class="hljs-string">"Allow"</span>
                Sid = <span class="hljs-string">""</span>
                Principal = {
                    Service = <span class="hljs-string">"ec2.amazonaws.com"</span>
                }
            }
        ]
    })  
}
</code></pre>
<pre><code class="lang-go"># target_iam.tfvars
profile = <span class="hljs-string">"aws-terraform"</span>
region  = <span class="hljs-string">"us-east-1"</span>

ec2-role-name = <span class="hljs-string">"my-ec2-iam-role"</span>
</code></pre>
<p>Syntax:</p>
<pre><code class="lang-powershell"><span class="hljs-variable">$</span> terraform apply <span class="hljs-literal">-var</span><span class="hljs-operator">-file</span> &lt;file&gt;.tfvars <span class="hljs-literal">-target</span>=<span class="hljs-string">"&lt;AWS_Terraform_Resource_name&gt;.&lt;Resource&gt;"</span> -<span class="hljs-literal">-auto</span><span class="hljs-literal">-approve</span>
</code></pre>
<p>Example:</p>
<pre><code class="lang-powershell"><span class="hljs-variable">$</span> terraform apply <span class="hljs-literal">-var</span><span class="hljs-operator">-file</span> target_iam.tfvars <span class="hljs-literal">-target</span>=<span class="hljs-string">"aws_iam_role.ec2-iam-role"</span> -<span class="hljs-literal">-auto</span><span class="hljs-literal">-approve</span>
</code></pre>
<p>Any resource can be selectively destroyed <strong>provided</strong> it does not have any dependencies or the related dependencies are also deleted.</p>
<pre><code class="lang-powershell"><span class="hljs-variable">$</span> terraform destroy <span class="hljs-literal">-var</span><span class="hljs-operator">-file</span> target_iam.tfvars <span class="hljs-literal">-target</span>=<span class="hljs-string">"aws_iam_role.ec2-iam-role"</span> -<span class="hljs-literal">-auto</span><span class="hljs-literal">-approve</span>
</code></pre>
<blockquote>
<p><strong>NOTE:</strong> It is <em>not recommended</em> to use <code>-target</code> for routine operations, since this can lead to undetected configuration drift and confusion about how the true state of resources relates to configuration.</p>
<p>Ref: <a target="_blank" href="https://developer.hashicorp.com/terraform/cli/commands/plan">https://developer.hashicorp.com/terraform/cli/commands/plan</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Adding multiple emails to sns subscriptions using Terraform]]></title><description><![CDATA[We seldom find advanced topics on Terraform templates online and sometimes the information is not fully available on the Official Pages as well.I'm bringing to you advanced template examples to be used in your organization's environment.
Bringing the...]]></description><link>https://reshma-cloud.com/adding-multiple-emails-to-sns-subscriptions-using-terraform</link><guid isPermaLink="true">https://reshma-cloud.com/adding-multiple-emails-to-sns-subscriptions-using-terraform</guid><dc:creator><![CDATA[Reshma A]]></dc:creator><pubDate>Tue, 04 Apr 2023 10:45:57 GMT</pubDate><content:encoded><![CDATA[<p>We seldom find advanced topics on Terraform templates online and sometimes the information is not fully available on the Official Pages as well.<br />I'm bringing to you advanced template examples to be used in your organization's environment.</p>
<p>Bringing the first in the series is adding multiple email ID subscriptions to our SNS Topic.</p>
<p>While you all know the Terraform Basics, I would not go into much detail on them. I have structured the code in a parameterized manner and would be following the same pattern in all my posts.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1680603716634/294be43b-b630-4f79-86ce-5e73508154cd.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-go"># providers.tf
terraform {
  required_providers {
    aws = {
      source  = <span class="hljs-string">"hashicorp/aws"</span>
      version = <span class="hljs-string">"4.60.0"</span>
    }
  }
}

provider <span class="hljs-string">"aws"</span> {
  region  = <span class="hljs-keyword">var</span>.region
  profile = <span class="hljs-keyword">var</span>.profile
}
</code></pre>
<pre><code class="lang-go"># variables.tf
variable <span class="hljs-string">"region"</span> {}
variable <span class="hljs-string">"profile"</span> {}

variable <span class="hljs-string">"sns-topic"</span> {}
variable <span class="hljs-string">"sns-topic-subscription"</span> {}
</code></pre>
<pre><code class="lang-go"># locals.tf
locals {
  emails = [<span class="hljs-string">"emailid1@email.com"</span>,<span class="hljs-string">"emailid2@email.com"</span>,<span class="hljs-string">"emailid3@email.com"</span>]
}
</code></pre>
<pre><code class="lang-go"># sns.tf
resource <span class="hljs-string">"aws_sns_topic"</span> <span class="hljs-string">"sns_topic"</span> {
  name = <span class="hljs-keyword">var</span>.sns-topic
}

resource <span class="hljs-string">"aws_sns_topic_subscription"</span> <span class="hljs-string">"sns_topic_subscription"</span> {
  count = length(local.emails)
  topic_arn = aws_sns_topic.sns_topic.arn
  protocol  = <span class="hljs-string">"email"</span>
  endpoint = local.emails[count.index]
}
</code></pre>
<pre><code class="lang-go"># sns.tfvars
sns-topic              = <span class="hljs-string">"sns-test-topic"</span>
sns-topic-subscription = <span class="hljs-string">"sns-test-subscription"</span>

profile = <span class="hljs-string">"aws-terraform"</span>
region  = <span class="hljs-string">"us-east-1"</span>
</code></pre>
<p>The same can be achieved without the use of locals.tf as well. Then we use the "for_each" functionality and pass the values to it and then refer to the "value" in the endpoint section.</p>
<pre><code class="lang-go">resource <span class="hljs-string">"aws_sns_topic_subscription"</span> <span class="hljs-string">"sns_topic_subscription"</span> {
  for_each = toset([<span class="hljs-string">"emailid1@email.com"</span>,<span class="hljs-string">"emailid2@email.com"</span>,<span class="hljs-string">"emailid3@email.com"</span>])
  topic_arn = aws_sns_topic.sns_topic.arn
  protocol  = <span class="hljs-string">"email"</span>
  endpoint = each.value
}
</code></pre>
<p>And as you already know the drill... Run the Terraform template</p>
<pre><code class="lang-plaintext">$ terraform init
$ terraform plan
$ terraform apply -var-file sns.tfvars --auto-approve
$ terraform destroy -var-file sns.tfvars --auto-approve
</code></pre>
<blockquote>
<p>Prerequisite:</p>
<ol>
<li><p>Ensure AWS CLI is installed and configured. Installation: <a target="_blank" href="https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html">https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html</a></p>
<p> Configuration: (I have configured using "Short-term credentials" format) <a target="_blank" href="https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html">https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html</a></p>
</li>
<li><p>Ensure Terraform is installed</p>
<p> <a target="_blank" href="https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli">https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli</a></p>
</li>
</ol>
</blockquote>
]]></content:encoded></item></channel></rss>