<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: yadanaresh</title>
    <description>The latest articles on DEV Community by yadanaresh (@nareshaws).</description>
    <link>https://dev.to/nareshaws</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1190320%2F0b0fd206-9e3f-46a3-bf38-232a4d960297.jpg</url>
      <title>DEV Community: yadanaresh</title>
      <link>https://dev.to/nareshaws</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nareshaws"/>
    <language>en</language>
    <item>
      <title>Securing Your AWS Terraform Deployments: 5 Authentication Methods</title>
      <dc:creator>yadanaresh</dc:creator>
      <pubDate>Sun, 03 Dec 2023 23:38:06 +0000</pubDate>
      <link>https://dev.to/nareshaws/securing-your-aws-terraform-deployments-5-authentication-methods-47p</link>
      <guid>https://dev.to/nareshaws/securing-your-aws-terraform-deployments-5-authentication-methods-47p</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In the rapidly evolving landscape of cloud infrastructure management, securing access to AWS resources is a foundational concern. One critical aspect is the secure authentication of Terraform, a popular infrastructure-as-code tool, to your AWS environment. In this blog post, we will delve into five distinct authentication methods, providing comprehensive explanations and practical demonstrations for each. By the end, you'll be well-equipped to make informed decisions aboåut the most suitable authentication approach for your specific use case.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before diving into the practical demonstrations, it's essential to ensure that the following prerequisites are satisfied:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;u&gt;Procure Bastion Server:&lt;/u&gt;&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Acquire a Bastion server with SSH port open.&lt;/li&gt;
&lt;li&gt;Ensure that HTTP and HTTPS ports are open to facilitate necessary communications.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;&lt;u&gt;Install Terraform on Bastion Server:&lt;/u&gt;&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Terraform should be installed on the Bastion server, serving as the central point for infrastructure provisioning.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reference: &lt;a href="https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli" rel="noopener noreferrer"&gt;https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;u&gt;Install AWS CLI on Bastion Server:&lt;/u&gt;&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS CLI is a crucial component for several authentication methods. Install it on the Bastion server to facilitate secure interactions with AWS services.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reference: &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; The following scenarios and practical demonstrations are explained using RHEL OS. Ensure that your Bastion server is running RHEL, and adapt commands accordingly based on the specific Linux distribution you are using.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scenario 1: Direct Values in Code
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;br&gt;
      The most straightforward yet insecure method involves hardcoding AWS secret and access keys directly into Terraform code or configuration files. While this approach might be convenient for testing or training purposes, it poses a significant security risk in a production environment. Anyone with access to the codebase can retrieve sensitive information, making it a less-than-ideal choice for real-world scenarios.&lt;/p&gt;

&lt;p&gt;Embedding AWS secret and access keys directly into Terraform code is generally considered a bad practice due to security concerns. When secret keys are exposed in Terraform code, it poses a significant security risk as anyone with access to the Terraform code can potentially access sensitive AWS resources, make unauthorized changes, or compromise the security of your infrastructure. It's crucial to follow best practices for handling secrets to avoid these risks.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Configuration File:&lt;/strong&gt;&lt;br&gt;
Terraform configurations are often stored in files with a &lt;code&gt;.tf&lt;/code&gt; extension. These files contain the infrastructure code and configuration details. In some cases, AWS secret and access keys might be directly embedded in these files.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Usage in Resources:&lt;/strong&gt;&lt;br&gt;
The variables are then used in the AWS resource definitions within the Terraform code. For example:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;access_key&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"AKIATDG3VPEUQ2HE5NEY"&lt;/span&gt;
  &lt;span class="nx"&gt;secret_key&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"bU2BBXqBhXeDvtsgta41mmUzbX5eV+IJCxGIkk/0"&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-west-2"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_instance"&lt;/span&gt; &lt;span class="s2"&gt;"senario1"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ami&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ami-0c55b159cbfafe1f0"&lt;/span&gt;
  &lt;span class="nx"&gt;instance_type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"t2.micro"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Exposing Secrets:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Unfortunately, when secrets are directly embedded like this, they become visible to anyone who has access to the Terraform code. This includes version control systems, shared repositories, and collaborators on the project.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security Implications:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Exposing AWS secret and access keys in Terraform code is a security vulnerability. If the Terraform code is inadvertently shared or exposed, unauthorized individuals may gain access to AWS resources, leading to potential data breaches, unauthorized usage, or even financial losses.&lt;br&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;

&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;  &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;access_key&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"AKIATDG3VPEUQ2HE5NEY"&lt;/span&gt;
      &lt;span class="nx"&gt;secret_key&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"bU2BBXqBhXeDvtsgta41mmUzbX5eV+IJCxGIkk/0"&lt;/span&gt;
      &lt;span class="nx"&gt;region&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-west-2"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_instance"&lt;/span&gt; &lt;span class="s2"&gt;"senario1"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;ami&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ami-0c55b159cbfafe1f0"&lt;/span&gt;
      &lt;span class="nx"&gt;instance_type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"t2.micro"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;commands to execute &lt;br&gt;
terraform init&lt;br&gt;
terraform plan&lt;br&gt;
terraform apply&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Scenario 2: Environment Variables
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;br&gt;
Storing AWS credentials as environment variables in Terraform improves security over direct code embedding but introduces risks. While protecting against code exposure, environment variables are susceptible to command history leaks. Manual export before Terraform execution and limited access control granularity make them less suitable for certain production scenarios. Organizations should consider advanced secrets management solutions, automate secure variable configuration, and regularly rotate credentials to enhance security. In production, combining environment variables with AWS IAM roles or dedicated key management services provides a more robust and secure approach.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exporting AWS Secret Keys as Environment Variables:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this demonstration, you are likely using commands in the terminal to export AWS secret keys as environment variables. This is a more secure approach than embedding the keys directly in Terraform code, as it separates sensitive information from the infrastructure configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    export AWS_ACCESS_KEY_ID="AKIATDG3VPEUQ2HE5NEY"
    export AWS_SECRET_ACCESS_KEY="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"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Terraform Configuration:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In your Terraform code, you then reference these environment variables instead of directly embedding the secret keys.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt; &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt; &lt;span class="c1"&gt;#always region is us east&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_instance"&lt;/span&gt; &lt;span class="s2"&gt;"senario2"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ami&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ami-023c11a32b0207432"&lt;/span&gt; &lt;span class="c1"&gt;# Specify ami details&lt;/span&gt;
  &lt;span class="nx"&gt;instance_type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"t2.micro"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Security Breach in Bash History:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The vulnerability arises from the fact that commands entered in a terminal, including the export commands for AWS secret keys, are often logged in the bash history file. If someone gains access to the history file, they can see the exported secret keys.&lt;/p&gt;

&lt;p&gt;For example, if a user runs &lt;code&gt;history&lt;/code&gt; or looks into the &lt;code&gt;.bash_history&lt;/code&gt; file, they can find:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  history |grep -i export
   22  export AWS_ACCESS_KEY_ID="AKIAZ3QDJN4PLRT7OUGC"
   23  export AWS_SECRET_ACCESS_KEY="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"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a potential security risk, as anyone with access to the system could view these commands and extract sensitive information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mitigation:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To mitigate this risk, you should take steps to secure the bash history file. You can configure the shell not to log certain commands or use tools that help manage and encrypt the history file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;To mask sensitive commands in Bash history in Linux, you can use the HISTCONTROL environment variable with the value ignorespace or ignoreboth. This prevents commands preceded by a space from being saved to the history. Here's how you can set it:

Copy code
echo "HISTCONTROL=ignorespace" &amp;gt;&amp;gt; ~/.bashrc
source ~/.bashrc
Now, when you precede a command with a space, it won't be stored in the Bash history. For example:

[root@ip-172-31-33-196 AWS-Terra]#  export AWS_ACCESS_KEY_ID="AKIAZ3QDJN4PLRT7OUGC"
[root@ip-172-31-33-196 AWS-Terra]# 
[root@ip-172-31-33-196 AWS-Terra]#  export AWS_SECRET_ACCESS_KEY="IGFhfJaQ7ZGyt1ZGSJPfuchhNREiJDcdiaTzWdoY"
[root@ip-172-31-33-196 AWS-Terra]# 
[root@ip-172-31-33-196 AWS-Terra]# history |grep -i export
   22  export AWS_ACCESS_KEY_ID="AKIAZ3QDJN4PLRT7OUGC"
   23  export AWS_SECRET_ACCESS_KEY="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"
   50  history |grep -i export
   51  history |grep -i export
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Practical Demonstration:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;commands&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;terraform init
----------------
Initializing the backend...

Initializing provider plugins...
- Finding latest version of hashicorp/aws...
- Installing hashicorp/aws v5.29.0...
- Installed hashicorp/aws v5.29.0 (signed by HashiCorp)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;terraform plan
---------------
`Plan: 1 to add, 0 to change, 0 to destroy.

─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;terraform apply
----------------
Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_instance.senario2: Creating...
aws_instance.senario2: Still creating... [10s elapsed]
aws_instance.senario2: Still creating... [20s elapsed]
aws_instance.senario2: Still creating... [30s elapsed]
aws_instance.senario2: Creation complete after 31s [id=i-005cb70b463c82be3]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Scenario 3: AWS CLI with Config Files
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;br&gt;
Leveraging the AWS CLI for AWS credential management offers an improved security approach by storing access and secret keys in a dedicated file (&lt;code&gt;~/.aws/secure-credentials&lt;/code&gt;). This method introduces an additional layer of protection, addressing concerns related to embedding credentials directly in Terraform code or using environment variables. The confidential file ensures that sensitive information is isolated and encrypted, enhancing security measures. However, it is imperative to enforce strict access controls to the AWS CLI and associated credential files. Limiting access to authorized teams or individuals helps prevent unauthorized use and ensures that only trusted personnel can interact with AWS resources. In summary, integrating the AWS CLI with secure credential storage practices is a robust security strategy, combining convenience with heightened protection against credential exposure and misuse.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Practical Demonstration:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;let's walk through the steps to configure the AWS CLI, store credentials in a secure file, and integrate them into Terraform for enhanced security.&lt;/p&gt;

&lt;p&gt;Before we test scenario 3, let's unset the environment variable using the following commands.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[root@ip-xxx-xx-xx-xxx AWS-Terra]# unset AWS_ACCESS_KEY_ID
[root@ip-xxx-xx-xx-xxx AWS-Terra]# unset AWS_SECRET_ACCESS_KEY
[root@ip-xxx-xx-xx-xxx AWS-Terra]# echo $AWS_SECRET_ACCESS_KEY

[root@ip-xxx-xx-xx-xxx AWS-Terra]# echo $AWS_ACCESS_KEY_ID

[root@ip-xxx-xx-xx-xxx AWS-Terra]# 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1. Configure AWS CLI:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws configure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow the prompts to enter your AWS access key, secret key, region, and preferred output format. This information will be stored in the AWS CLI configuration file (&lt;code&gt;~/.aws/credentials&lt;/code&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Store Credentials in a Secure File:
&lt;/h3&gt;

&lt;p&gt;Create a dedicated file to store your AWS credentials securely. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[default]"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ~/.aws/credentials
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"aws_access_key_id = YOUR_ACCESS_KEY"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.aws/credentials
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"aws_secret_access_key = YOUR_SECRET_KEY"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.aws/credentials
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Secure the file's permissions to make it readable only by the owner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod &lt;/span&gt;600 /AWS-Terra/.aws/credentials
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Configure Terraform to Use AWS CLI Credentials:
&lt;/h3&gt;

&lt;p&gt;In your Terraform configuration, set the AWS provider block to use the AWS CLI credentials file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;shared_credentials_files&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"/AWS-Terra/.aws/credentials"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt;                 &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Enhanced Security:
&lt;/h3&gt;

&lt;p&gt;By default, only authorized users should have access to the AWS CLI configuration and credentials. Ensure that access to the AWS CLI is restricted to authorized teams or individuals.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;shared_credentials_files&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"/AWS-Terra/.aws/credentials"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt; &lt;span class="c1"&gt;#always region is us east&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_instance"&lt;/span&gt; &lt;span class="s2"&gt;"senario3"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ami&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ami-023c11a32b0207432"&lt;/span&gt; &lt;span class="c1"&gt;# Specify ami details&lt;/span&gt;
  &lt;span class="nx"&gt;instance_type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"t2.micro"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;commands&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;terraform plan
--------------
aws_instance.senario2: Refreshing state... [id=i-005cb70b463c82be3]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create
  - destroy

Terraform will perform the following actions:

  # aws_instance.senario2 will be destroyed
  # (because aws_instance.senario2 is not in configura 


Plan: 1 to add, 0 to change, 1 to destroy.

───────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.


terraform apply
----------------
aws_instance.senario2: Refreshing state... [id=i-005cb70b463c82be3]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create
  - destroy

Terraform will perform the following actions:

  # aws_instance.senario2 will be destroyed
Plan: 1 to add, 0 to change, 1 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_instance.senario2: Destroying... [id=i-005cb70b463c82be3]
aws_instance.senario3: Creating...
aws_instance.senario2: Still destroying... [id=i-005cb70b463c82be3, 10s elapsed]
aws_instance.senario3: Still creating... [10s elapsed]
aws_instance.senario2: Still destroying... [id=i-005cb70b463c82be3, 20s elapsed]
aws_instance.senario3: Still creating... [20s elapsed]
aws_instance.senario2: Destruction complete after 30s
aws_instance.senario3: Still creating... [30s elapsed]
aws_instance.senario3: Still creating... [40s elapsed]
aws_instance.senario3: Still creating... [50s elapsed]
aws_instance.senario3: Creation complete after 52s [id=i-0e214b3b0fb488a6d]

Apply complete! Resources: 1 added, 0 changed, 1 destroyed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Scenario 4: EC2 Role-Based Authentication
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;br&gt;
Securing AWS infrastructure through IAM roles and their attachment to EC2 instances is a best practice that enhances security. This approach minimizes security breaches by providing temporary and scoped permissions, ensuring resources are accessed based on the instance's role. IAM roles offer dynamic and flexible access control, reducing the risk associated with long-lived credentials. In practical terms, setting up EC2 role-based authentication involves creating roles with specific permissions and attaching them to instances. This not only simplifies credential management but also strengthens security measures, aligning with the principle of least privilege. Leveraging IAM roles showcases AWS's robust security model and is essential for securing cloud-based environments effectively.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IAM Role Permissions for EC2 Bastion Instance Creation:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;u&gt;IAM Console:&lt;/u&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to the IAM Console in the AWS Management Console.&lt;/li&gt;
&lt;li&gt;Select "Roles" and click "Create role."&lt;/li&gt;
&lt;li&gt;Choose "AWS service" as the trusted entity and EC2 as the use case.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;u&gt;Permissions:&lt;/u&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the "Permissions" step, attach the following policies to the role:&lt;/li&gt;
&lt;li&gt;AmazonEC2FullAccess: Provides comprehensive EC2 permissions.&lt;/li&gt;
&lt;li&gt;AmazonSSMFullAccess: Allows interaction with EC2 instances using AWS Systems Manager.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's essential to follow the principle of least privilege. If you only need to create and manage EC2 instances, the above policies are generally sufficient. However, if you plan to perform additional tasks (e.g., creating VPCs, modifying security groups), you may need to attach additional policies accordingly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;u&gt;Create Role:&lt;/u&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complete the role creation process and make note of the Role ARN, which you will use when launching your EC2 instance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;u&gt;Instance Launch Configuration:&lt;/u&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Launch a new EC2 instance or select an existing one.&lt;/li&gt;
&lt;li&gt;In the instance configuration, choose the IAM role created earlier in the "Configure Instance Details" section.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;u&gt;Verify Role-Based Authentication:&lt;/u&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Connect to the EC2 instance using SSH or any other preferred method.&lt;/li&gt;
&lt;li&gt;Confirm the role-based authentication by checking the AWS CLI configuration on the instance using &lt;code&gt;aws configure list&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Terraform code&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;  &lt;span class="c1"&gt;# Set your desired AWS region&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_role"&lt;/span&gt; &lt;span class="s2"&gt;"ec2_role"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ec2_role"&lt;/span&gt;
  &lt;span class="nx"&gt;assume_role_policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_instance_profile"&lt;/span&gt; &lt;span class="s2"&gt;"ec2_instance_profile"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ec2_instance_profile"&lt;/span&gt;
  &lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ec2_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_role_policy_attachment"&lt;/span&gt; &lt;span class="s2"&gt;"ec2_full_access"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;policy_arn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:iam::aws:policy/AmazonEC2FullAccess"&lt;/span&gt;
  &lt;span class="nx"&gt;role&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ec2_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_instance"&lt;/span&gt; &lt;span class="s2"&gt;"Bastion_ec2_role"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ami&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ami-023c11a32b0207432"&lt;/span&gt;
  &lt;span class="nx"&gt;instance_type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"t2.micro"&lt;/span&gt;
  &lt;span class="nx"&gt;key_name&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"terraform-infra"&lt;/span&gt;

  &lt;span class="nx"&gt;iam_instance_profile&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_instance_profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ec2_instance_profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;

  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"bastion-role"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl1185vuv7aairc29cvpl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl1185vuv7aairc29cvpl.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Figkcgvl6xa4g2lvhyc3w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Figkcgvl6xa4g2lvhyc3w.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0tex3ljf3e9f2lb14ek1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0tex3ljf3e9f2lb14ek1.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;terraform init
----------------
Initializing the backend...

Initializing provider plugins...
- Finding latest version of hashicorp/aws...
- Installing hashicorp/aws v5.29.0...
- Installed hashicorp/aws v5.29.0 (signed by HashiCorp)

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

terraform plan
----------------
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_instance.senario4 will be created
  + resource "aws_instance" "senario4" {

Plan: 1 to add, 0 to change, 0 to destroy.

─────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

terraform apply
-----------------
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_instance.senario4 will be created
  + resource "aws_instance" "senario4" {
      + ami                                  = "ami-023c11a32b0207432"

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_instance.senario4: Creating...

aws_instance.senario4: Still creating... [4m30s elapsed]
aws_instance.senario4: Creation complete after 4m33s [id=i-01c26968753921b24]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;After creating the Bastion EC2 instance with the 'ec2_role,' which has the 'AmazonEC2FullAccess' permission, I logged into the Bastion server. Subsequently, I executed a Terraform script to create an additional EC2 instance without passing any AWS access and secret keys explicitly. The EC2 instance was successfully created based on the IAM role policy associated with 'ec2_role.' This demonstrates Scenario 4, where there is no need to provide AWS access and secret keys explicitly; EC2 instances can be launched securely using IAM roles.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Scenario 5: HashiCorp Vault Integration
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;br&gt;
Integrating Terraform with HashiCorp Vault represents the apex of contemporary cloud security practices. This synergy centralizes the administration of sensitive information, specifically AWS secret and access keys, ensuring their secure storage. The dynamic retrieval of these credentials during Terraform execution adds an extra layer of security. Exploring the nuances of Vault integration reveals its robust security features, establishing it as a reliable safeguard for critical information. &lt;em&gt;If you harbor a keen interest in securing AWS secrets, integrating them with HashiCorp Vault emerges as a preferred and effective method, offering a comprehensive approach to managing and protecting sensitive data in cloud environments&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Taking a hands-on approach&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;creating HashiCorp vault secrets&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;u&gt;installation of vault on Linux server&lt;/u&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; yum-utils
&lt;span class="nb"&gt;sudo &lt;/span&gt;yum-config-manager &lt;span class="nt"&gt;--add-repo&lt;/span&gt; https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nb"&gt;install &lt;/span&gt;vault

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;commands&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;[-31-36-42 ~]# vault login&lt;br&gt;
Token (will be hidden): &lt;br&gt;
Success! You are now authenticated. The token information displayed below is already stored in the token helper. You do NOT need to run "vault login" again. Future Vault requests will automatically use this token.&lt;/p&gt;

&lt;p&gt;Key                  Value&lt;/p&gt;



&lt;p&gt;token                hvs.IZnSVaRnskiqOgLbkKVgzJgY&lt;br&gt;
token_accessor       w1ggJYnsUZwl8f3on9h2A5Vj&lt;br&gt;
token_duration       ∞&lt;br&gt;
token_renewable      false&lt;br&gt;
token_policies       ["root"]&lt;br&gt;
identity_policies    []&lt;br&gt;
policies             ["root"]&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;commands&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;[31-36-42 ec2-with-vault]# vault kv put secret/aws-creds access_key=AKIAUUSZO22P4DSSDUCWHVPKssf&lt;br&gt;
------Secret Path ----&lt;br&gt;
secret/data/aws-creds&lt;/p&gt;

&lt;p&gt;------ Metadata -------&lt;br&gt;
Key                Value&lt;/p&gt;



&lt;p&gt;created_time       2023-12-03T22:50:07.362873124Z&lt;br&gt;
custom_metadata    &lt;br&gt;
deletion_time      n/a&lt;br&gt;
destroyed          false&lt;br&gt;
version            3&lt;br&gt;
[root@ip-172-31-36-42 ec2-with-vault]# vault kv put secret/aws-sec secret_key=3wWrTb9qUm+OewewebBB44ElkqbO6fNxE82pWKGLIheJM&lt;br&gt;
---- Secret Path -----&lt;br&gt;
secret/data/aws-sec&lt;/p&gt;

&lt;p&gt;--------- Metadata --------&lt;br&gt;
Key                Value&lt;/p&gt;



&lt;p&gt;created_time       2023-12-03T22:50:47.626808901Z&lt;br&gt;
custom_metadata    &lt;br&gt;
deletion_time      n/a&lt;br&gt;
destroyed          false&lt;br&gt;
version            1&lt;/p&gt;

&lt;p&gt;provider.tf&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"vault"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"https://127.0.0.1:8200"&lt;/span&gt;
  &lt;span class="nx"&gt;skip_tls_verify&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"xxxxxxxxxxxxxxxxxxx"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;vault-secrect.tf&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="s2"&gt;"vault_generic_secret"&lt;/span&gt; &lt;span class="s2"&gt;"aws-creds"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"secret/data/aws-creds"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="s2"&gt;"vault_generic_secret"&lt;/span&gt; &lt;span class="s2"&gt;"aws-sec"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"secret/data/aws-sec"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt; &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt; &lt;span class="c1"&gt;#always region is us east&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_instance"&lt;/span&gt; &lt;span class="s2"&gt;"ec2-with-vault"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ami&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ami-023c11a32b0207432"&lt;/span&gt;
  &lt;span class="nx"&gt;instance_type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"t2.micro"&lt;/span&gt;
  &lt;span class="nx"&gt;key_name&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"terraform-infra"&lt;/span&gt;

  &lt;span class="c1"&gt;# Other instance configurations...&lt;/span&gt;

  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ec2-with-vault"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Conclusion&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Choosing the right authentication method for your Terraform deployments is pivotal in maintaining a robust and secure AWS environment. By understanding the strengths and weaknesses of each scenario and following the practical demonstrations, you can make informed decisions aligned with your organization's security requirements. Stay tuned for the upcoming sections, where we will provide detailed step-by-step instructions and insights for each authentication method.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>AWS Setting up VPC Transit Gateway and EC2 Instances With Terraform</title>
      <dc:creator>yadanaresh</dc:creator>
      <pubDate>Thu, 09 Nov 2023 02:25:41 +0000</pubDate>
      <link>https://dev.to/nareshaws/aws-setting-up-vpc-transit-gateway-and-ec2-instances-with-terraform-5869</link>
      <guid>https://dev.to/nareshaws/aws-setting-up-vpc-transit-gateway-and-ec2-instances-with-terraform-5869</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In the dynamic landscape of cloud infrastructure, managing network communication and deploying resources across multiple VPCs can be a complex task. AWS provides a solution in the form of the VPC Transit Gateway, streamlining the connectivity between VPCs and on-premises environments. Automating these setups becomes easier and more efficient using Terraform, an Infrastructure as Code tool. In this blog post, I'll guide you through the process of setting up a VPC Transit Gateway and deploying EC2 instances across distinct VPCs, interconnected via the gateway, all orchestrated using Terraform.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In this guide, I aim to provide a comprehensive walk-through for two scenarios simultaneously: performing each task manually in the AWS Management Console and, in parallel, furnishing the corresponding Terraform script for automating each individual task. This dual approach will offer readers a clear understanding of executing actions within the AWS Console while simultaneously illustrating the equivalent infrastructure setup in Terraform for automation.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Task 1: Creating VPCs, Subnets, Route Tables and Internet Gateways
&lt;/h2&gt;

&lt;p&gt;Virtual Private Clouds (VPCs) form the foundation of network isolation within AWS, allowing segmentation of resources. We'll define VPCs with unique CIDR blocks, create subnets spread across multiple availability zones to ensure high availability, and establish Internet Gateways for external connectivity.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Creating VPC with different CIDR IP Range&lt;/u&gt;&lt;br&gt;
AWS Management Console:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Log in to the AWS Management Console.&lt;/li&gt;
&lt;li&gt;Navigate to the VPC service by either searching for "VPC" in the AWS Management Console's search bar or finding it under the "Networking &amp;amp; Content Delivery" section.&lt;/li&gt;
&lt;li&gt;Once in the VPC dashboard, click on "Your VPCs" from the left-hand navigation pane.&lt;/li&gt;
&lt;li&gt;Click on the "Create VPC" button.&lt;/li&gt;
&lt;li&gt;Provide a name &lt;em&gt;vpc1&lt;/em&gt; for the VPC and enter the CIDR block range, for instance, "10.1.0.0/16".&lt;/li&gt;
&lt;li&gt;Choose an availability zone, for example, "us-west-2".&lt;/li&gt;
&lt;li&gt;Click "Create" to set up the first VPC.&lt;/li&gt;
&lt;li&gt;Follow the same steps for other 2 VPC (&lt;em&gt;vpc2,vpc3&lt;/em&gt;) creation as per first VPC, but ensure that you use distinct CIDR blocks for the second and third VPCs. For example, "10.2.0.0/16" and "10.3.0.0/16" respectively, while selecting the same availability zone ("us-west-2" in this case)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;u&gt;Creating 3 Subnets Associated with Different VPCs&lt;/u&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the VPC dashboard, select "Subnets" from the left-hand navigation pane.&lt;/li&gt;
&lt;li&gt;Click on "Create Subnet".&lt;/li&gt;
&lt;li&gt;Choose the appropriate VPC in the "VPC" dropdown list.&lt;/li&gt;
&lt;li&gt;Provide a name &lt;em&gt;subnet1&lt;/em&gt; for the subnet and select the availability zone.&lt;/li&gt;
&lt;li&gt;Enter the CIDR block for the first subnet, ensuring it falls within the CIDR block range of the chosen VPC.&lt;/li&gt;
&lt;li&gt;Click "Create" to generate the first subnet.&lt;/li&gt;
&lt;li&gt;Repeat the same process, but for each new subnet, select a different VPC in the "VPC" dropdown list, name the subnet, select an availability zone, and define unique CIDR blocks for each of the second and third subnets.&lt;/li&gt;
&lt;li&gt;Ensure each subnet belongs to its respective VPC and the CIDR blocks don't overlap with other subnets or VPCs.&lt;/li&gt;
&lt;li&gt;Click "Create" to generate the additional subnets.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;u&gt;Creating Internet Gateways and Attaching to VPCs:&lt;/u&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the VPC dashboard, select "Internet Gateways" from the left-hand navigation pane.&lt;/li&gt;
&lt;li&gt;Click on "Create Internet Gateway".&lt;/li&gt;
&lt;li&gt;Provide a name &lt;strong&gt;igw1&lt;/strong&gt; for the Internet Gateway and click "Create" to generate the first Internet Gateway.&lt;/li&gt;
&lt;li&gt;Attaching the First Internet Gateway to a VPC:&lt;/li&gt;
&lt;li&gt;After creating the Internet Gateway, select it from the list.&lt;/li&gt;
&lt;li&gt;From the "Actions" menu, click on "Attach to VPC".&lt;/li&gt;
&lt;li&gt;Choose the VPC to which you want to attach this Internet Gateway and click "Attach".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;u&gt;Creating the Second &lt;em&gt;igw2&lt;/em&gt; and Third &lt;em&gt;igw3&lt;/em&gt; Internet Gateways:&lt;/u&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repeat the above steps to create two additional Internet Gateways, providing unique names for each gateway.&lt;/li&gt;
&lt;li&gt;Attaching Each Internet Gateway to Its Respective VPC:&lt;/li&gt;
&lt;li&gt;Select each newly created Internet Gateway.&lt;/li&gt;
&lt;li&gt;From the "Actions" menu, click "Attach to VPC".&lt;/li&gt;
&lt;li&gt;Choose the corresponding VPC for each Internet Gateway and click "Attach".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;u&gt;Creating Route Tables and Associating Subnets:&lt;/u&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the VPC dashboard, select "Route Tables" from the left-hand navigation pane.&lt;/li&gt;
&lt;li&gt;Click on "Create Route Table".&lt;/li&gt;
&lt;li&gt;Provide a name for the route table and select the VPC with which this route table will be associated.&lt;/li&gt;
&lt;li&gt;Click "Create" to generate the first route table.
&lt;u&gt;Associating the First Route Table with Subnet:&lt;/u&gt;
&lt;/li&gt;
&lt;li&gt;Under the "Route Tables" section, select the newly created route table.&lt;/li&gt;
&lt;li&gt;Click on the "Subnet Associations" tab.&lt;/li&gt;
&lt;li&gt;Click on "Edit subnet associations".&lt;/li&gt;
&lt;li&gt;Choose the first subnet to associate with this route table and click "Save".
&lt;u&gt;Creating the Second and Third Route Tables&lt;/u&gt;
&lt;/li&gt;
&lt;li&gt;Repeat the above steps to create two additional route tables, each associated with a different VPC.&lt;/li&gt;
&lt;li&gt;Make sure you select unique names for the route tables and associate them with their respective VPCs.&lt;/li&gt;
&lt;li&gt;Associating Subnets with the Remaining Route Tables:&lt;/li&gt;
&lt;li&gt;For each additional route table, go to the "Subnet Associations" tab and click "Edit subnet associations".&lt;/li&gt;
&lt;li&gt;Choose the corresponding subnet to associate with each route table and save the changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Terraform script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;provider "aws" {
  region = "us-west-2" # Change to your preferred AWS region
}

# Create VPCs
resource "aws_vpc" "vpc1" {
  cidr_block = "10.1.0.0/16"
  enable_dns_support = true
  enable_dns_hostnames = true
}

resource "aws_vpc" "vpc2" {
  cidr_block = "10.2.0.0/16"
  enable_dns_support = true
  enable_dns_hostnames = true
}

resource "aws_vpc" "vpc3" {
  cidr_block = "10.3.0.0/16"
  enable_dns_support = true
  enable_dns_hostnames = true
}

# Create Internet Gateways
resource "aws_internet_gateway" "igw1" {
  vpc_id = aws_vpc.vpc1.id
}

resource "aws_internet_gateway" "igw2" {
  vpc_id = aws_vpc.vpc2.id
}

resource "aws_internet_gateway" "igw3" {
  vpc_id = aws_vpc.vpc3.id
}

resource "aws_route_table" "route_table1" {
  vpc_id = aws_vpc.vpc1.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = "aws_internet_gateway.igw1.id"  # Replace with the actual internet gateway ID for VPC 1
  }
}
resource "aws_route_table" "route_table2" {
  vpc_id = aws_vpc.vpc2.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = "aws_internet_gateway.igw2.id"  # Replace with the actual internet gateway ID for VPC2
  }
}
resource "aws_route_table" "route_table2" {
  vpc_id = aws_vpc.vpc3.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = "aws_internet_gateway.igw3.id"  # Replace with the actual internet gateway ID for VPC3
  }
}

# Create Subnets and associating with route tables
resource "aws_subnet" "subnet1" {
  vpc_id     = aws_vpc.vpc1.id
  cidr_block = "10.0.1.0/24"
  availability_zone = "us-west-2a"
  route_table_id = aws_route_table.route_table1.id
}

resource "aws_subnet" "subnet2" {
  vpc_id     = aws_vpc.vpc2.id
  cidr_block = "10.1.1.0/24"
  availability_zone = "us-west-2b"
  route_table_id = aws_route_table.route_table2.id
}

resource "aws_subnet" "subnet3" {
  vpc_id     = aws_vpc.vpc3.id
  cidr_block = "10.2.1.0/24"
  availability_zone = "us-west-2c"
  route_table_id = aws_route_table.route_table3.id

# Create Internet Gateway Attachments
resource "aws_vpc_attachment" "igw_attachment1" {
  vpc_id = aws_vpc.vpc1.id
  internet_gateway_id = aws_internet_gateway.igw1.id
}

resource "aws_vpc_attachment" "igw_attachment2" {
  vpc_id = aws_vpc.vpc2.id
  internet_gateway_id = aws_internet_gateway.igw2.id
}

resource "aws_vpc_attachment" "igw_attachment3" {
  vpc_id = aws_vpc.vpc3.id
  internet_gateway_id = aws_internet_gateway.igw3.id
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Task 2: Provisioning EC2 Instances in Different VPCs**
&lt;/h2&gt;

&lt;p&gt;EC2 instances play a pivotal role in hosting applications and services within VPCs. With Terraform, we'll automate the deployment of EC2 instances across these VPCs, setting up Apache web servers using user data. This automated configuration simplifies the initialization process, ensuring that each instance is ready for use upon launch.&lt;/p&gt;

&lt;p&gt;AWS Management Console:&lt;br&gt;
Navigate to the EC2 dashboard.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on "Launch Instance".&lt;/li&gt;
&lt;li&gt;Choose an Amazon Machine Image (AMI) based on your requirements.&lt;/li&gt;
&lt;li&gt;Select the instance type and configure the instance details, including the VPC and subnet.&lt;/li&gt;
&lt;li&gt;Add storage, configure security groups, and define user data scripts for installation or configurations.&lt;/li&gt;
&lt;li&gt;Launch the instance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Terraform Script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Create EC2 Instances
resource "aws_instance" "ec2_instance1" {
  ami           = "ami-12345678" # Replace with RHEL desired AMI ID
  instance_type = "t2.micro" # Change as needed
  subnet_id     = aws_subnet.subnet1.id
  user_data     = &amp;lt;&amp;lt;-EOF
    #!/bin/bash
sudo yum update -y
sudo yum install -y httpd
sudo service httpd start
sudo chkconfig on
sudo chmod -R 755 /var/www/

cat &amp;lt;&amp;lt;HTML &amp;gt; /var/www/html/index.html
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Server Details&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Server Details&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Hostname:&amp;lt;/strong&amp;gt; hostname&amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;IP Address:&amp;lt;/strong&amp;gt; $(hostname -I | awk '{print $1}')&amp;lt;/p&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
HTML
  EOF
}

# Repeat the above code for other 2 aws_instance with different subnet selection.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Task 3:Implementing VPC Transit Gateway**
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Implementing VPC Transit Gateway and Route Table Associations&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the Transit Gateway dashboard, select "Transit Gateways" from the left-hand navigation pane.&lt;br&gt;
Click on "Create Transit Gateway".&lt;br&gt;
Provide a name for the Transit Gateway and configure other settings as needed.&lt;br&gt;
Click "Create" to generate the Transit Gateway.&lt;br&gt;
Attach VPC,Subnet in transit gateway attchment&lt;/p&gt;

&lt;p&gt;Terraform Script&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Create Transit Gateway
resource "aws_ec2_transit_gateway" "my_transit_gateway" {
  description = "My Transit Gateway"
}

# Create Transit Gateway Route Tables
resource "aws_ec2_transit_gateway_route_table" "route_table1" {
  transit_gateway_id = aws_ec2_transit_gateway.my_transit_gateway.id
}

# Associate Route Tables with Attachments
resource "aws_ec2_transit_gateway_route_table_association" "route_table_association1" {
  transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.vpc_attachment_ec2_1.id
  transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.route_table1.id
}

# Repeat the above code for other Transit Gateway route tables and associations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
Setting up a VPC Transit Gateway and deploying EC2 instances across VPCs with Terraform simplifies infrastructure management, ensuring scalability and security. This blog post aimed to guide you through the process and explain the importance of using Infrastructure as Code for AWS setups. We encourage further exploration into Terraform's capabilities for automating and managing AWS infrastructure.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>A Step-by-Step Guide to AWS EC2 Auto Scaling</title>
      <dc:creator>yadanaresh</dc:creator>
      <pubDate>Tue, 31 Oct 2023 18:05:16 +0000</pubDate>
      <link>https://dev.to/nareshaws/a-step-by-step-guide-to-aws-ec2-auto-scaling-3hej</link>
      <guid>https://dev.to/nareshaws/a-step-by-step-guide-to-aws-ec2-auto-scaling-3hej</guid>
      <description>&lt;p&gt;Amazon Web Services (AWS) Elastic Compute Cloud (EC2) is a powerful and flexible cloud computing service that allows you to run virtual machines in the cloud. However, managing the capacity of your EC2 instances manually can be a daunting and time-consuming task. This is where AWS EC2 Auto Scaling comes into play. In this step-by-step guide, we will explore the concept of auto scaling and show you how to set up and configure AWS EC2 Auto Scaling to ensure that your application can handle varying workloads efficiently.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is AWS EC2 Auto Scaling?
&lt;/h2&gt;

&lt;p&gt;AWS EC2 Auto Scaling is a feature that allows you to automatically adjust the number of EC2 instances in your fleet to match your desired capacity. It is designed to help you maintain high availability and cost efficiency by automatically adding or removing instances based on the defined scaling policies and conditions. This ensures that your application can handle varying levels of traffic without manual intervention.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before you begin, make sure you have an AWS account and are logged in to the AWS Management Console.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sign in to AWS Console
&lt;/h2&gt;

&lt;p&gt;To get started with AWS EC2 Auto Scaling, sign in to your AWS Management Console. If you don't have an AWS account, you can sign up for one &lt;a href="https://aws.amazon.com/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Create a Virtual Private Cloud (VPC)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Go to the AWS Management Console.&lt;/li&gt;
&lt;li&gt;Navigate to the VPC service.&lt;/li&gt;
&lt;li&gt;Click on "Create VPC."&lt;/li&gt;
&lt;li&gt;Provide a name for your VPC and specify the IP address range.&lt;/li&gt;
&lt;li&gt;Click "Create VPC."&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 2: Create Two Subnets
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;In the VPC service, go to "Subnets."&lt;/li&gt;
&lt;li&gt;Click "Create Subnet."&lt;/li&gt;
&lt;li&gt;Choose your VPC.&lt;/li&gt;
&lt;li&gt;Specify a name for the subnet.&lt;/li&gt;
&lt;li&gt;Select the availability zone (e.g., us-east-1a).&lt;/li&gt;
&lt;li&gt;Set the IP range for the subnet.&lt;/li&gt;
&lt;li&gt;Click "Create Subnet."&lt;/li&gt;
&lt;li&gt;Repeat the process for the second subnet (e.g., us-east-1b).&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 3: Create an Internet Gateway
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;In the VPC service, go to "Internet Gateways."&lt;/li&gt;
&lt;li&gt;Click "Create Internet Gateway."&lt;/li&gt;
&lt;li&gt;Provide a name for the internet gateway.&lt;/li&gt;
&lt;li&gt;Click "Create Internet Gateway."&lt;/li&gt;
&lt;li&gt;Select the newly created internet gateway and attach it to your VPC.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;u&gt;&lt;em&gt;Step 3.1: Create a Route Table&lt;/em&gt;&lt;/u&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In the VPC service, go to "Route Tables."&lt;/li&gt;
&lt;li&gt;Click "Create Route Table."&lt;/li&gt;
&lt;li&gt;Provide a name for the route table.&lt;/li&gt;
&lt;li&gt;Choose your VPC.&lt;/li&gt;
&lt;li&gt;Click "Create Route Table."&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;u&gt;&lt;em&gt;Step 3.2: Associate Subnets with Route Table&lt;/em&gt;&lt;/u&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Select the newly created route table.&lt;/li&gt;
&lt;li&gt;In the "Subnet Associations" tab, click "Edit subnet associations."&lt;/li&gt;
&lt;li&gt;Associate both of your subnets with the route table.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;u&gt;&lt;em&gt;Step 3.3: Edit Route with Destination&lt;/em&gt;&lt;/u&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In the "Routes" tab of the route table, click "Edit routes."&lt;/li&gt;
&lt;li&gt;Add a route with a destination of "0.0.0.0/0" and select the internet gateway you created.&lt;/li&gt;
&lt;li&gt;Click "Save routes."&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 4: Create a Target Group
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Go to the EC2 service.&lt;/li&gt;
&lt;li&gt;Under the "Load Balancing" section, select "Target Groups."&lt;/li&gt;
&lt;li&gt;Click "Create target group."&lt;/li&gt;
&lt;li&gt;Provide a name for the target group.&lt;/li&gt;
&lt;li&gt;Specify the protocol and port your application uses.&lt;/li&gt;
&lt;li&gt;Choose your VPC.&lt;/li&gt;
&lt;li&gt;Configure health checks as needed.&lt;/li&gt;
&lt;li&gt;Click "Create."&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 5: Create an Application Load Balancer
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;In the EC2 service, under the "Load Balancing" section, select "Load Balancers."&lt;/li&gt;
&lt;li&gt;Click "Create Load Balancer."&lt;/li&gt;
&lt;li&gt;Choose "Application Load Balancer."&lt;/li&gt;
&lt;li&gt;Configure listeners and routing as necessary.&lt;/li&gt;
&lt;li&gt;Select the two subnets you created.&lt;/li&gt;
&lt;li&gt;Configure security groups to allow HTTP traffic and open it to the world.&lt;/li&gt;
&lt;li&gt;Attach the existing target group.&lt;/li&gt;
&lt;li&gt;Click "Create."&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 6: Create Security Groups
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;In the EC2 service, navigate to "Security Groups."&lt;/li&gt;
&lt;li&gt;Create two security groups: one for the Application Load Balancer and another for the EC2 instances launched by Auto Scaling.&lt;/li&gt;
&lt;li&gt;Allow HTTP (port 80) for the Application Load Balancer security group and allow it to be accessed from anywhere.&lt;/li&gt;
&lt;li&gt;For the EC2 instances, allow HTTP (port 80) and SSH (port 22) access, and make them accessible to everyone.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 7: Create a Launch Template
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;In the EC2 service, go to "Launch Templates."&lt;/li&gt;
&lt;li&gt;Click "Create launch template."&lt;/li&gt;
&lt;li&gt;Select the Amazon Machine Image (AMI) you want to use (e.g., RHEL 9).&lt;/li&gt;
&lt;li&gt;Configure the instance type (e.g., t2.micro).&lt;/li&gt;
&lt;li&gt;Ensure that you enable "Auto-assign Public IP."&lt;/li&gt;
&lt;li&gt;Attach the security group you created for EC2 instances.&lt;/li&gt;
&lt;li&gt;Add your SSH key pair.&lt;/li&gt;
&lt;li&gt;In the user data section, add any necessary startup scripts or configurations.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;u&gt;&lt;em&gt;Step 7.1: Create an Auto Scaling Group&lt;/em&gt;&lt;/u&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In the EC2 service, under the "Auto Scaling" section, select "Auto Scaling Groups."&lt;/li&gt;
&lt;li&gt;Click "Create Auto Scaling group."&lt;/li&gt;
&lt;li&gt;Choose the launch template you created.&lt;/li&gt;
&lt;li&gt;Configure network settings by selecting the two subnets you created.&lt;/li&gt;
&lt;li&gt;Attach the existing load balancer and target group.&lt;/li&gt;
&lt;li&gt;Enable health checks and monitoring.&lt;/li&gt;
&lt;li&gt;Set the desired, minimum, and maximum group sizes (e.g., 2, 1, 3).&lt;/li&gt;
&lt;li&gt;Leave scaling policies as "none" for this basic setup.&lt;/li&gt;
&lt;li&gt;Click through the remaining options and create the auto scaling group.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 8: Test and Monitor
&lt;/h2&gt;

&lt;p&gt;After configuring auto scaling, it's crucial to thoroughly test it to ensure that it behaves as expected. You can simulate traffic spikes or resource failures to see if the auto scaling group responds correctly.&lt;/p&gt;

&lt;p&gt;Additionally, use AWS CloudWatch to monitor your instances and scaling activities. Create custom CloudWatch alarms to trigger actions based on specific metrics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fine-Tune and Optimise
&lt;/h2&gt;

&lt;p&gt;Once your auto scaling group is up and running, periodically review your scaling policies and configurations to optimize cost and performance. Adjust the scaling thresholds, instance types, and other settings as needed based on your application's usage patterns.&lt;/p&gt;

&lt;p&gt;"For your convenience, I have prepared a Terraform script that fulfills the aforementioned requirements. This script orchestrates the setup of an AWS infrastructure, incorporating essential components like a VPC, subnets, an internet gateway, security groups, load balancers, launch templates, and an auto-scaling group for EC2 instances."&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Here is Git repo: &lt;a href="https://github.com/yadanaresh/aws-ec2-autoscale.git"&gt;https://github.com/yadanaresh/aws-ec2-autoscale.git&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;AWS EC2 Auto Scaling is a powerful tool for managing the capacity of your EC2 instances automatically. By following this step-by-step guide, you can set up and configure auto scaling to ensure your application can handle varying workloads efficiently, improve availability, and optimize costs. Remember that the key to successful auto scaling is proper planning and monitoring to align your application's performance with your business needs.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Automating S3 File Upload Email Notifications with AWS Lambda and SNS</title>
      <dc:creator>yadanaresh</dc:creator>
      <pubDate>Sat, 21 Oct 2023 02:28:23 +0000</pubDate>
      <link>https://dev.to/nareshaws/automating-s3-file-upload-email-notifications-with-aws-lambda-and-sns-12bh</link>
      <guid>https://dev.to/nareshaws/automating-s3-file-upload-email-notifications-with-aws-lambda-and-sns-12bh</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;br&gt;
In the fast-paced world of cloud computing, automation is the key to efficiency and reliability. One common scenario is the need to receive notifications whenever files are uploaded to an Amazon S3 bucket. In this blog post, we'll explore how to set up an AWS Lambda function to automatically send SNS notifications whenever a file is uploaded to an S3 bucket.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;br&gt;
Before we dive into the technical details, here are some prerequisites to get started:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;An AWS account.&lt;/li&gt;
&lt;li&gt;An S3 bucket where you will upload files.&lt;/li&gt;
&lt;li&gt;An SNS topic for sending notifications.&lt;/li&gt;
&lt;li&gt;Basic knowledge of AWS services and Python.&lt;/li&gt;
&lt;li&gt;Setting Up the AWS Lambda Function&lt;/li&gt;
&lt;li&gt;Creating the Lambda Function&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To create an AWS Lambda function in Python that sends a push notification using Amazon SNS whenever a file is uploaded to an S3 bucket, you can follow these steps. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create an S3 Bucket&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;You can follow on-screen guidance to create an S3 bucket. After successfully creating the bucket, make a note of the bucket name. You will need to update the lambda function code with this bucket name.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1Zysujr7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dljttdpwiqt7nmc2089c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1Zysujr7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dljttdpwiqt7nmc2089c.png" alt="Image description" width="800" height="156"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bucket Name: s3-lambda-sns1&lt;br&gt;
AWS Region : US East(N. Virginia) us-east-1 (&lt;em&gt;Note&lt;/em&gt;, &lt;em&gt;your Lambda,SNS services should be part of same region&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;&lt;u&gt;The rest of the options should remain as their default settings, there is no need for any additional changes.&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--s4RY649O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ankt6znyw0pojogkurgf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--s4RY649O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ankt6znyw0pojogkurgf.png" alt="Image description" width="800" height="778"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IzLrafA5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/77jxw6s3plkekw27usb0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IzLrafA5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/77jxw6s3plkekw27usb0.png" alt="Image description" width="800" height="859"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZBFxtZXI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jqxvd47mywm2wpvdwloa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZBFxtZXI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jqxvd47mywm2wpvdwloa.png" alt="Image description" width="800" height="581"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on &lt;em&gt;Create Bucket&lt;/em&gt; to create the bucket.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create an SNS Topic&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Create an SNS(Simple Notification Service) topic that will be used to send notifications. Note the topic ARN to update in lambda code [YOUR_SNS_TOPIC_ARN].&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GJmY1A5V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tbbac3dvcrbhcdvgmvip.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GJmY1A5V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tbbac3dvcrbhcdvgmvip.png" alt="Image description" width="800" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--A2zH23H7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/98xay52cdrvzeexrme4n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A2zH23H7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/98xay52cdrvzeexrme4n.png" alt="Image description" width="800" height="620"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Q6jqfRBl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l59ybfsi1t885i5oxf2h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Q6jqfRBl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l59ybfsi1t885i5oxf2h.png" alt="Image description" width="800" height="783"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;u&gt;The rest of the options should remain as their default settings, there is no need for any additional changes.&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rQgND6Hs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5nunl61mr2gqsb6xb83e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rQgND6Hs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5nunl61mr2gqsb6xb83e.png" alt="Image description" width="800" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;SNS is services created.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;create Subscription to receive the email alerts&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kG365oLh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5srtxxdiq20tbz0vkw09.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kG365oLh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5srtxxdiq20tbz0vkw09.png" alt="Image description" width="800" height="588"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Once you enter your email address, Amazon will send a confirmation email to the provided address. you should verify it, as email alerts will not be triggered until the email address is verified.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oW4Kod16--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hqg62yng90undhvrsaem.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oW4Kod16--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hqg62yng90undhvrsaem.png" alt="Image description" width="800" height="777"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create an IAM Role&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Create an IAM role for your Lambda function that allows it to interact with S3 and SNS. Attach policies for &lt;code&gt;AmazonS3FullAccess&lt;/code&gt; and &lt;code&gt;AmazonSNSFullAccess&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--16oPFVJc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ws5u8rtavgkokay8vq9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--16oPFVJc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ws5u8rtavgkokay8vq9.png" alt="Image description" width="800" height="241"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UiRC4_5d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8y1o5w3gylwcpvwi5ej6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UiRC4_5d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8y1o5w3gylwcpvwi5ej6.png" alt="Image description" width="800" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OYhsYB6x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e4lhozf6x9estamfmq17.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OYhsYB6x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e4lhozf6x9estamfmq17.png" alt="Image description" width="800" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6uBYWtNL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8ci8l8kte10c878xlj5p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6uBYWtNL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8ci8l8kte10c878xlj5p.png" alt="Image description" width="800" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LN50Z1PI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sd323hlatc7s2sh8oh65.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LN50Z1PI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sd323hlatc7s2sh8oh65.png" alt="Image description" width="800" height="258"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6SGC8zmV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/93gluyut3lymy73wsxml.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6SGC8zmV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/93gluyut3lymy73wsxml.png" alt="Image description" width="800" height="344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create the Lambda Function&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Create a Lambda function with the following Python code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aqaf9bVD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8u0my78yz3uz4jdiyptn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aqaf9bVD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8u0my78yz3uz4jdiyptn.png" alt="Image description" width="800" height="112"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2XoGWmM0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u3145rrydktwnm8i220t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2XoGWmM0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u3145rrydktwnm8i220t.png" alt="Image description" width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--l4aqyp1O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/li1s43h1f43syj3lpghu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--l4aqyp1O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/li1s43h1f43syj3lpghu.png" alt="Image description" width="800" height="171"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7iyzLN3e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ke5ybf48mlo9aplz169r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7iyzLN3e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ke5ybf48mlo9aplz169r.png" alt="Image description" width="800" height="238"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;code for your reference:&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;boto3&lt;/span&gt;

&lt;span class="n"&gt;s3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'s3'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;sns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'sns'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lambda_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Retrieve information about the S3 event
&lt;/span&gt;    &lt;span class="n"&gt;records&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Records'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;records&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'eventName'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;'ObjectCreated:Put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# Extract the bucket and object key from the S3 event
&lt;/span&gt;            &lt;span class="n"&gt;bucket_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'s3'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s"&gt;'bucket'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="n"&gt;object_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'s3'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s"&gt;'object'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s"&gt;'key'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# S3 trigger is added to the Lambda function, S3 values will be automatically loaded
&lt;/span&gt;            &lt;span class="c1"&gt;# Send a notification using SNS
&lt;/span&gt;            &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"File '&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;object_key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;' has been uploaded to the S3 bucket '&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;bucket_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;'."&lt;/span&gt;
            &lt;span class="n"&gt;subject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"S3 File Upload Notification"&lt;/span&gt;

            &lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;TopicArn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'YOUR_SNS_TOPIC_ARN'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Subject&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;'statusCode'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'body'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Notification sent successfully!'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aj515zvJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i0f0foei4i0hcw6mhnjr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aj515zvJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i0f0foei4i0hcw6mhnjr.png" alt="Image description" width="800" height="522"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Bbp5j47h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ob32t0tuyamyp9h353mv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Bbp5j47h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ob32t0tuyamyp9h353mv.png" alt="Image description" width="800" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testing&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;You can test the Lambda function by uploading a file to the specified S3 bucket. You should receive an email notification through the SNS topic when the Lambda function is triggered.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5-1Jk0LY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5rn8wqh6k5972qlzd9pk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5-1Jk0LY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5rn8wqh6k5972qlzd9pk.png" alt="Image description" width="800" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Email alert is triggered after file uploaded to S3&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CuRDdCNe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8zmqpd9kde941ksa1r13.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CuRDdCNe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8zmqpd9kde941ksa1r13.png" alt="Image description" width="800" height="1057"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remember to set up proper error handling, logging, and security best practices in your Lambda function to ensure it works reliably in a production environment. Also, ensure that the IAM role assigned to the Lambda function has appropriate permissions for S3 and SNS.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
In this blog post, we've demonstrated how to automate the process of sending SNS notifications whenever a file is uploaded to an S3 bucket using AWS Lambda. This approach is a valuable addition to your cloud automation toolkit, providing real-time alerts for file uploads.&lt;/p&gt;

&lt;p&gt;By following the steps outlined in this blog post, you can easily set up your own S3 file upload notification system and adapt it to your specific use case. Automation not only saves time but also enhances the reliability and responsiveness of your AWS infrastructure.&lt;/p&gt;

&lt;p&gt;Stay tuned for more AWS and cloud-related tips and tutorials!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
