<?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: Samuel Udeh</title>
    <description>The latest articles on DEV Community by Samuel Udeh (@samuel_udeh).</description>
    <link>https://dev.to/samuel_udeh</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%2F1550542%2Fd9d6fdad-a4a8-4a93-9f04-3bf2db721649.JPG</url>
      <title>DEV Community: Samuel Udeh</title>
      <link>https://dev.to/samuel_udeh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/samuel_udeh"/>
    <language>en</language>
    <item>
      <title>🚀 Building a Multi-Environment Web Application Infrastructure with Auto-Scaling on AWS Using Terraform</title>
      <dc:creator>Samuel Udeh</dc:creator>
      <pubDate>Thu, 28 Aug 2025 15:27:43 +0000</pubDate>
      <link>https://dev.to/samuel_udeh/building-a-multi-environment-web-application-infrastructure-with-auto-scaling-on-aws-using-43m9</link>
      <guid>https://dev.to/samuel_udeh/building-a-multi-environment-web-application-infrastructure-with-auto-scaling-on-aws-using-43m9</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In today’s cloud-native world, applications need to scale dynamically, stay cost-efficient, and remain reproducible across environments (dev, staging, prod). To achieve this, I built a Multi-Environment Web Application Infrastructure with Auto-Scaling using Terraform on AWS.&lt;/p&gt;

&lt;p&gt;This project was a hands-on demonstration of Infrastructure as Code (IaC), scalable architecture design, and DevOps automation.&lt;/p&gt;

&lt;p&gt;🎯 &lt;strong&gt;Project Goals&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Provision AWS infrastructure for multiple environments (dev, prod).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Automate resource creation using Terraform modules.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deploy a simple web app served by Nginx.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Configure Application Load Balancer (ALB) + Auto Scaling Group (ASG).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ensure traffic is distributed and scaling happens automatically under load.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🏗️ &lt;strong&gt;Architecture&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here’s the high-level architecture I built:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;VPC with public and private subnets across multiple AZs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Internet Gateway and NAT Gateway for proper routing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Application Load Balancer (ALB) in public subnets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Auto Scaling Group (ASG) in private subnets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;EC2 instances bootstrapped with user_data to install Nginx and serve a web page.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CloudWatch Alarms to scale out/in based on CPU utilization.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;📌 When traffic increases → ASG scales out by launching new EC2 instances.&lt;br&gt;
📌 When traffic decreases → ASG scales in, saving costs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F6rz3z3cs4rubi0pwpoc4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F6rz3z3cs4rubi0pwpoc4.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Before you start, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS account&lt;/li&gt;
&lt;li&gt;Terraform installed&lt;/li&gt;
&lt;li&gt;AWS CLI installed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Authenticate Terraform With AWS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To authenticate Terraform with AWS, you can follow these steps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configure AWS CLI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open your terminal, and run the following command to configure the AWS CLI:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Enter the following details when prompted:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS Access Key ID: Your access key ID.&lt;/li&gt;
&lt;li&gt;AWS Secret Access Key: Your secret access key.&lt;/li&gt;
&lt;li&gt;Default region name: The AWS region you want to use (e.g., us-east-1).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Project Structure:&lt;/strong&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-web-platform/
├── environments/
│   ├── dev/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   ├── outputs.tf
│   │   ├── terraform.tfvars         
│   │                 
│   └── prod/
│       ├── main.tf
│       ├── variables.tf
│       ├── outputs.tf
│       ├── terraform.tfvars
│       
├── modules/
│   ├── networking/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── outputs.tf
│   ├── compute/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── outputs.tf
│   ├── database/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── outputs.tf
│   └── monitoring/
│       ├── main.tf
│       ├── variables.tf
│       └── outputs.tf                  
├── README.md
└── .gitignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🛠️ &lt;strong&gt;Implementation with Terraform&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I structured my Terraform project into reusable modules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Network/ → VPC, Subnets, Routing, NAT&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Security/ → Security Groups, Ingress/Egress rules&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compute/ → ASG, Launch Templates, User Data&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Loadbalancer/ → ALB + Target Groups + Listeners&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A snippet of my user_data (runs on EC2 launch):&lt;/p&gt;

&lt;h1&gt;
  
  
  !/bin/bash
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apt-get update -y
apt-get install -y nginx
echo "Hello from ${var.environment} - ${var.project}" &amp;gt; /var/www/html/index.html
systemctl enable nginx &amp;amp;&amp;amp; systemctl start nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures every new EC2 instance in the ASG automatically serves a simple environment-specific message.&lt;/p&gt;

&lt;p&gt;🔍 &lt;strong&gt;Testing the Setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After applying Terraform (terraform apply), I tested the deployment:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F32ad3swstoe164ignrhi.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F32ad3swstoe164ignrhi.JPG" alt=" " width="800" height="242"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Checked the ALB DNS Name&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Terraform outputs alb_dns_name:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://web-platform-dev-alb-495228054.eu-north-1.elb.amazonaws.com/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Opening this URL displayed my Nginx welcome message. ✅&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Load Testing For Auto Scaling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I validated the Auto Scaling setup by simulating high traffic using Apache Bench. The test successfully triggered CloudWatch alarms, which in turn scaled out the Auto Scaling Group by adding EC2 instances. When traffic normalized, scale-in policies removed extra instances, ensuring efficiency and cost optimization&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ab -n 1000 -c 100 http://&amp;lt;your-alb-dns-name&amp;gt;/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;-n 1000 → Total number of requests = 1000&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;-c 100 → Concurrency level = 100 requests at the same time&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;http:/// → Target URL (the ALB’s DNS name)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At high load, CloudWatch alarms triggered scale-out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Observed Scaling&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;ASG increased desired capacity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New EC2 instances launched and registered with the ALB.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When traffic reduced, ASG scaled back in automatically.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;📊 &lt;strong&gt;Results&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;✅ Highly Available: Load Balancer ensured zero downtime during scaling.&lt;/p&gt;

&lt;p&gt;✅ Scalable: ASG responded dynamically to CPU load.&lt;/p&gt;

&lt;p&gt;✅ Environment-Aware: Different environments (dev, staging, prod) could be deployed with the same modules.&lt;/p&gt;

&lt;p&gt;✅ Cost-Efficient: Unused capacity scaled in automatically.&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Key Learnings&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Modular Terraform makes infrastructure reusable and easy to extend.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CloudWatch Alarms + ASG are powerful for real-world auto-healing &amp;amp; scaling.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;IaC ensures consistency across environments and reduces manual errors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing Auto Scaling with stress/load tools validates that your setup actually works.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;📌 &lt;strong&gt;Next Steps&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Add HTTPS (TLS/SSL) with ACM + ALB.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement Terraform remote backend with state locking (e.g., S3 + DynamoDB or HCP Terraform).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Integrate CI/CD pipeline for infrastructure deployments.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;This project gave me a solid foundation in building scalable, production-ready infrastructure on AWS using Terraform. It reflects real-world patterns used in modern cloud deployments and can be extended to host any kind of application.&lt;/p&gt;

&lt;p&gt;👉 Check out the repo here: &lt;a href="https://github.com/SamuelUdeh/terraform-aws-multi-env" rel="noopener noreferrer"&gt;https://github.com/SamuelUdeh/terraform-aws-multi-env&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Deploying a Netlify Site with Terraform + HCP Remote State</title>
      <dc:creator>Samuel Udeh</dc:creator>
      <pubDate>Fri, 22 Aug 2025 11:00:23 +0000</pubDate>
      <link>https://dev.to/samuel_udeh/deploying-a-netlify-site-with-terraform-hcp-remote-state-37dj</link>
      <guid>https://dev.to/samuel_udeh/deploying-a-netlify-site-with-terraform-hcp-remote-state-37dj</guid>
      <description>&lt;p&gt;Infrastructure as Code (IaC) is about making deployments reproducible, automated, and collaborative. In this project, I built and deployed a static website on Netlify using Terraform, while storing the Terraform state securely in HCP Terraform (Terraform Cloud).&lt;/p&gt;

&lt;p&gt;This was part of the Terraform Challenge, and I’ll walk you through what I did and how you can replicate it.&lt;/p&gt;

&lt;p&gt;🎯 &lt;strong&gt;Project Goals&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Deploy a static frontend site to Netlify&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Manage it with Terraform (Infrastructure as Code)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Store Terraform state in HCP Terraform (Terraform Cloud)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Keep secrets out of the repo (use workspace env vars instead)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make the setup re-runnable and reproducible&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Live Site 👉 comforting-fudge-57ff13.netlify.app&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repo 👉 github.com/SamuelUdeh/terraform-netlify-challenge&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🛠 &lt;strong&gt;Tools I Used&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Terraform → To define infrastructure as code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;HCP Terraform (Terraform Cloud) → To store remote state securely&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Netlify → To host the static site&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GitHub → Version control + Netlify deploy hook&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;⚙️ &lt;strong&gt;How It Works&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Static Site → A minimal index.html page lives in /site.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Netlify → Hosts the site, automatically deploying on every push to main.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Terraform → Manages Netlify site settings (publish dir, environment variables).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;HCP Terraform → Stores state remotely, enabling collaboration and history.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Architecture Flow:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GitHub Repo  ---&amp;gt;  Netlify (Site Hosting) ---&amp;gt; Live URL&lt;br&gt;
       |&lt;br&gt;
       +---&amp;gt; Terraform ---&amp;gt; HCP Terraform (Remote State)&lt;/p&gt;

&lt;p&gt;🧑‍💻 &lt;strong&gt;Step-by-Step Setup&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Terraform ≥ 1.6&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Accounts: Netlify, GitHub, HCP Terraform&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Netlify Personal Access Token (NETLIFY_TOKEN)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;2.&lt;strong&gt;Create Site in Netlify&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In Netlify: New site from Git → connect repo → publish directory = site&lt;/p&gt;

&lt;p&gt;3.&lt;strong&gt;Configure HCP Terraform&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create Organization + Workspace&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add NETLIFY_TOKEN as a sensitive environment variable&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;4.&lt;strong&gt;Terraform Config&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Example versions.tf:&lt;/p&gt;

&lt;p&gt;terraform {&lt;br&gt;
  required_providers {&lt;br&gt;
    netlify = {&lt;br&gt;
      source  = "netlify/netlify"&lt;br&gt;
      version = "~&amp;gt; 0.2"&lt;br&gt;
    }&lt;br&gt;
    random = {&lt;br&gt;
      source  = "hashicorp/random"&lt;br&gt;
      version = "~&amp;gt; 3.6"&lt;br&gt;
    }&lt;br&gt;
  }&lt;/p&gt;

&lt;p&gt;cloud {&lt;br&gt;
    organization = "your-org"&lt;br&gt;
    workspaces {&lt;br&gt;
      name = "portfolio-site-workspace"&lt;br&gt;
    }&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;outputs.tf:&lt;/p&gt;

&lt;p&gt;output "live_url" {&lt;br&gt;
  value = "https://${var.site_name}.netlify.app"&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;5.&lt;strong&gt;Run Terraform&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;terraform init&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;terraform plan&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;terraform apply&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Output:&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Outputs:&lt;/strong&gt;&lt;br&gt;
live_url = "&lt;a href="https://comforting-fudge-57ff13.netlify.app" rel="noopener noreferrer"&gt;https://comforting-fudge-57ff13.netlify.app&lt;/a&gt;"&lt;br&gt;
repo = "&lt;a href="https://github.com/SamuelUdeh/terraform-netlify-challenge" rel="noopener noreferrer"&gt;https://github.com/SamuelUdeh/terraform-netlify-challenge&lt;/a&gt;"&lt;/p&gt;

&lt;p&gt;🔑 &lt;strong&gt;Lessons Learned&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Netlify provider doesn’t create sites (yet), you create the site in the UI once, then manage settings via Terraform.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remote state in HCP Terraform is safer and team-ready vs local terraform.tfstate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Keep secrets out of code, use workspace environment variables like NETLIFY_TOKEN.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Even a minimal project (simple HTML site) is enough to demonstrate IaC principles.&lt;/p&gt;

&lt;p&gt;📸 Deliverables&lt;/p&gt;

&lt;p&gt;✅ Repo with Terraform + site&lt;/p&gt;

&lt;p&gt;✅ Remote state in HCP Terraform&lt;/p&gt;

&lt;p&gt;✅ Live Netlify URL&lt;/p&gt;

&lt;p&gt;🌟 Wrap Up&lt;/p&gt;

&lt;p&gt;This challenge showed how simple it is to connect Terraform → Netlify → HCP Terraform and manage even small projects as Infrastructure as Code.&lt;/p&gt;

&lt;p&gt;Try it yourself:&lt;br&gt;
👉 Clone my repo, configure HCP Terraform, and run terraform apply.&lt;/p&gt;

&lt;p&gt;Happy coding, and thanks to HUG-Ibadan for the challenge inspiration! 🙌&lt;/p&gt;

</description>
    </item>
    <item>
      <title>State Isolation: Layout vs Workspace</title>
      <dc:creator>Samuel Udeh</dc:creator>
      <pubDate>Wed, 25 Dec 2024 06:51:32 +0000</pubDate>
      <link>https://dev.to/samuel_udeh/state-isolation-layout-vs-workspace-ji9</link>
      <guid>https://dev.to/samuel_udeh/state-isolation-layout-vs-workspace-ji9</guid>
      <description>&lt;p&gt;Terraform State isolation refers to the practice of managing and organizing your infrastructure state files to ensure that different environments or projects do not interfere with one another. There are two ways you could isolate state files:&lt;br&gt;
&lt;strong&gt;Isolation via workspaces&lt;/strong&gt;&lt;br&gt;
Useful for quick, isolated tests on the same configuration&lt;br&gt;
&lt;strong&gt;Isolation via file layout&lt;/strong&gt;&lt;br&gt;
Useful for production use cases for which you need strong separation between environments.&lt;/p&gt;

&lt;p&gt;In this blog post, we’ll focus on Workspace-based Isolation, providing examples to demonstrate its capabilities.&lt;br&gt;
&lt;strong&gt;Isolation via Workspaces&lt;/strong&gt;&lt;br&gt;
Terraform workspaces allow you to store your Terraform state in multiple, separate, named workspaces. Terraform starts with a single workspace called “default,” and if you never explicitly specify a workspace, the default workspace is the one you’ll use&lt;br&gt;
the entire time. To create a new workspace or switch between workspaces, you use the terraform workspace commands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;main.tf&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;provider "aws" {&lt;br&gt;
  region = "us-east-1"  # Adjust as needed&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_instance" "example" {&lt;br&gt;
  ami = "ami-0e2c8caa4b6378d8c"&lt;br&gt;
  instance_type = "t2.micro"&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_s3_bucket" "terraform_state" {&lt;br&gt;
  bucket = "samley-bucket"  # Ensure this name is unique across all of AWS&lt;br&gt;
  acl    = "private"         # Set the ACL for the bucket&lt;/p&gt;

&lt;p&gt;versioning {&lt;br&gt;
    enabled = true  # Enable versioning&lt;br&gt;
  }&lt;/p&gt;

&lt;p&gt;# Enable server-side encryption&lt;br&gt;
  server_side_encryption_configuration {&lt;br&gt;
    rule {&lt;br&gt;
      apply_server_side_encryption_by_default {&lt;br&gt;
        sse_algorithm = "AES256"  # Use S3-managed keys for encryption&lt;br&gt;
      }&lt;br&gt;
    }&lt;br&gt;
  }&lt;/p&gt;

&lt;p&gt;lifecycle {&lt;br&gt;
    prevent_destroy = false # Prevent accidental deletion&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;h1&gt;
  
  
  Block public access settings for the bucket
&lt;/h1&gt;

&lt;p&gt;resource "aws_s3_bucket_public_access_block" "public_access" {&lt;br&gt;
  bucket                  = aws_s3_bucket.terraform_state.id&lt;br&gt;
  block_public_acls       = true&lt;br&gt;
  ignore_public_acls      = true&lt;br&gt;
  block_public_policy      = true&lt;br&gt;
  restrict_public_buckets  = true&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_dynamodb_table" "terraform_locks" {&lt;br&gt;
  name         = "state-locks"&lt;br&gt;
  billing_mode = "PAY_PER_REQUEST"&lt;br&gt;
  hash_key     = "LockID"&lt;/p&gt;

&lt;p&gt;attribute {&lt;br&gt;
    name = "LockID"&lt;br&gt;
    type = "S"&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;output "s3_bucket_arn" {&lt;br&gt;
  value       = aws_s3_bucket.terraform_state.arn&lt;br&gt;
  description = "The ARN of the S3 bucket"&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;output "dynamodb_table_name" {&lt;br&gt;
  value       = aws_dynamodb_table.terraform_locks.name&lt;br&gt;
  description = "The name of the DynamoDB table"&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Run the &lt;strong&gt;terraform plan&lt;/strong&gt;&lt;br&gt;
Run the &lt;strong&gt;terraform apply&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After creating the resources, the new backend &lt;strong&gt;s3&lt;/strong&gt; code can now be added to the configuration...&lt;/p&gt;

&lt;p&gt;terraform {&lt;br&gt;
  backend "s3" {&lt;br&gt;
    bucket         = "samley-bucket"&lt;br&gt;&lt;br&gt;
    key            = "workspaces-example/terraform.tfstate"&lt;br&gt;&lt;br&gt;
    region         = "us-east-1"&lt;br&gt;&lt;br&gt;
    dynamodb_table = "state-locks"&lt;br&gt;&lt;br&gt;
    encrypt        = true&lt;br&gt;&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Run &lt;strong&gt;terraform init&lt;/strong&gt;&lt;br&gt;
Run &lt;strong&gt;terraform apply&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The state for this deployment is stored in the default workspace. You can confirm this by running the &lt;strong&gt;terraform workspace show&lt;/strong&gt; command,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fu5rejmso0503hxmb4mla.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fu5rejmso0503hxmb4mla.JPG" alt="Image description" width="800" height="135"&gt;&lt;/a&gt;&lt;br&gt;
The default workspace stores your state in exactly the location you specify via the key configuration. As shown in the Figure below, if you take a look in your S3 bucket, you’ll&lt;br&gt;
find a terraform.tfstate file in the workspaces-example folder. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F038pvhwncqe2ykh1jqcr.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F038pvhwncqe2ykh1jqcr.JPG" alt="Image description" width="800" height="337"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Managing Workspaces&lt;/strong&gt;&lt;br&gt;
You can create and switch between workspaces using the Terraform commands:&lt;/p&gt;

&lt;h1&gt;
  
  
  Create workspaces
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;terraform workspace new example1&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;terraform workspace new example2&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Switch to a workspace
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;terraform workspace select example1&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Plan&lt;/strong&gt; and &lt;strong&gt;Apply&lt;/strong&gt; changes to the current workspace
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;terraform plan&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;terraform apply&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Terraform wants to create a totally new EC2 Instance from scratch! That’s because the state files in each workspace are isolated from one another, and because you’re now in the example1 workspace, Terraform isn’t using the state file from the default&lt;br&gt;
workspace and therefore doesn’t see the EC2 Instance was already created there.&lt;br&gt;
By running terraform apply, to deploy this second EC2 Instance in the new workspace. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F8xcxsozwtdtg5vf4eezo.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F8xcxsozwtdtg5vf4eezo.JPG" alt="Image description" width="800" height="342"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example above,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;example1&lt;/strong&gt; workspace uses the state file &lt;strong&gt;example1/terraform.tfstate&lt;/strong&gt;.
The &lt;strong&gt;example2&lt;/strong&gt; workspace uses the state file &lt;strong&gt;example2/terraform.tfstate&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Inside each of those workspaces, Terraform uses the key you specified in your backend configuration, so you should find an example1/workspaces-example/terraform.tfstate and an example2/workspaces-example/terraform.tfstate. In other words,&lt;br&gt;
switching to a different workspace is equivalent to changing the path where your statefile is stored.&lt;/p&gt;

&lt;p&gt;To avoid unnecessary charges, delete the bucket by destroying the infrastructure using the &lt;strong&gt;terraform destroy&lt;/strong&gt; command&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CONCLUSION&lt;/strong&gt;&lt;br&gt;
Terraform workspaces allow you to run terraform workspace new and deploy a new copy of the exact same infrastructure, but storing the state in a separate file.&lt;br&gt;
Workspace-based isolation offers a flexible way to manage multiple environments with a shared Terraform configuration. By associating each workspace with its own state file, you can ensure environment-specific changes without interference.&lt;/p&gt;

&lt;p&gt;Let us know how you’re using Terraform workspaces in your projects! Happy Terraforming!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Managing Terraform State: Best Practices for DevOps</title>
      <dc:creator>Samuel Udeh</dc:creator>
      <pubDate>Sun, 22 Dec 2024 12:35:18 +0000</pubDate>
      <link>https://dev.to/samuel_udeh/managing-terraform-state-best-practices-for-devops-12h4</link>
      <guid>https://dev.to/samuel_udeh/managing-terraform-state-best-practices-for-devops-12h4</guid>
      <description>&lt;p&gt;Managing Terraform state is crucial for maintaining the integrity and reliability of your infrastructure as code (IaC) deployments.&lt;/p&gt;

&lt;p&gt;The Terraform state file is a crucial component of how Terraform manages infrastructure. It acts as a source of truth for the current state of your managed resources.&lt;/p&gt;

&lt;p&gt;This project can help teams understand and implement effective state management practices in their Terraform workflows. It aims to demonstrate best practices for managing Terraform state files in a collaborative DevOps environment. It will cover setting up a Terraform project, configuring remote state storage, applying state locking, and implementing security measures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Objectives&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Understand the structure and purpose of the Terraform state file.&lt;/li&gt;
&lt;li&gt;Configure remote state storage using AWS S3 with state locking.&lt;/li&gt;
&lt;li&gt;Implement best practices for managing sensitive data.&lt;/li&gt;
&lt;li&gt;Demonstrate regular maintenance and backup strategies for state files.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ol&gt;
&lt;li&gt;Basic knowledge of Terraform and infrastructure as code (IaC).&lt;/li&gt;
&lt;li&gt;AWS account with necessary permissions.&lt;/li&gt;
&lt;li&gt;Terraform installed on your local machine.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Tools and Technologies&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Terraform&lt;/li&gt;
&lt;li&gt;AWS (S3, DynamoDB)&lt;/li&gt;
&lt;li&gt;Git (for version control)&lt;/li&gt;
&lt;li&gt;HashiCorp Vault (optional for secrets management)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step-by-Step Guide to Managing Terraform State&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Step 1:&lt;/strong&gt; &lt;strong&gt;Set Up the Terraform Project&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Create a Project Directory:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F2owwr9fcoyhokpddnvve.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F2owwr9fcoyhokpddnvve.JPG" alt="Image description" width="800" height="80"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Step 2:&lt;/strong&gt; &lt;strong&gt;Set Up the AWS Provider&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fxnda4g2nz8ol5xpdixn2.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fxnda4g2nz8ol5xpdixn2.JPG" alt="Image description" width="780" height="195"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Step 3:&lt;/strong&gt; &lt;strong&gt;Create an S3 Bucket for Remote State Storage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fcjt2nx2eur7mwld98jav.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fcjt2nx2eur7mwld98jav.JPG" alt="Image description" width="800" height="187"&gt;&lt;/a&gt;&lt;br&gt;
An S3 bucket is configured to store the Terraform state file. The prevent_destroy lifecycle rule ensures the bucket cannot be accidentally deleted&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4:&lt;/strong&gt; &lt;strong&gt;Enable Versioning on the S3 Bucket&lt;/strong&gt;&lt;br&gt;
Versioning allows you to see older versions of the file and revert to those older versions at any time, which can be a useful fallback mechanism if something goes wrong.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F3bu5ti2h8mmk1peomtsn.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F3bu5ti2h8mmk1peomtsn.JPG" alt="Image description" width="674" height="186"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5:&lt;/strong&gt; &lt;strong&gt;Set Up Server-Side Encryption&lt;/strong&gt;&lt;br&gt;
This ensures that your state files, and any secrets they might contain, are always encrypted on disk when stored in S3&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ff0uqjhcxcs6bvd9r29bw.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ff0uqjhcxcs6bvd9r29bw.JPG" alt="Image description" width="800" height="216"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Step 6:&lt;/strong&gt; &lt;strong&gt;Block Public Access to the S3 Bucket&lt;/strong&gt;&lt;br&gt;
Block all public access to the S3 bucket to ensure no one on your&lt;br&gt;
team can ever accidentally make this S3 bucket public.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Flixquo2ngrgfrhbpzydc.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Flixquo2ngrgfrhbpzydc.JPG" alt="Image description" width="800" height="207"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7:&lt;/strong&gt; &lt;strong&gt;Create a DynamoDB Table for State Locking&lt;/strong&gt;&lt;br&gt;
A DynamoDB table is configured to enable state locking, which prevents concurrent updates to the state file, preventing two team members from running terraform apply on the same state file at the same time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fy66rhkc2quqhtaej19jf.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fy66rhkc2quqhtaej19jf.JPG" alt="Image description" width="800" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Backend Configuration Restrictions:&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;No References to Resources:&lt;/strong&gt; In Terraform, when configuring the backend (like S3), you cannot reference resources that are defined in the same file. This is a fundamental design choice to ensure that the backend is properly initialized before any resources are created.&lt;br&gt;
&lt;strong&gt;Direct Specification Required:&lt;/strong&gt; You must specify the bucket name and DynamoDB table name directly in the backend configuration.&lt;br&gt;
&lt;strong&gt;State Initialization:&lt;/strong&gt;&lt;br&gt;
If you're trying to initialize a backend that references resources not yet created, you'll get errors. You need to ensure that the backend is set up in a way that allows for its own initialization.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps to Resolve&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Separate the Initialization:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First, create the S3 bucket and DynamoDB table in a separate configuration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy the State Management Resources:&lt;/strong&gt;
Here, you use the &lt;strong&gt;terraform init&lt;/strong&gt; and &lt;strong&gt;terraform apply&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Update the Main Configuration:&lt;/strong&gt;
After successfully creating the resources, update your main Terraform configuration to use the bucket and table names directly. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 8:&lt;/strong&gt; &lt;strong&gt;Configure Terraform Backend&lt;/strong&gt;&lt;br&gt;
The Terraform backend stores the state in your S3 bucket with encryption and locking.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F3rutx22w5evohnc8c87k.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F3rutx22w5evohnc8c87k.JPG" alt="Image description" width="800" height="252"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 9:&lt;/strong&gt; &lt;strong&gt;Output Key Resource Information&lt;/strong&gt;&lt;br&gt;
These variables will print out the Amazon Resource Name (ARN) of your S3 bucket and the name of your DynamoDB table.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F9pjb6kt8vuezquqh4zhb.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F9pjb6kt8vuezquqh4zhb.JPG" alt="Image description" width="800" height="263"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fbg9j6te4enxl53nijteq.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fbg9j6te4enxl53nijteq.JPG" alt="Image description" width="800" height="216"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;How Each Step Aligns with Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Remote State Storage:&lt;/strong&gt; The S3 bucket ensures the state file is stored securely and accessible to the team.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fzu637qajc5n0pdy3zn9c.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fzu637qajc5n0pdy3zn9c.JPG" alt="Image description" width="800" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;State Locking:&lt;/strong&gt; The DynamoDB table prevents simultaneous state modifications, avoiding conflicts.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fzcgs3nkydzgoqbwog5k3.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fzcgs3nkydzgoqbwog5k3.JPG" alt="Image description" width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Versioning:&lt;/strong&gt; Versioning allows you to see older versions of the file and revert to those older versions at any time.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Flrpow6utu5es56bbynrq.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Flrpow6utu5es56bbynrq.JPG" alt="Image description" width="800" height="348"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Encryption: AES256 encryption secures the state file.&lt;/li&gt;
&lt;li&gt;Access Control: Public access to the S3 bucket is restricted to protect sensitive data.&lt;/li&gt;
&lt;li&gt;Lifecycle Management: The prevent_destroy rule ensures critical resources are not accidentally deleted.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By following these steps and best practices, you can effectively manage Terraform state, enhancing the security, collaboration, and reliability of your infrastructure.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Managing high traffic applications with AWS Elastic Load Balancer and Terraform</title>
      <dc:creator>Samuel Udeh</dc:creator>
      <pubDate>Fri, 20 Dec 2024 22:01:45 +0000</pubDate>
      <link>https://dev.to/samuel_udeh/managing-high-traffic-applications-with-aws-elastic-load-balancer-and-terraform-418h</link>
      <guid>https://dev.to/samuel_udeh/managing-high-traffic-applications-with-aws-elastic-load-balancer-and-terraform-418h</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;br&gt;
Managing high-traffic applications can be a daunting challenge, especially when trying to ensure that the system is both scalable and highly available. As businesses grow and their user bases expand, the ability to scale infrastructure dynamically becomes crucial. &lt;strong&gt;AWS Elastic Load Balancer&lt;/strong&gt; (ELB) is one of the most powerful tools for distributing incoming application traffic across multiple targets, such as Amazon EC2 instances, containers, or IP addresses. When paired with Terraform, an infrastructure-as-code tool, it becomes even easier to provision, manage, and scale high-traffic applications.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fap08o51rnj9n2kbalcvq.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fap08o51rnj9n2kbalcvq.JPG" alt="Image description" width="596" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is AWS Elastic Load Balancer?&lt;/strong&gt;&lt;br&gt;
AWS Elastic Load Balancer (ELB) is a fully managed service that automatically distributes incoming application traffic across multiple targets to ensure that your application performs reliably.&lt;br&gt;
&lt;strong&gt;AWS offers three types of load balancers:&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Application Load Balancer (ALB)&lt;/strong&gt;&lt;br&gt;
Best suited for load balancing of HTTP and HTTPS traffic. Operates at the&lt;br&gt;
application layer (Layer 7) of the Open Systems Interconnection (OSI) model.&lt;br&gt;
&lt;strong&gt;Network Load Balancer (NLB)&lt;/strong&gt;&lt;br&gt;
Best suited for load balancing of TCP, UDP, and TLS traffic. Can scale up and&lt;br&gt;
down in response to load faster than the ALB (the NLB is designed to scale to&lt;br&gt;
tens of millions of requests per second). Operates at the transport layer (Layer 4)&lt;br&gt;
of the OSI model.&lt;br&gt;
&lt;strong&gt;Classic Load Balancer (CLB)&lt;/strong&gt;&lt;br&gt;
This is the “legacy” load balancer that predates both the ALB and NLB. It can handle HTTP, HTTPS, TCP, and TLS traffic but with far fewer features than either the ALB or NLB. Operates at both the application layer (L7) and transport layer (L4) of the OSI model.&lt;br&gt;
Most applications these days should use either the ALB or the NLB. Because the simple web server example you’re working on is an HTTP app without any extreme performance requirements, the ALB is going to be the best fit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Components&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Elastic Load Balancer (ELB)&lt;/strong&gt;: Distributes incoming application traffic across multiple targets, such as EC2 instances.&lt;br&gt;
&lt;strong&gt;Auto Scaling Groups (ASG)&lt;/strong&gt;: Automatically adjusts the number of EC2 instances based on traffic demands.&lt;br&gt;
&lt;strong&gt;Health Checks&lt;/strong&gt;: Ensures that only healthy instances receive traffic.&lt;br&gt;
&lt;strong&gt;Security Groups&lt;/strong&gt;: Controls access to the load balancer and backend instances.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Flf4u6pyh5s3xyiskixdn.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Flf4u6pyh5s3xyiskixdn.JPG" alt="Image description" width="800" height="684"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Setting Up The Infrastructure&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Step 1&lt;/strong&gt;: Define the provider&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fshrh4u87n6ypr3v5qe3i.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fshrh4u87n6ypr3v5qe3i.JPG" alt="Image description" width="780" height="195"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Provider:&lt;/strong&gt; Specifies the AWS provider and the region where the resources will be created.&lt;br&gt;
&lt;strong&gt;Data Resource:&lt;/strong&gt; Fetches the available availability zones for resource distribution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;: Create the VPC and Subnets&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fdh3wdtoy58prwbr0z8cp.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fdh3wdtoy58prwbr0z8cp.JPG" alt="Image description" width="800" height="505"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F3zuem6c54bsjezqs8gzx.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F3zuem6c54bsjezqs8gzx.JPG" alt="Image description" width="800" height="172"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;VPC:&lt;/strong&gt; Creates a VPC with a CIDR block of 10.0.0.0/16.&lt;br&gt;
&lt;strong&gt;Internet Gateway:&lt;/strong&gt; Allows external access to the VPC.&lt;br&gt;
&lt;strong&gt;Route Table&lt;/strong&gt;: Defines routes that send traffic to the internet.&lt;br&gt;
&lt;strong&gt;Subnets:&lt;/strong&gt; Creates two public subnets in different availability zones for high availability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; Create Security Groups&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fqsc5i0zfcs5c1arcnuxq.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fqsc5i0zfcs5c1arcnuxq.JPG" alt="Image description" width="800" height="499"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Security Group:&lt;/strong&gt; Allows incoming traffic on port 80 (HTTP) from any IP address. Egress rules allow all outbound traffic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5:&lt;/strong&gt; Create Application Load Balancer&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F01zpggg0r6am6snkl0ei.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F01zpggg0r6am6snkl0ei.JPG" alt="Image description" width="719" height="241"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;ALB:&lt;/strong&gt; Creates an application load balancer that distributes incoming traffic across the healthy targets. It is publicly accessible and associated with the security group and public subnets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6:&lt;/strong&gt; Create Target Group&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fx15ie40g9aaa0okdid9v.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fx15ie40g9aaa0okdid9v.JPG" alt="Image description" width="800" height="380"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Target Group:&lt;/strong&gt; Defines a group of instances that the ALB will forward traffic to. It includes health checks to monitor the status of the instances&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7:&lt;/strong&gt; Create Load Balancer Listener&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fy19zfzqejqsz3pk3ybil.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fy19zfzqejqsz3pk3ybil.JPG" alt="Image description" width="800" height="334"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Listener:&lt;/strong&gt; Configures the ALB to listen on port 80 and forward traffic to the target group.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 8:&lt;/strong&gt; Create Launch Template&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fup2i2oc412ibfrp0yfmd.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fup2i2oc412ibfrp0yfmd.JPG" alt="Image description" width="800" height="271"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Launch Template:&lt;/strong&gt; Defines the configuration for EC2 instances, including the AMI ID, instance type, and network settings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 9:&lt;/strong&gt; Create Auto Scaling Group&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F53jcw4iw2a16mlscdor3.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F53jcw4iw2a16mlscdor3.JPG" alt="Image description" width="800" height="474"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;ASG:&lt;/strong&gt; Manages a group of EC2 instances. It defines the desired, minimum, and maximum number of instances. It uses the launch template for configuration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 10:&lt;/strong&gt; Create Scaling Policies&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F84lfu90a7tqiukewwf5u.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F84lfu90a7tqiukewwf5u.JPG" alt="Image description" width="800" height="439"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Scaling Policies:&lt;/strong&gt; Define how the ASG should respond to changes in demand. The scale-out policy increases the number of instances, while the scale-in policy decreases them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 11:&lt;/strong&gt; Create Output&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Flwipmudsvyc31jgna2z2.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Flwipmudsvyc31jgna2z2.JPG" alt="Image description" width="800" height="111"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Output:&lt;/strong&gt; Displays the DNS name of the load balancer once the infrastructure is created.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F19qxikorgc4w0lwt5s9a.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F19qxikorgc4w0lwt5s9a.JPG" alt="Image description" width="800" height="508"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations!&lt;br&gt;
This Terraform configuration sets up a robust architecture for handling high-traffic applications by combining an Application Load Balancer with an Auto Scaling Group. The ALB ensures efficient traffic distribution, while the ASG automatically adjusts the number of EC2 instances based on demand. This setup enhances reliability, scalability, and performance.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Deploying a Highly Available Web App on AWS Using Terraform</title>
      <dc:creator>Samuel Udeh</dc:creator>
      <pubDate>Thu, 19 Dec 2024 09:56:41 +0000</pubDate>
      <link>https://dev.to/samuel_udeh/deploying-a-highly-available-web-app-on-aws-using-terraform-23e5</link>
      <guid>https://dev.to/samuel_udeh/deploying-a-highly-available-web-app-on-aws-using-terraform-23e5</guid>
      <description>&lt;p&gt;Deploying a highly available web application on AWS using Terraform involves several key components to ensure redundancy, scalability, and fault tolerance. This will guide you through deploying a clustered web server on AWS with Terraform using the Auto Scaling Group(ASG) and the Application Load Balancer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learning Outcome&lt;/strong&gt; &lt;br&gt;
Master deploying highly available infrastructure using Terraform by understanding the following;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set up an Auto Scaling Group (ASG) for managing server instances.&lt;/li&gt;
&lt;li&gt;Configure an Application Load Balancer to distribute traffic.&lt;/li&gt;
&lt;li&gt;Use a Launch Template for consistent instance provisioning.&lt;/li&gt;
&lt;li&gt;Test the deployment. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Overview of Components&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;VPC&lt;/strong&gt;: Create a Virtual Private Cloud to host your resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subnets&lt;/strong&gt;: Use multiple availability zones with public and private subnets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Load Balancer&lt;/strong&gt;: Use an Application Load Balancer (ALB) to distribute traffic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EC2 Instances&lt;/strong&gt;: Launch instances in multiple availability zones.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto Scaling Group&lt;/strong&gt;: Automatically scale your instances based on demand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security Groups&lt;/strong&gt;: Control inbound and outbound traffic.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Terraform Script Overview&lt;/strong&gt;&lt;br&gt;
Below is the terraform configuration file to set up the infrastructure:&lt;br&gt;
&lt;strong&gt;main.tf&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;provider "aws" {&lt;br&gt;
  region = "us-east-1"&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;data "aws_availability_zones" "available" {}&lt;/p&gt;

&lt;p&gt;resource "aws_vpc" "main" {&lt;br&gt;
  cidr_block = "10.0.0.0/16"&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_internet_gateway" "igw" {&lt;br&gt;
  vpc_id = aws_vpc.main.id&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_route_table" "public" {&lt;br&gt;
  vpc_id = aws_vpc.main.id&lt;/p&gt;

&lt;p&gt;route {&lt;br&gt;
    cidr_block = "0.0.0.0/0"&lt;br&gt;
    gateway_id = aws_internet_gateway.igw.id&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_subnet" "public" {&lt;br&gt;
  count                 = 2&lt;br&gt;
  vpc_id                = aws_vpc.main.id&lt;br&gt;
  cidr_block            = "10.0.${count.index + 1}.0/24"&lt;br&gt;
  availability_zone     = element(data.aws_availability_zones.available.names, count.index)&lt;br&gt;
  map_public_ip_on_launch = true&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_route_table_association" "public" {&lt;br&gt;
  count          = 2&lt;br&gt;
  subnet_id      = aws_subnet.public[count.index].id&lt;br&gt;
  route_table_id = aws_route_table.public.id&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_subnet" "private" {&lt;br&gt;
  count                 = 2&lt;br&gt;
  vpc_id                = aws_vpc.main.id&lt;br&gt;
  cidr_block            = "10.0.${count.index + 3}.0/24"&lt;br&gt;
  availability_zone     = element(data.aws_availability_zones.available.names, count.index)&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_security_group" "web_sg" {&lt;br&gt;
  vpc_id = aws_vpc.main.id&lt;/p&gt;

&lt;p&gt;ingress {&lt;br&gt;
    from_port   = 80&lt;br&gt;
    to_port     = 80&lt;br&gt;
    protocol    = "tcp"&lt;br&gt;
    cidr_blocks = ["0.0.0.0/0"]  # Consider restricting this in production&lt;br&gt;
  }&lt;/p&gt;

&lt;p&gt;ingress {&lt;br&gt;
    from_port   = 22&lt;br&gt;
    to_port     = 22&lt;br&gt;
    protocol    = "tcp"&lt;br&gt;
    cidr_blocks = ["0.0.0.0/0"]  # Consider restricting this in production&lt;br&gt;
  }&lt;/p&gt;

&lt;p&gt;egress {&lt;br&gt;
    from_port   = 0&lt;br&gt;
    to_port     = 0&lt;br&gt;
    protocol    = "-1"&lt;br&gt;
    cidr_blocks = ["0.0.0.0/0"]&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_lb" "app_lb" {&lt;br&gt;
  name               = "app-lb"  # Ensure this is unique&lt;br&gt;
  internal           = false&lt;br&gt;
  load_balancer_type = "application"&lt;br&gt;
  security_groups    = [aws_security_group.web_sg.id]&lt;br&gt;
  subnets            = aws_subnet.public[*].id&lt;/p&gt;

&lt;p&gt;# depends_on = [aws_security_group.web_sg]&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_launch_template" "app" {&lt;br&gt;
  name_prefix   = "app-launch-template-"&lt;br&gt;
  image_id      = "ami-0b0ea68c435eb488d"&lt;br&gt;&lt;br&gt;
  instance_type = "t2.micro"&lt;/p&gt;

&lt;p&gt;lifecycle {&lt;br&gt;
    create_before_destroy = true&lt;br&gt;
  }&lt;/p&gt;

&lt;p&gt;network_interfaces {&lt;br&gt;
    associate_public_ip_address = true&lt;br&gt;
    security_groups = [aws_security_group.web_sg.id]&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_autoscaling_group" "app_asg" {&lt;br&gt;
  desired_capacity     = 2&lt;br&gt;
  max_size             = 5&lt;br&gt;
  min_size             = 2&lt;br&gt;
  vpc_zone_identifier = aws_subnet.private[*].id&lt;br&gt;
  launch_template {&lt;br&gt;
    id      = aws_launch_template.app.id&lt;br&gt;
    version = "$Latest"&lt;br&gt;
  }&lt;/p&gt;

&lt;p&gt;tag {&lt;br&gt;
    key                 = "Name"&lt;br&gt;
    value               = "app-instance"&lt;br&gt;
    propagate_at_launch = true&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_lb_target_group" "app_tg" {&lt;br&gt;
  name     = "app-tg"&lt;br&gt;
  port     = 80&lt;br&gt;
  protocol = "HTTP"&lt;br&gt;
  vpc_id   = aws_vpc.main.id&lt;/p&gt;

&lt;p&gt;health_check {&lt;br&gt;
    path                = "/"&lt;br&gt;
    interval            = 30&lt;br&gt;
    timeout             = 5&lt;br&gt;
    healthy_threshold  = 2&lt;br&gt;
    unhealthy_threshold = 2&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_lb_listener" "front_end" {&lt;br&gt;
  load_balancer_arn = aws_lb.app_lb.arn&lt;br&gt;
  port              = 80&lt;br&gt;
  protocol          = "HTTP"&lt;/p&gt;

&lt;p&gt;default_action {&lt;br&gt;
    type             = "forward"&lt;br&gt;
    target_group_arn = aws_lb_target_group.app_tg.arn&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;output "load_balancer_dns" {&lt;br&gt;
  value = aws_lb.app_lb.dns_name&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deploying the Infrastructure&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Initialize Terraform:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fdypa4t6zuegdm213nnpy.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fdypa4t6zuegdm213nnpy.JPG" alt="Image description" width="800" height="69"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Review the Plan:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fu2y7kb7zvia7gginhovm.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fu2y7kb7zvia7gginhovm.JPG" alt="Image description" width="800" height="64"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Apply the Configuration:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fsyvoxtz2pfk7hqrg9g5v.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fsyvoxtz2pfk7hqrg9g5v.JPG" alt="Image description" width="800" height="67"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Confirm the action by typing your key_value and &lt;strong&gt;yes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verifying the Deployment&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Load Balancer:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fjvch9rgcpdnctt0xi5ks.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fjvch9rgcpdnctt0xi5ks.JPG" alt="Image description" width="800" height="369"&gt;&lt;/a&gt;&lt;br&gt;
To see the &lt;strong&gt;DNS NAME&lt;/strong&gt; of the ALB, you can access the AWS console or check the output from the code:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Feiyflkrjgg8gmm4lysb2.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Feiyflkrjgg8gmm4lysb2.JPG" alt="Image description" width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Auto Scaling&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fkg4lrdkee3sykwewhi2w.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fkg4lrdkee3sykwewhi2w.JPG" alt="Image description" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
By leveraging Terraform, you’ve created a scalable and robust web server deployment. The Auto Scaling Group ensures high availability, while the Load Balancer distributes traffic efficiently. This setup serves as a strong foundation for more advanced infrastructure automation.&lt;/p&gt;

&lt;p&gt;Have you tried deploying an Auto Scaling web server? Share your thoughts and experiences in the comments!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Deploying Your First Server with Terraform: A Beginner's Guide"</title>
      <dc:creator>Samuel Udeh</dc:creator>
      <pubDate>Fri, 13 Dec 2024 08:29:10 +0000</pubDate>
      <link>https://dev.to/samuel_udeh/deploying-your-first-server-with-terraform-a-beginners-guide-37o7</link>
      <guid>https://dev.to/samuel_udeh/deploying-your-first-server-with-terraform-a-beginners-guide-37o7</guid>
      <description>&lt;p&gt;Welcome to Day 3 of my Terraform learning journey! Today, I will walk through deploying your first server on AWS using Terraform. This guide is designed for beginners, so don’t worry if you’re new to infrastructure as code I've got you covered.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fzlo1cx03p1hbgaav9q3m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fzlo1cx03p1hbgaav9q3m.png" alt="Image description" width="671" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Terraform?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Terraform simplifies infrastructure management by using code to provision and manage resources. Instead of manually creating servers in the AWS console, Terraform automates this process, ensuring consistency and repeatability&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What We’ll Achieve&lt;/strong&gt;&lt;br&gt;
By the end of this guide, you’ll have:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Deployed an AWS EC2 instance running a simple web server.&lt;/li&gt;
&lt;li&gt;Configured the instance with an HTTP server (Apache) using a startup script.&lt;/li&gt;
&lt;li&gt;Accessed your web server via a public IP.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ol&gt;
&lt;li&gt;AWS Account: Ensure you have an AWS account.&lt;/li&gt;
&lt;li&gt;Terraform Installed: Make sure you have Terraform installed on your local machine.&lt;/li&gt;
&lt;li&gt;AWS CLI Installed: Optional, but recommended for managing AWS resources.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; &lt;strong&gt;Configure AWS Credentials&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Set Up AWS CLI :&lt;/strong&gt;&lt;br&gt;
Open your terminal and run the following command to configure your AWS credentials:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F4j5807apdoqwvg2lw7ep.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F4j5807apdoqwvg2lw7ep.JPG" alt="Image description" width="800" height="99"&gt;&lt;/a&gt;&lt;br&gt;
Enter your AWS Access Key ID, Secret Access Key, region, and output format.&lt;/p&gt;

&lt;p&gt;Note: When you are working with AWS using Terraform, you need the Access keys and Secret Access key unlike when you are working on the AWS Console where you require passwords. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To get the Access Keys,&lt;/strong&gt; &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;login into your AWS Console as IAM user&lt;/li&gt;
&lt;li&gt;Go to your name and select security credentials&lt;/li&gt;
&lt;li&gt;Go to access keys and click on create Access key&lt;/li&gt;
&lt;li&gt;Select the use case as Command Line Interface&lt;/li&gt;
&lt;li&gt;Enter the description tag, then go on to create the access key.
P.S: Ensure you don't share the access keys with anyone&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fh9yu1nkdam31j8gudlwq.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fh9yu1nkdam31j8gudlwq.JPG" alt="Image description" width="800" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; &lt;strong&gt;Set Up Your Project&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create Project Directory&lt;/li&gt;
&lt;li&gt;Create a new directory for your Terraform project:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;mkdir terraform_project&lt;br&gt;
cd terraform_project &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; &lt;strong&gt;Create Configuration Files&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;main.tf: This file will contain the main configuration for your infrastructure.&lt;/li&gt;
&lt;li&gt;variables.tf: This file is for defining variables.&lt;/li&gt;
&lt;li&gt;outputs.tf: This file will contain outputs to display after deployment.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;File Structure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;terraform_project/&lt;br&gt;
├── main.tf&lt;br&gt;
├── variables.tf&lt;br&gt;
└── outputs.tf&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Write Your Terraform Configuration&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;main.tf&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;provider "aws" {&lt;br&gt;
  region = "us-east-1"&lt;br&gt;
}&lt;/p&gt;

&lt;h1&gt;
  
  
  Create a VPC
&lt;/h1&gt;

&lt;p&gt;resource "aws_vpc" "main" {&lt;br&gt;
  cidr_block = "10.0.0.0/16"&lt;br&gt;
}&lt;/p&gt;

&lt;h1&gt;
  
  
  Create a Public Subnet
&lt;/h1&gt;

&lt;p&gt;resource "aws_subnet" "public" {&lt;br&gt;
  vpc_id            = aws_vpc.main.id&lt;br&gt;
  cidr_block        = "10.0.1.0/24"&lt;br&gt;
  map_public_ip_on_launch = true&lt;br&gt;
}&lt;/p&gt;

&lt;h1&gt;
  
  
  Create an Internet Gateway
&lt;/h1&gt;

&lt;p&gt;resource "aws_internet_gateway" "igw" {&lt;br&gt;
  vpc_id = aws_vpc.main.id&lt;br&gt;
}&lt;/p&gt;

&lt;h1&gt;
  
  
  Create a Route Table for Public Subnet
&lt;/h1&gt;

&lt;p&gt;resource "aws_route_table" "public" {&lt;br&gt;
  vpc_id = aws_vpc.main.id&lt;/p&gt;

&lt;p&gt;route {&lt;br&gt;
    cidr_block = "0.0.0.0/0"&lt;br&gt;
    gateway_id = aws_internet_gateway.igw.id&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;h1&gt;
  
  
  Associate the Route Table with the Public Subnet
&lt;/h1&gt;

&lt;p&gt;resource "aws_route_table_association" "public_association" {&lt;br&gt;
  subnet_id      = aws_subnet.public.id&lt;br&gt;
  route_table_id = aws_route_table.public.id&lt;br&gt;
}&lt;/p&gt;

&lt;h1&gt;
  
  
  Create a Security Group
&lt;/h1&gt;

&lt;p&gt;resource "aws_security_group" "allow_ssh" {&lt;br&gt;
  vpc_id = aws_vpc.main.id&lt;/p&gt;

&lt;p&gt;ingress {&lt;br&gt;
    from_port   = 22&lt;br&gt;
    to_port     = 22&lt;br&gt;
    protocol    = "tcp"&lt;br&gt;
    cidr_blocks = ["0.0.0.0/0"]&lt;br&gt;
  }&lt;/p&gt;

&lt;p&gt;egress {&lt;br&gt;
    from_port   = 0&lt;br&gt;
    to_port     = 0&lt;br&gt;
    protocol    = "-1"&lt;br&gt;
    cidr_blocks = ["0.0.0.0/0"]&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;h1&gt;
  
  
  Create an EC2 Instance
&lt;/h1&gt;

&lt;p&gt;resource "aws_instance" "web" {&lt;br&gt;
  ami           = "ami-0c55b159cbfafe1f0"  # Example AMI ID for Amazon Linux 2&lt;br&gt;
  instance_type = "t2.micro"&lt;br&gt;
  subnet_id     = aws_subnet.public.id&lt;br&gt;
  security_groups = [aws_security_group.allow_ssh.name]&lt;/p&gt;

&lt;p&gt;user_data = &amp;lt;&amp;lt;-EOF&lt;br&gt;
              #!/bin/bash&lt;br&gt;
              echo "Hello, World!" &amp;gt; /var/www/html/index.html&lt;br&gt;
              apt-get update&lt;br&gt;
              apt-get install -y apache2&lt;br&gt;
              systemctl start apache2&lt;br&gt;
              systemctl enable apache2&lt;br&gt;
              EOF&lt;/p&gt;

&lt;p&gt;tags = {&lt;br&gt;
    Name = "WebServer"&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fjvgd107c2crurmz0fm7p.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fjvgd107c2crurmz0fm7p.JPG" alt="Image description" width="800" height="590"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4:&lt;/strong&gt; &lt;strong&gt;Deploy The Server&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Initialize Terraform&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fjy4s85iy1i7zp0icjryy.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fjy4s85iy1i7zp0icjryy.JPG" alt="Image description" width="800" height="69"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Plan the deployment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fbr6fs4fgde1tqbssjl8l.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fbr6fs4fgde1tqbssjl8l.JPG" alt="Image description" width="800" height="64"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Apply The Configuration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fcqnokar77dw0d1c8yaa7.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fcqnokar77dw0d1c8yaa7.JPG" alt="Image description" width="800" height="67"&gt;&lt;/a&gt;&lt;br&gt;
Type &lt;strong&gt;yes&lt;/strong&gt; when prompted.&lt;/p&gt;

&lt;p&gt;When successfully created ;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F8940o8whilspd53v7ugu.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F8940o8whilspd53v7ugu.JPG" alt="Image description" width="800" height="197"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F9ve6gt2jh8cmjfxeuue6.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F9ve6gt2jh8cmjfxeuue6.JPG" alt="Image description" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5:&lt;/strong&gt; &lt;strong&gt;Test the Deployment&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Copy the public IP of your EC2 instance.&lt;/li&gt;
&lt;li&gt;Open a browser and visit:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fvlbfuxl3bhxivfsa2191.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fvlbfuxl3bhxivfsa2191.JPG" alt="Image description" width="776" height="79"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should see &lt;strong&gt;"Hello, World"&lt;/strong&gt; displayed on the page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F314xij4a3jrq9gu5rxrr.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F314xij4a3jrq9gu5rxrr.JPG" alt="Image description" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Congratulations !&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You've successfully used Terraform to create EC2 instance, and also access the Apache Server through the IP Address.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Step-by-Step Guide to Setting Up Terraform, AWS CLI, and VS Code</title>
      <dc:creator>Samuel Udeh</dc:creator>
      <pubDate>Mon, 09 Dec 2024 15:10:24 +0000</pubDate>
      <link>https://dev.to/samuel_udeh/step-by-step-guide-to-setting-up-terraform-aws-cli-and-vs-code-b2o</link>
      <guid>https://dev.to/samuel_udeh/step-by-step-guide-to-setting-up-terraform-aws-cli-and-vs-code-b2o</guid>
      <description>&lt;p&gt;A Step-by-Step Guide to Setting Up Terraform, AWS CLI, and VS Code. Whether you’re a beginner or looking to refresh your setup, this guide will walk you through installing Terraform, configuring the AWS CLI, and setting up VS Code for smooth Infrastructure as Code (IaC) workflows.&lt;/p&gt;

&lt;p&gt;Installing Terraform:&lt;/p&gt;

&lt;p&gt;On Windows:&lt;/p&gt;

&lt;p&gt;Download the Terraform binary from Terraform’s official website.&lt;br&gt;
Extract the binary to a directory (e.g., C:\Terraform).&lt;br&gt;
Add the directory to your system’s PATH:&lt;br&gt;
Open System Properties &amp;gt; Environment Variables.&lt;br&gt;
Edit the PATH variable and add C:\Terraform.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fak04do81phfeh0gj1cxu.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fak04do81phfeh0gj1cxu.PNG" alt="Image description" width="800" height="129"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On macOS/Linux:&lt;br&gt;
Install using a package manager&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fo88lrl3keuuceh6zcs4b.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fo88lrl3keuuceh6zcs4b.PNG" alt="Image description" width="658" height="107"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Verify installation:&lt;/p&gt;

&lt;p&gt;terraform version&lt;/p&gt;

&lt;p&gt;Set Up the AWS CLI&lt;br&gt;
The AWS CLI allows Terraform to communicate with AWS for provisioning resources.&lt;/p&gt;

&lt;p&gt;Installation:&lt;br&gt;
1.Download the AWS CLI from AWS CLI Installation Guide.&lt;br&gt;
2.Follow the installation steps for your OS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fhuaojfqx7wq87fblsjcu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fhuaojfqx7wq87fblsjcu.png" alt="Image description" width="800" height="557"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Verify AWS CLI&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Filzsv7rkh6m9373l5rb4.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Filzsv7rkh6m9373l5rb4.PNG" alt="Image description" width="800" height="83"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Configuration&lt;br&gt;
Run the following command to configure the CLI:&lt;/p&gt;

&lt;p&gt;aws configure&lt;/p&gt;

&lt;p&gt;Provide your Access Key ID, Secret Access Key, Region, and output format (e.g., json).&lt;/p&gt;

&lt;p&gt;Test the configuration:&lt;br&gt;
use the command "aws s3 ls"&lt;br&gt;
If this works, your AWS CLI is ready to go!&lt;/p&gt;

&lt;p&gt;Install and Configure VS Code&lt;/p&gt;

&lt;p&gt;VS Code is a lightweight and powerful editor perfect for Terraform projects.&lt;/p&gt;

&lt;p&gt;Installation&lt;br&gt;
Download VS Code from VS Code's website.&lt;/p&gt;

&lt;p&gt;Install Terraform extensions:&lt;/p&gt;

&lt;p&gt;Open VS Code.&lt;br&gt;
Go to Extensions (Ctrl+Shift+X or Cmd+Shift+X).&lt;br&gt;
Search for and install "HashiCorp Terraform".&lt;br&gt;
Optional Extensions for Productivity&lt;br&gt;
AWS Toolkit: For managing AWS services directly from VS Code.&lt;br&gt;
Prettier: For consistent formatting of your Terraform code.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>What is Infrastructure as Code (IaC) and Why It's Transforming DevOps</title>
      <dc:creator>Samuel Udeh</dc:creator>
      <pubDate>Sun, 08 Dec 2024 14:32:50 +0000</pubDate>
      <link>https://dev.to/samuel_udeh/what-is-infrastructure-as-code-iac-and-why-its-transforming-devops-2k47</link>
      <guid>https://dev.to/samuel_udeh/what-is-infrastructure-as-code-iac-and-why-its-transforming-devops-2k47</guid>
      <description>&lt;p&gt;Infrastructure as Code (IaC) is a modern approach to managing and provisioning computing infrastructure through code and automation tools rather than manual processes. This practice enables developers and operations teams to define infrastructure in a descriptive manner, making it easy to deploy and manage.&lt;/p&gt;

&lt;p&gt;The idea behind infrastructure as code (IaC) is that you write and execute code to define, deploy, update, and destroy your infrastructure.&lt;/p&gt;

&lt;p&gt;WHY IT IS TRANSFORMING DevOpS&lt;/p&gt;

&lt;p&gt;. According to the 2016 State of DevOps Report, organizations that use DevOps practices, such as IaC, deploy 200 times more frequently, recover from failures 24 times faster, and have lead times that are 2,555 times lower.&lt;br&gt;
When your infrastructure is defined as code, you are able to use a wide variety of software engineering practices to dramatically improve your software delivery process, including the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Self-service&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Most teams that deploy code manually have a small number of sysadmins (often,&lt;br&gt;
just one) who are the only ones who know all the magic incantations to make the&lt;br&gt;
deployment work and are the only ones with access to production. This becomes&lt;br&gt;
a major bottleneck as the company grows. If your infrastructure is defined in&lt;br&gt;
code, the entire deployment process can be automated, and developers can kick&lt;br&gt;
off their own deployments whenever necessary.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Speed and safety&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the deployment process is automated, it will be significantly faster, since a computer can carry out the deployment steps far faster than a person, and safer, given that an automated process will be more consistent, more repeatable, and not prone to manual error.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Documentation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the state of your infrastructure is locked away in a single sysadmin’s head, and that sysadmin goes on vacation or leaves the company or gets hit by a bus, you may suddenly realize you can no longer manage your own infrastructure. On the other hand, if your infrastructure is defined as code, then the state of your infrastructure is in source files that anyone can read. In other words, IaC acts as documentation, allowing everyone in the organization to understand how things work, even if the sysadmin goes on vacation.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Version control&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can store your IaC source files in version control, which means that the entire history of your infrastructure is now captured in the commit log. This becomes a powerful tool for debugging issues, because any time a problem pops up, your first step will be to check the commit log and find out what changed in your infrastructure, and your second step might be to resolve the problem by simply reverting back to a previous, known-good version of your IaC code.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Validation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the state of your infrastructure is defined in code, for every single change, you can perform a code review, run a suite of automated tests, and pass the code through static analysis tools—all practices that are known to significantly reduce the chance of defects.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reuse&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can package your infrastructure into reusable modules so that instead of doing every deployment for every product in every environment from scratch, you can build on top of known, documented, battle-tested pieces.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Happiness&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There is one other very important, and often overlooked, reason for why you should use IaC: happiness. Deploying code and managing infrastructure manually is repetitive and tedious. Developers and sysadmins resent this type of work, since it involves no creativity, no challenge, and no recognition. You could deploy code perfectly for months, and no one will take notice—until that one day when you mess it up. That creates a stressful and unpleasant environment.&lt;br&gt;
IaC offers a better alternative that allows computers to do what they do best(automation) and developers to do what they do best (coding).&lt;/p&gt;

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