<?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: Nandan K</title>
    <description>The latest articles on DEV Community by Nandan K (@nandan_007).</description>
    <link>https://dev.to/nandan_007</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%2F3628678%2F9731326f-3c3d-4717-9049-824889daabe8.jpg</url>
      <title>DEV Community: Nandan K</title>
      <link>https://dev.to/nandan_007</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nandan_007"/>
    <language>en</language>
    <item>
      <title>DevOps Project: Hosting Serverless Web Application in AWS using S3,Lambda, CloudFront, DynamoDB, Route53, SSL certificate</title>
      <dc:creator>Nandan K</dc:creator>
      <pubDate>Fri, 06 Mar 2026 06:07:21 +0000</pubDate>
      <link>https://dev.to/nandan_007/devops-project-hosting-serverless-web-application-in-aws-using-s3lambda-cloudfront-dynamodb-2362</link>
      <guid>https://dev.to/nandan_007/devops-project-hosting-serverless-web-application-in-aws-using-s3lambda-cloudfront-dynamodb-2362</guid>
      <description>&lt;p&gt;🎯 DevOps is not just about learning tools; it’s about applying them to solve real-world problems. One of the best ways to build practical DevOps skills is by creating hands-on projects that demonstrate how different cloud services work together. &lt;/p&gt;

&lt;p&gt;In this project, I built a serverless web application using core AWS services such as AWS Lambda, Amazon DynamoDB, CloudFront Distribution, Amazon S3, Route53, SSL certification and also integrating these different AWS services. &lt;/p&gt;

&lt;p&gt;📌 AWS Services used to implement the project:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The application follows a serverless architecture, which means there are no servers to manage, and AWS automatically handles scaling and infrastructure management. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Amazon S3 will host the static website&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AWS Lambda will run the backend logic that processes user requests. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DynamoDB as database&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Route53 for DNS name resolution&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;created CloudFront distribution to speed up the data delivery&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Created SSL certificate using Amazon certificate manager and attach it to CloudFront (for HTTPS secure connection) &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Github Repo for source code: &lt;a href="https://github.com/Nandan3/Projects_on_AWS_Lambda" rel="noopener noreferrer"&gt;https://github.com/Nandan3/Projects_on_AWS_Lambda&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 About AWS Lambda:&lt;/p&gt;

&lt;p&gt;✅ What AWS Lambda does:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A serverless compute service that lets you run code without provisioning or managing servers.&lt;/li&gt;
&lt;li&gt;Runs code without servers - You don’t manage EC2 instances.&lt;/li&gt;
&lt;li&gt;Automatically scales depending on the amount of user traffic.&lt;/li&gt;
&lt;li&gt;Integrates with other AWS services - S3, DynamoDB, CloudWatch, SNS, SQS, API Gateway, etc.&lt;/li&gt;
&lt;li&gt;Supports popular programming languages like Python, Java, C#, Node.js, Go, Ruby, Power shell.&lt;/li&gt;
&lt;li&gt;It has runtime API extension that allows you to use other programming language not listed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;✅ How It Works (Flow):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Lambda starts with an events, which triggers lambda to do something or execute the code.&lt;/li&gt;
&lt;li&gt;Source of the event is another AWS services like S3, API Gateway. It can be trigger from stream of data or queue, like Kinesis Data Streams or Simple Queue Service.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 About Dynamo DB:&lt;br&gt;
✅ Intro:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Managing and scaling NoSQL DB for web application and services.&lt;/li&gt;
&lt;li&gt;Replicates data across multiple AWS Regions automatically.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;✅ Features:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;NoSQL data: Key-value and document-style storage.&lt;/li&gt;
&lt;li&gt;Provides us fully managed serverless and highly available DB&lt;/li&gt;
&lt;li&gt;Handle high traffic applications&lt;/li&gt;
&lt;li&gt;Works with Lambda, API Gateway, Step Functions, etc.&lt;/li&gt;
&lt;li&gt;Secure - Encryption, IAM-based access control, and VPC integration.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;✅ Dynamo DB - Components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Tables: place to store data or collection of data&lt;/li&gt;
&lt;li&gt;Items: each table contains zero or more items. Entry into the table.&lt;/li&gt;
&lt;li&gt;Attributes: items composed of one or more attributes. Like properties within table.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;✅ Use cases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Building internet scale applications, which supports user content, metadata and caches that require high concurrency and connections for millions of users and millions requests per seconds.&lt;/li&gt;
&lt;li&gt;Also great for workloads that are used within real time video streaming and interactive content because it delivers low latency with multi-region replication.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Project Architecture:&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%2F1yx2ei8rd14rfyxi8dx9.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%2F1yx2ei8rd14rfyxi8dx9.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🎯 Detailed guide for implementing the project:&lt;/p&gt;

&lt;p&gt;📌 Steps to Configure S3:&lt;/p&gt;

&lt;p&gt;✅ Step 1:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to S3 in AWS Console&lt;/li&gt;
&lt;li&gt;Create S3 bucket with proper configuration set up.
Name: Serverless-web-application
Type: Private S3 bucket
Server-side encryption with Amazon S3 managed keys (SSE-S3)&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%2Fjyj8m3euq9c9wvfd55mh.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%2Fjyj8m3euq9c9wvfd55mh.png" alt=" " width="764" height="93"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Step 2:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Upload HTML, Java script, CSS files into S3 bucket&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%2Fmz7sslwsrq6wb1egxzt2.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%2Fmz7sslwsrq6wb1egxzt2.png" alt=" " width="762" height="130"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Steps to configure CloudFront Distribution:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;CloudFront is secure content delivery service in AWS and reduce the latency, ensures high data transfer speed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;✅ Step 1: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to CloudFront &amp;gt;&amp;gt; create Distributions
Origin type: Amazon S3
    S3 Origin: serverless-web-application-using-lambda.s3.ap-south-1.amazonaws.com (select from dropdown)&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%2Fyyafo3w8j10wwi8q7uy9.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%2Fyyafo3w8j10wwi8q7uy9.png" alt=" " width="776" height="86"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Step 2:&lt;br&gt;
Copy S3 bucket policy, which you need to attach to bucket. So that CloudFront can access the S3.&lt;br&gt;
Go to CloudFront &amp;gt;&amp;gt; click on the distribution, which you created now &amp;gt;&amp;gt; select "Origin" &amp;gt;&amp;gt; select "origin name (severless-web-application)" &amp;gt;&amp;gt; Edit.&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%2Fcy3g1xvk62t6zcklx2du.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%2Fcy3g1xvk62t6zcklx2du.png" alt=" " width="476" height="233"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Step 3:&lt;br&gt;
Copy the CloudFront Policy&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%2Fcv1mpzysj28y34ht4w7p.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%2Fcv1mpzysj28y34ht4w7p.png" alt=" " width="800" height="105"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Step 4: &lt;br&gt;
Go to S3 bucket &amp;gt;&amp;gt; Permissions &amp;gt;&amp;gt; bucket policy &amp;gt;&amp;gt; paste the policy, which you copied&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%2Fu7dg49yfzbwqbixqvk0a.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%2Fu7dg49yfzbwqbixqvk0a.png" alt=" " width="616" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This allows the CloudFront Service principle to access S3 bucket&lt;/p&gt;

&lt;p&gt;✅ Step 5:&lt;br&gt;
Make sure that the default root object is "index.html" in cloud front. Because in S3 - "index.html" is the entry point to our application.&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%2Fi31r2gf84jpccyx6rwki.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%2Fi31r2gf84jpccyx6rwki.png" alt=" " width="800" height="146"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Enable Route53 for CloudFront Distribution&lt;br&gt;
✅ Step 1: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Purchase your own DNS name from GoDaddy or Route53 itself.&lt;/li&gt;
&lt;li&gt;Then create Hosted zone by using DNS name in Route53 (if the DNS name is purchased from external).&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%2Fcuv1b1h9gqlff1dia8s8.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%2Fcuv1b1h9gqlff1dia8s8.png" alt=" " width="742" height="72"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Step 2: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Inside CloudFront distribution &amp;gt;&amp;gt; origin &amp;gt;&amp;gt; add DNS name and select custom SSL certificate (if don't have request the certificate in Amazon ACM).&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%2Ftfj8jrernvrnqgrbtlai.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%2Ftfj8jrernvrnqgrbtlai.png" alt=" " width="800" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add DNS record and SSL certificate into CloudFront&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%2F8814a270ccfcnfd50ulo.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%2F8814a270ccfcnfd50ulo.png" alt=" " width="792" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;To request SSL certificate &amp;gt;&amp;gt; go to Amazon ACM &amp;gt;&amp;gt; request a certificate with "*.nandanwithtech.in" domain name.&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%2F77cbfwyhh3n9o9oeqmv2.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%2F77cbfwyhh3n9o9oeqmv2.png" alt=" " width="800" height="245"&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%2F94gctyyodhy4vkxmgaj4.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%2F94gctyyodhy4vkxmgaj4.png" alt=" " width="607" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Validate the certificate with Route53 for that: click on the certificate &amp;gt;&amp;gt; under "Domain" section &amp;gt;&amp;gt; create records in Route53 &amp;gt;&amp;gt; proceed.&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%2F8c6bgeqv51in6j9rd7wu.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%2F8c6bgeqv51in6j9rd7wu.png" alt=" " width="799" height="220"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A CNAME record will be created under Route53&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%2Fngeu4mg3r2krlyaf4h04.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%2Fngeu4mg3r2krlyaf4h04.png" alt=" " width="800" height="68"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Step 3: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create Route53 record for "serverless" subdomain in serverless.nandanwithtech.in&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%2F7hfvyuocqaeqpy3f1taq.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%2F7hfvyuocqaeqpy3f1taq.png" alt=" " width="800" height="322"&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%2Fisgexn6lme0uo7bt349b.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%2Fisgexn6lme0uo7bt349b.png" alt=" " width="570" height="91"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now try to access the application with registered DNS name with "secure https": &lt;a href="https://serverless.nandanwithtech.in/" rel="noopener noreferrer"&gt;https://serverless.nandanwithtech.in/&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%2F0emylb1y95whpclzimpd.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%2F0emylb1y95whpclzimpd.png" alt=" " width="351" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Steps to Create DynamoDB tables and map it with Lambda functions&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a Dynamo DB table and make sure to create an IAM role for the Lambda function to give permission to access DynamoDB table.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;✅ Step 1:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;As we see in the web application, whenever any person enter his/her name and submit the details and refresh the page, view count should be increased.&lt;/li&gt;
&lt;li&gt;For this, I'm creating Dynamo DB table in AWS and adding the Id, view items into the table.&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%2Fe5y26vdnkst8qjeua2o7.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%2Fe5y26vdnkst8qjeua2o7.png" alt=" " width="570" height="98"&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%2Fj0gagsmcej8bqg1ocscv.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%2Fj0gagsmcej8bqg1ocscv.png" alt=" " width="374" height="106"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Step 2:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create an IAM role and give permissions to Lambda functions to access dynamoDB.
Go to IAM &amp;gt;&amp;gt; Role &amp;gt;&amp;gt; create role&lt;/li&gt;
&lt;li&gt;Here I ensured the "least priviliged access" control mechanism, by giving only required permissions through policy and attached it to role.&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%2Fgce1wz4w14ypvquufl14.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%2Fgce1wz4w14ypvquufl14.png" alt=" " width="378" height="359"&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%2Fg69dvsx5rtv91no8apne.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%2Fg69dvsx5rtv91no8apne.png" alt=" " width="403" height="238"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Creating a Lambda function and integrating with the website&lt;/p&gt;

&lt;p&gt;✅ Step 1:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to Lambda &amp;gt;&amp;gt; create Lambda function
Name: serverless-web-app-lambda
Language: Python 3.14
Enable function URL to assign HTTPS to Lambda function&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%2Fltsmlajf7wjqn7l10j7n.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%2Fltsmlajf7wjqn7l10j7n.png" alt=" " width="511" height="211"&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%2F7l9tsa93mbf3xbifnm2t.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%2F7l9tsa93mbf3xbifnm2t.png" alt=" " width="800" height="159"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;proceed with the Lambda function&lt;/p&gt;

&lt;p&gt;Function URL: &lt;a href="https://atzqihljt3dupct4orlsbjm5yi0qwgrl.lambda-url.ap-south-1.on.aws/" rel="noopener noreferrer"&gt;https://atzqihljt3dupct4orlsbjm5yi0qwgrl.lambda-url.ap-south-1.on.aws/&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add IAM role to Lambda function to access Dynamo DB
Go to Lambda function &amp;gt;&amp;gt; configuration &amp;gt;&amp;gt; Permissions &amp;gt;&amp;gt; click on Edit &amp;gt;&amp;gt; choose execution role.&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%2Fzi1elfs85hw95b0seetc.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%2Fzi1elfs85hw95b0seetc.png" alt=" " width="775" height="130"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Update the code into Lambda function &amp;gt;&amp;gt; Test the code&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%2Fxwzh0rluwgpfgq7pmg4o.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%2Fxwzh0rluwgpfgq7pmg4o.png" alt=" " width="454" height="137"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Access the website using secure domain name - &lt;a href="https://serverless.nandanwithtech.in/" rel="noopener noreferrer"&gt;https://serverless.nandanwithtech.in/&lt;/a&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%2F2wsfrfok402sl44a9ldo.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%2F2wsfrfok402sl44a9ldo.png" alt=" " width="468" height="260"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Error during implementation:&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%2F2f739qowrslmu4he3jj9.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%2F2f739qowrslmu4he3jj9.png" alt=" " width="677" height="113"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Solution: Add PutItem permission in IAM policy&lt;/p&gt;

</description>
      <category>aws</category>
      <category>terraform</category>
      <category>kubernetes</category>
      <category>docker</category>
    </item>
    <item>
      <title>DevOps Project: Containerize and Run an e-commerce based application in AWS EKS cluster using Terraform with all best practices</title>
      <dc:creator>Nandan K</dc:creator>
      <pubDate>Tue, 24 Feb 2026 10:42:52 +0000</pubDate>
      <link>https://dev.to/nandan_007/containerize-and-run-an-e-commerce-based-application-in-aws-eks-cluster-using-terraform-with-all-1oei</link>
      <guid>https://dev.to/nandan_007/containerize-and-run-an-e-commerce-based-application-in-aws-eks-cluster-using-terraform-with-all-1oei</guid>
      <description>&lt;p&gt;🎯 This Project contains the OpenTelemetry Astronomy Shop, a microservice-based distributed system intended to illustrate the implementation of OpenTelemetry in a near real-world environment.&lt;/p&gt;

&lt;p&gt;Welcome to the OpenTelemetry Astronomy Shop Project Demonstration:&lt;/p&gt;

&lt;p&gt;📌 Here the goals are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Realistic Distributed System Example This repository demonstrates a real-world, microservice-based distributed application using the Open-Telemetry Astronomy Shop, designed to showcase end-to-end observability in modern cloud-native systems.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Multi-Microservice, Multi-Language Architecture The application consists of multiple independent microservices implemented in different programming languages, reflecting how real organizations build and maintain heterogeneous technology stacks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hands-On Observability Experience By implementing this project, you gain practical, hands-on experience with distributed tracing, context propagation, and observability tools as used in real production environments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Industry-Aligned Learning Approach This project mirrors how organizations design, instrument, and monitor microservice architectures, helping learners understand real-world implementation patterns and best practices.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 Tools used to implement the application:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Containerize the micro-service using "Docker"&lt;/li&gt;
&lt;li&gt;AWS services used - EC2 instance, IAM roles &amp;amp; policies, EKS cluster, Route53, VPC, Subnets&lt;/li&gt;
&lt;li&gt;Kubernetes for managing the containerized micro-services.&lt;/li&gt;
&lt;li&gt;AWS infrastructure creation using Terraform modules&lt;/li&gt;
&lt;li&gt;Implemented the CI using GitHub Actions and CD using ArgoCD&lt;/li&gt;
&lt;li&gt;Used Ingress and Ingress Controller to expose the application to external world.&lt;/li&gt;
&lt;li&gt;Helm chart for downloading and installing the software's and dependencies.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 What You Will Learn:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cloud Infrastructure Setup – Learn how to configure and deploy a cloud environment for DevOps implementation.&lt;/li&gt;
&lt;li&gt;Understanding the Project &amp;amp; SDLC – Gain in-depth knowledge of software development lifecycles in microservices-based architectures.&lt;/li&gt;
&lt;li&gt;Containerization with Docker – Learn how to package and manage applications efficiently using Docker.&lt;/li&gt;
&lt;li&gt;Docker Compose Setup – Manage multi-container applications with Docker Compose.&lt;/li&gt;
&lt;li&gt;Kubernetes for Orchestration – Deploy and manage containers at scale using Kubernetes.&lt;/li&gt;
&lt;li&gt;Infrastructure as Code (IaC) with Terraform – Automate and manage cloud infrastructure effortlessly.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 Refer the Application architecture: &lt;a href="https://opentelemetry.io/docs/demo/architecture/" rel="noopener noreferrer"&gt;https://opentelemetry.io/docs/demo/architecture/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Refer the Source code of the application: &lt;a href="https://github.com/open-telemetry/opentelemetry-demo" rel="noopener noreferrer"&gt;https://github.com/open-telemetry/opentelemetry-demo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Project architecture diagram and Overview of microservices is available at the below link.&lt;/p&gt;

&lt;p&gt;Architecture&lt;br&gt;
&lt;a href="https://opentelemetry.io/docs/demo/architecture/" rel="noopener noreferrer"&gt;https://opentelemetry.io/docs/demo/architecture/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Overview of microservices used in the project&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://opentelemetry.io/docs/demo/services/" rel="noopener noreferrer"&gt;https://opentelemetry.io/docs/demo/services/&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Running the Application in Local environment:&lt;/p&gt;

&lt;p&gt;✅ Create EC2 Instance:&lt;br&gt;
type: t2.large&lt;br&gt;
storage: 30GB&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%2Fj8elzwlpc0t2vu0yl3j9.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%2Fj8elzwlpc0t2vu0yl3j9.png" alt=" " width="759" height="76"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Resize File system: (if running out of space while creating the application)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Increase the instance volume to 30GB&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%2F8nyhqupp45xqwg9o1yv9.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%2F8nyhqupp45xqwg9o1yv9.png" alt=" " width="577" height="109"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Change the file system in CLI $lsblk&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%2Fdcbsf18t8yzh4qmezwsd.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%2Fdcbsf18t8yzh4qmezwsd.png" alt=" " width="518" height="175"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;$sudo apt install cloud-guest-utils&lt;br&gt;
$sudo growpart /dev/xvda 1&lt;br&gt;
$sudo resize2fs /dev/xvda1&lt;/p&gt;

&lt;p&gt;✅ If you face any issue related to "permission denied", while executing the docker commands. Add the user to docker group using:&lt;br&gt;
$sudo usermod -aG docker ubuntu&lt;/p&gt;

&lt;p&gt;✅ Running the application local environment using docker compose:&lt;/p&gt;

&lt;p&gt;Why docker compose?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I'm deploying e-commerce application, which contains multiple micro-services. So we containerize and running as one model using docker compose is efficient.&lt;/li&gt;
&lt;li&gt;It runs multiple containers at once and establish the dependencies between the containers.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;✅ You will find the docker-compose.yaml file in my GitHub repository:&lt;br&gt;
Link: &lt;a href="https://github.com/Nandan3/End-to-End-DevOps-Projects/blob/main/docker-compose.yaml" rel="noopener noreferrer"&gt;https://github.com/Nandan3/End-to-End-DevOps-Projects/blob/main/docker-compose.yaml&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Run the below command&lt;br&gt;
$docker compose up -d&lt;/p&gt;

&lt;p&gt;It will pull the images from docker registry and run the micro-services&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%2Fvihq8su52vi6s38fwv60.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%2Fvihq8su52vi6s38fwv60.png" alt=" " width="501" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Edit security groups inbound rules to access the application from web browser:&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%2Fx15jvmajce6dcpu94lej.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%2Fx15jvmajce6dcpu94lej.png" alt=" " width="800" height="137"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Access the application using: http://:8080&lt;br&gt;
Public-IP: EC2 Public IP&lt;/p&gt;

&lt;h2&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%2F91u1p12di68rv5xc1zzq.png" alt=" " width="800" height="406"&gt;
&lt;/h2&gt;

&lt;p&gt;Containerize the multiple Micro-services using Dockerfiles:&lt;/p&gt;

&lt;p&gt;📌 This is an e-commerce based application, which contains multiple micro-services. Each micro-services are developed using different programming languages. For example&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Product-catalogue service: Go lang&lt;/li&gt;
&lt;li&gt;Ad service: Java&lt;/li&gt;
&lt;li&gt;Recommendation service: Python
So I took 3 micro-services from different programming language, where I containerize the micro-services using Dockerfile and build the images.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 Product-catalog service: (Go programming language)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;$sudo apt install golang-go&lt;/li&gt;
&lt;li&gt;Files: go.mod &amp;amp; go.sum - takes care of dependencies&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Build the service in local using below steps:&lt;br&gt;
a. $export PRODUCT_CATALOG_PORT=8088&lt;br&gt;
b. $go build -o product-catalog .&lt;br&gt;
c. $./product-catalog&lt;/p&gt;

&lt;p&gt;O/P:&lt;br&gt;
INFO[0000] Loaded 10 products&lt;br&gt;
INFO[0000] Product Catalog gRPC server started on port: 8088&lt;/p&gt;

&lt;p&gt;✅ Using Dockerfile:&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%2Flte73ud7ijc5f3xugt16.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%2Flte73ud7ijc5f3xugt16.png" alt=" " width="444" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Run the below commands to build the image and to run the container:&lt;br&gt;
a. $docker build -t nandandocker07/product-catalog:v1 .&lt;/p&gt;

&lt;p&gt;-t &amp;gt;&amp;gt; tag (docker-hub-user)/repo-name:version&lt;br&gt;
. &amp;gt;&amp;gt; location of dockerfile&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%2F6ddwh8yb3pwua6m4tc9y.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%2F6ddwh8yb3pwua6m4tc9y.png" alt=" " width="800" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;b. $docker run nandandocker07/product-catalog:v1&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%2Fyumnkhkkc1w8an8v53xb.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%2Fyumnkhkkc1w8an8v53xb.png" alt=" " width="800" height="49"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Ad-service: (Java programming language)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Build using gradle or maven&lt;/li&gt;
&lt;li&gt;File: gradlew (gradle wrapper for Linux &amp;amp; Mac) or gradlew.bat (for    windows) takes care of dependencies.
File: pom.xml (take care of dependencies in case of maven)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Build the service in local using below steps:&lt;br&gt;
a. Install java:&lt;br&gt;
$sudo apt install openjdk-21-jre-headless&lt;br&gt;
b. Give permission to gradlew file&lt;br&gt;
$chmod +x gradlew&lt;br&gt;
c. Run the below command:&lt;br&gt;
$./gradlew installDist&lt;/p&gt;

&lt;p&gt;ü Start the gradle daemon, which is like a server&lt;br&gt;
ü Install the dependencies &lt;br&gt;
ü Perform code compilation &lt;br&gt;
ü Build the application and stored in perticular directory&lt;br&gt;
✅ Using Dockerfile:&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%2Fpm5jpoa8o5l9bpmdssf5.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%2Fpm5jpoa8o5l9bpmdssf5.png" alt=" " width="485" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Run the below commands to build the image and to run the container:&lt;br&gt;
a. $docker build -t nandandocker07/ad-service:v1 .&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%2F1vj005w1m6s7w1kguiau.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%2F1vj005w1m6s7w1kguiau.png" alt=" " width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;b. $docker run nandandocker07/ad-service:v1&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%2F1mgl0v2l5tidtzpvefoa.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%2F1mgl0v2l5tidtzpvefoa.png" alt=" " width="800" height="103"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Recommendation service: (Python programming language)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;File: requirments.txt take care of dependencies
✅ Using Dockerfile:&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%2Fek4i6hm2eb4rdqd5cdq3.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%2Fek4i6hm2eb4rdqd5cdq3.png" alt=" " width="416" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Run the below commands to build the image and to run the container:&lt;br&gt;
a. $docker build -t nandandocker07/recommandation-service:v1 .&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%2Fkvpp9lo239upazje8hnc.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%2Fkvpp9lo239upazje8hnc.png" alt=" " width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;b. $docker run nandandocker07/recommandation-service:v1&lt;/p&gt;

&lt;p&gt;📌 Push the docker images into docker hub: (registry or container artifactory)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Registries are: dockerhub, quay.io, ECR, ACR, GHCR&lt;/li&gt;
&lt;li&gt;First login to registry where you want to push the image
Eg:
$docker login docker.io
$docker login quay.io
$docker login ARN #AWS&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%2Fc5k8wbx84lpa2ho7fco5.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%2Fc5k8wbx84lpa2ho7fco5.png" alt=" " width="800" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Push the image using below command
$docker tag docker.io/nandandocker07/product-catalog:v1
$docker push docker.io/nandandocker07/product-catalog:v1&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;docker.io &amp;gt;&amp;gt; docker hub registry&lt;br&gt;
nandandocker07 &amp;gt;&amp;gt; registry user name&lt;br&gt;
product-catalog &amp;gt;&amp;gt; repo name&lt;br&gt;
:v1 &amp;gt;&amp;gt; tag of the image&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%2Fet2sm5mr74tfff5l65o6.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%2Fet2sm5mr74tfff5l65o6.png" alt=" " width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Preparation of docker-compose file to run the entire environment:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Main components of docker-compose.yml&lt;br&gt;
ü Service object &amp;gt;&amp;gt; define how to pull or run the micro-services&lt;br&gt;
ü Network object &amp;gt;&amp;gt; create network for all micro-services&lt;br&gt;
ü Volume object&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You will find the docker-compose.yaml file in my github repository&lt;br&gt;
Link: &lt;a href="https://github.com/Nandan3/End-to-End-DevOps-Projects/blob/main/docker-compose.yaml" rel="noopener noreferrer"&gt;https://github.com/Nandan3/End-to-End-DevOps-Projects/blob/main/docker-compose.yaml&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run the application using docker compose commands&lt;br&gt;
$docker compose up -d&lt;/p&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%2Fmc7chfeht80r13bkt8rl.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%2Fmc7chfeht80r13bkt8rl.png" alt=" " width="600" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Access the application using: http://:8080&lt;br&gt;
Public-IP: EC2 Public IP&lt;/p&gt;

&lt;h2&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%2F5sdbvhpclpxg8a5cvaug.png" alt=" " width="800" height="433"&gt;
&lt;/h2&gt;

&lt;p&gt;Deploy the Application into AWS EKS Cluster:&lt;/p&gt;

&lt;p&gt;📌 Why AWS EKS?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Upgrades becomes easy&lt;/li&gt;
&lt;li&gt;Manage control plane&lt;/li&gt;
&lt;li&gt;Scaling become easy&lt;/li&gt;
&lt;li&gt;Integrated K8s UI&lt;/li&gt;
&lt;li&gt;Cost efficient&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 Creating the following infrastructure using Terraform:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;VPC, Public subnet and Private subnet&lt;/li&gt;
&lt;li&gt;Internet gateway, NAT gateway, Route tables&lt;/li&gt;
&lt;li&gt;EKS cluster&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 Create S3 bucket and DynamoDB for state file management 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%2F5xfrbxs2nld56n0yaye4.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%2F5xfrbxs2nld56n0yaye4.png" alt=" " width="482" height="459"&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%2Fc5ixg5aokup0nmmkk6fu.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%2Fc5ixg5aokup0nmmkk6fu.png" alt=" " width="800" height="113"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Create VPC &amp;amp; EKS cluster using Terraform:&lt;br&gt;
VPC &amp;amp; Cluster creation code: &lt;a href="https://github.com/Nandan3/End-to-End-DevOps-Projects/tree/main/EKS_install" rel="noopener noreferrer"&gt;https://github.com/Nandan3/End-to-End-DevOps-Projects/tree/main/EKS_install&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Cluster information:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;cluster_endpoint = "&lt;a href="https://D9F38304FBE9AFF51F006DE59DEC4993.gr7.us-west-1.eks.amazonaws.com" rel="noopener noreferrer"&gt;https://D9F38304FBE9AFF51F006DE59DEC4993.gr7.us-west-1.eks.amazonaws.com&lt;/a&gt;"&lt;/li&gt;
&lt;li&gt;cluster_name = "my-eks-cluster"&lt;/li&gt;
&lt;li&gt;vpc_id = "vpc-09bcf1df61d87cf8b"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;✅ Run the following command to create the cluster:&lt;br&gt;
$terraform init&lt;br&gt;
$terraform plan&lt;br&gt;
$terraform apply --auto-approve&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%2F5mfvs598m4y3o0fjjtzq.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%2F5mfvs598m4y3o0fjjtzq.png" alt=" " width="800" height="140"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 How to connect to 1 or many Kubernetes clusters from command line ?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cluster info are stored in kube-config files $kubectl config view $kubectl config current-context #context represents the cluster $kubectl config use-context #switch between the clusters&lt;/li&gt;
&lt;li&gt;&lt;p&gt;$cat ~/.aws/credentials &amp;gt;&amp;gt; Path where aws credentials are stored&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;$aws eks update-kubeconfig --region us-west-1 --name my-eks-cluster&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;o/p:&lt;br&gt;
Added new context arn:aws:eks:us-west-1:454842419673:cluster/my-eks-cluster to /home/ubuntu/.kube/config&lt;br&gt;
Context &amp;gt;&amp;gt; complete K8s related information (creates kube-config file)&lt;/p&gt;

&lt;p&gt;$kubectl config view&lt;br&gt;
$kubectl config current-context&lt;br&gt;
$kubectl get nodes&lt;/p&gt;

&lt;p&gt;📌 Deploying Project on K8:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;EKS cluster creation is completed.&lt;/li&gt;
&lt;li&gt;Check in CLI
$kubectl config current-context&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%2Fx3wjci6earg8tmjdz9sc.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%2Fx3wjci6earg8tmjdz9sc.png" alt=" " width="694" height="48"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Create a service account:&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%2Fr5jg1rj0u0d55lfsgcnz.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%2Fr5jg1rj0u0d55lfsgcnz.png" alt=" " width="425" height="231"&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%2Fc35zosswgkkmxcbmgraa.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%2Fc35zosswgkkmxcbmgraa.png" alt=" " width="800" height="114"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;$kubectl apply -f complete-deploy.yaml&lt;br&gt;
$kubectl get pods&lt;/p&gt;

&lt;p&gt;📌 How one micro-services are connected another in this project?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;By using environment variables ü Service name or URL is injected via ConfigMap ü Application reads it at runtime
Eg:
If want to connect shipping service to quote service, in the environment variable of shipping pod have service name of the quote service&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In shipping service:&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%2Fgaf5lvk5d1mnsw4a4eik.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%2Fgaf5lvk5d1mnsw4a4eik.png" alt=" " width="363" height="38"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Other ways: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;By using service discovery mechanism using services &lt;/li&gt;
&lt;li&gt;DNS-Based Service Discovery (Implicit - Kubernetes automatically creates DNS entries for Services.) &lt;/li&gt;
&lt;li&gt;Headless Services (Direct Pod-to-Pod) [When to use - Stateful apps (Kafka, Cassandra), Client needs individual Pod identities]&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;✅ Access the project from outside the VPC/Cluster:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Change service type to LB mode to access via internet: $kubectl edit svc opentelemetry-demo-frontendproxy Add - type: LoadBalancer&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%2F3e61fww1ugknjat6byv1.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%2F3e61fww1ugknjat6byv1.png" alt=" " width="800" height="60"&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%2Fa7wlucf5rie9vkhgn0q5.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%2Fa7wlucf5rie9vkhgn0q5.png" alt=" " width="800" height="179"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&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%2Frq95acxg51l3m0r9oj0i.png" alt=" " width="800" height="136"&gt;
&lt;/h2&gt;

&lt;p&gt;Configure the Ingress and Ingress controller to expose the application into internet:&lt;/p&gt;

&lt;p&gt;📌 Why Ingress and Ingress Controller:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Configuration of LB is not declarative or lack of declarative approach Eg: if I want to change from http to https, I have to do it in 2. AWS UI not in svc.yaml manifest.&lt;/li&gt;
&lt;li&gt;Not cost effective Eg: if 10 microservice require external access, AWS will 10 LB&lt;/li&gt;
&lt;li&gt;CCM only tied to AWS or any cloud provider LB, what about F5, nginx, Envy, Traffik&lt;/li&gt;
&lt;li&gt;LB type will not work in mini-kube, kind, k3d&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 Ingress:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It helps you to define routing rules for incoming traffic&lt;/li&gt;
&lt;li&gt;Declarative (yaml) - LB can be updated and modified&lt;/li&gt;
&lt;li&gt;Cost effective - using path based &amp;amp; host based routing, we can route the request 100's of target groups&lt;/li&gt;
&lt;li&gt;Not dependent on CCM - by using reverse proxy or other mechanism&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 Creation of Ingress &amp;amp; Ingress Controller:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create Ingress resource for Front-end service &amp;gt;&amp;gt; creation of ALB Ingress controller (AWS), which reads the ingress resource &amp;gt;&amp;gt; accordingly ALB Ingress controller creates LB for us.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 Steps to install ALB ingress controller on EKS cluster:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;ALB ingress controller is pod within the EKS cluster &amp;gt;&amp;gt; it creates an elastic LB &amp;gt;&amp;gt; creates only if service account of the ALB binds to the IAM roles or policies &amp;gt;&amp;gt; it binds through "IAM OIDC connector or provider"&lt;/li&gt;
&lt;li&gt;Install eksctl in CLI&lt;/li&gt;
&lt;li&gt;Make sure you are in the correct cluster&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%2Fa2d3pb0g1yofwi9ebgl8.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%2Fa2d3pb0g1yofwi9ebgl8.png" alt=" " width="768" height="84"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Follow the steps to set up OIDC provider and ALB controller: &lt;a href="https://github.com/Nandan3/End-to-End-DevOps-Projects/blob/main/kubernetes_files/kubernetes-ingress-controller" rel="noopener noreferrer"&gt;https://github.com/Nandan3/End-to-End-DevOps-Projects/blob/main/kubernetes_files/kubernetes-ingress-controller&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;oidc_id: D9F38304FBE9AFF51F006DE59DEC4993&lt;/p&gt;

&lt;p&gt;Check if there is an IAM OIDC provider configured already [adding OIDC provider to my cluster]&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%2Fbzvzyjr5bwfejx3bgvzn.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%2Fbzvzyjr5bwfejx3bgvzn.png" alt=" " width="800" height="58"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Create service account &amp;amp; IAM role &amp;amp; policy and attach it to SA:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Download IAM policy.json from AWS for ELB&lt;br&gt;
Link: curl -O &lt;a href="https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.11.0/docs/install/iam_policy.json" rel="noopener noreferrer"&gt;https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.11.0/docs/install/iam_policy.json&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create an IAM policy&lt;/p&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%2Fc7srhteyirv2nmyvzbe1.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%2Fc7srhteyirv2nmyvzbe1.png" alt=" " width="800" height="175"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create IAM role and attach them to a service account created previously.&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%2Fwb9xforcyyieb3xueaua.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%2Fwb9xforcyyieb3xueaua.png" alt=" " width="800" height="231"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Use Helm chart to download ALB controller:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Add helm repo for eks&lt;br&gt;
$helm repo add eks &lt;a href="https://aws.github.io/eks-charts" rel="noopener noreferrer"&gt;https://aws.github.io/eks-charts&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install ALB controllers using helm &amp;amp; verify that the deployments are running.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;$helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=my-eks-cluster --set serviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller --set region=us-west-1 --set vpcId=vpc-09bcf1df61d87cf8b&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%2Fkoob8vn466naw8newatm.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%2Fkoob8vn466naw8newatm.png" alt=" " width="800" height="226"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Setup Ingress resources and access the Project:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Using ingress, access the project as external user&lt;/li&gt;
&lt;li&gt;Change the type of the LB in frontendproxy service yaml $kubectl edit svc opentelemetry-demo-frontendproxy&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%2Foh51lqc4njrpaxw11nmc.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%2Foh51lqc4njrpaxw11nmc.png" alt=" " width="202" height="36"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Create ingress resource using yaml manifest: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Link of yaml file: &lt;a href="https://github.com/Nandan3/End-to-End-DevOps-Projects/blob/main/kubernetes_files/ingress.yaml" rel="noopener noreferrer"&gt;https://github.com/Nandan3/End-to-End-DevOps-Projects/blob/main/kubernetes_files/ingress.yaml&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Run: $kubectl apply -f ingress.yaml&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%2Fj3uvnro9csldl4hn1kcd.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%2Fj3uvnro9csldl4hn1kcd.png" alt=" " width="800" height="91"&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%2Fnyl5yco5s64kzfixyexu.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%2Fnyl5yco5s64kzfixyexu.png" alt=" " width="800" height="112"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Accessing the application using IP address or DNS will not work until it will add it in local DNS file&lt;/p&gt;

&lt;p&gt;✅ Steps to add IP &amp;amp; DNS into local DNS file:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In linux: add it in /etc/hosts&lt;/li&gt;
&lt;li&gt;In windows: a. Open notepad as administrator &amp;gt;&amp;gt; file -&amp;gt; open -&amp;gt; select C:\windows\system32\drivers\etc\hosts file add C:\windows&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&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%2Fa3ove7tfhl81jmk2g4af.png" alt=" " width="732" height="213"&gt;
&lt;/h2&gt;

&lt;p&gt;Set up CICD pipeline using Github Actions and GitOps approach (ArgoCD):&lt;/p&gt;

&lt;p&gt;📌 Built Continuous Integration pipeline using Github Actions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Write a ci.yaml file under .github/worflows/ directory&lt;br&gt;
Link of the file: &lt;a href="https://github.com/Nandan3/End-to-End-DevOps-Projects/tree/main/.github/workflow" rel="noopener noreferrer"&gt;https://github.com/Nandan3/End-to-End-DevOps-Projects/tree/main/.github/workflow&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a new git branch in CLI&lt;br&gt;
$git checkout -b cicheck&lt;br&gt;
Switched to a new branch 'cicheck'&lt;br&gt;
Modify main.go file in product-catalog directory&lt;/p&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%2F7odpikh4gym6ovqp2tzr.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%2F7odpikh4gym6ovqp2tzr.png" alt=" " width="679" height="181"&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%2Fzpxajmzblps3lvmgo4ev.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%2Fzpxajmzblps3lvmgo4ev.png" alt=" " width="800" height="256"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Built Continuous Deployment pipeline using GitOps approach:&lt;/p&gt;

&lt;p&gt;✅ Why ArgoCD is preferred over other tools (like Ansible, shell scripting, python using helm)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Constant monitoring and automatic deployment to K8s cluster 2. Reconciliation of state: if any changes made in k8s cluster directly argoCD removes it and fix it into previous version. (version control system is the source of truth)&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%2Fgiopczmuuxex4fu2h7ij.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%2Fgiopczmuuxex4fu2h7ij.png" alt=" " width="800" height="385"&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%2Fxk573fb67doz1nxkuq9v.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%2Fxk573fb67doz1nxkuq9v.png" alt=" " width="411" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Deep dive into the IAM concepts and understand it with practicle hands-on.</title>
      <dc:creator>Nandan K</dc:creator>
      <pubDate>Sat, 21 Feb 2026 13:54:48 +0000</pubDate>
      <link>https://dev.to/nandan_007/deep-dive-into-the-iam-concepts-and-understand-it-with-practicle-hands-on-2ogp</link>
      <guid>https://dev.to/nandan_007/deep-dive-into-the-iam-concepts-and-understand-it-with-practicle-hands-on-2ogp</guid>
      <description>&lt;p&gt;🎯 In my recent interviews, I encountered lot of IAM related questions including scenario based questions in AWS. &lt;/p&gt;

&lt;p&gt;For example "an IAM user has FullAdmin, access to AWS account, yet he/she not able to access the S3 buckets, what must be the reason?"&lt;/p&gt;

&lt;p&gt;So I deep dive into the IAM concepts and understand it with practicle hands-on.&lt;/p&gt;

&lt;p&gt;📌 IAM User:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Represents a person, service or app needing access.&lt;/li&gt;
&lt;li&gt;To access any services in AWS &amp;gt;&amp;gt; grant user permissions &amp;gt;&amp;gt; to provide that permission, first assign "IAM Policies" to specific user or groups.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 IAM Groups:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Collection of users with common permissions and roles&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 IAM Roles:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Temporary access given to users, apps, or services.&lt;/li&gt;
&lt;li&gt;Increases the security&lt;/li&gt;
&lt;li&gt;Permissions for IAM roles comes from IAM policy (attach it roles, AWS service, Users, Groups)&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%2Fb7j8d7hmcrvjgo4vy2qs.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%2Fb7j8d7hmcrvjgo4vy2qs.png" alt=" " width="800" height="255"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Implement the "Principle of Least Privilege":&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;If your user needs access to do their jobs, give them access, but take away the access that they don't need.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 IAM Policies and Permissions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Permissions are provide fine-grained control over the actions performed on AWS resources or service.&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%2Fjnnsr5g9vodrmgr0ggxy.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%2Fjnnsr5g9vodrmgr0ggxy.png" alt=" " width="800" height="241"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Policies manage actions and permissions in AWS &amp;gt;&amp;gt; rules that define what resources an entity can access and what actions they can perform.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;✅ AWS Identity Based Policy:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It is policy attach to roles, groups or users&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%2Fed7jzbbxnmukkro30vxm.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%2Fed7jzbbxnmukkro30vxm.png" alt=" " width="800" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ AWS Resource Based Policy:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Policy is directly attach to AWS resources like S3, RDS etc &amp;gt;&amp;gt; this policy is going to define which user or service have the permission to access the resource.&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%2Fwjyg7ud8qtrffznjhvbg.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%2Fwjyg7ud8qtrffznjhvbg.png" alt=" " width="598" height="261"&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%2F4qijz01hs82qphqnzkx6.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%2F4qijz01hs82qphqnzkx6.png" alt=" " width="521" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, the group called "accounting" is denied from deleting the S3 bucket and objects within the bucket.&lt;/p&gt;

&lt;p&gt;📌 IAM Permission Boundaries:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;If new interns are hired &amp;gt;&amp;gt; they doesn't have proper experience &amp;gt;&amp;gt; these permissions are too wide to them &amp;gt;&amp;gt; so how can we limit the access to the new interns, while adding them into the proper group?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Solution: IAM Permission Boundaries&lt;br&gt;
If Developer have full access to the logs group, then I can assign list access to the new interns (Max level of Permission).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Even though new intern has the Full control permission, but "Permission Boundary" limits the access to only access the resource.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 IAM Session Policy:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It allows temporary access to users on AWS resources.&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%2Fb1zn6bogs8i8b718m54k.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%2Fb1zn6bogs8i8b718m54k.png" alt=" " width="800" height="253"&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%2Fjmp93gxlb051nmghzdzt.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%2Fjmp93gxlb051nmghzdzt.png" alt=" " width="731" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Inline Policy:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Attach the policy directly to user, group, roles&lt;/li&gt;
&lt;li&gt;Cannot be used by any other user, group, roles
Eg:
Provide temporary S3 access to DevOps Engineer (only valid for certain time period)&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%2Fmk97wsqjxh3md8vp0jyp.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%2Fmk97wsqjxh3md8vp0jyp.png" alt=" " width="489" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Managed Policy:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Created and managed by AWS&lt;/li&gt;
&lt;li&gt;It can be reused with other entities in different accounts.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Policy with Conditions:&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%2Ffibh4p991qegyvlal4qx.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%2Ffibh4p991qegyvlal4qx.png" alt=" " width="800" height="334"&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%2F832ze4rabdbjh11qv23e.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%2F832ze4rabdbjh11qv23e.png" alt=" " width="489" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To be continued...&lt;/p&gt;

&lt;h1&gt;
  
  
  AWS #Kubernetes #Terraform #Docker
&lt;/h1&gt;

</description>
      <category>aws</category>
      <category>terraform</category>
      <category>kubernetes</category>
      <category>docker</category>
    </item>
    <item>
      <title>Terraform Provisioners</title>
      <dc:creator>Nandan K</dc:creator>
      <pubDate>Thu, 25 Dec 2025 07:51:08 +0000</pubDate>
      <link>https://dev.to/nandan_007/terraform-provisioners-46m9</link>
      <guid>https://dev.to/nandan_007/terraform-provisioners-46m9</guid>
      <description>&lt;p&gt;Day 16 of #30daysofawsterraform challenge&lt;/p&gt;

&lt;p&gt;🎯 Do you want to execute the script or implement some configuration during resource creation or destruction using Terraform in any cloud providers? Here is the "Terraform Provisioners"&lt;/p&gt;

&lt;p&gt;✅ Terraform Provisioners are used to run scripts or commands on a resource after it is created (or before it is destroyed).&lt;/p&gt;

&lt;p&gt;✅ Key Features:&lt;br&gt;
      1. Provisioners run during resource lifecycle events (creation or destruction)&lt;br&gt;
      2. They are a "last resort" - Terraform recommends using native cloud-init, user_data, or configuration management tools when possible&lt;br&gt;
      3. They execute only once during resource creation (not on updates)&lt;br&gt;
      4. Failure handling: By default, if a provisioner fails, the resource is marked as "tainted" and will be recreated on next apply&lt;/p&gt;

&lt;p&gt;💡 Types of Provisioners:&lt;/p&gt;

&lt;p&gt;📌 "local-exec" Provisioner:&lt;br&gt;
Runs a command on the machine where Terraform is executed, NOT on the resource.&lt;br&gt;
Eg:&lt;br&gt;
provisioner "local-exec" {&lt;br&gt;
  command = "echo 'Local-exec: created instance ${self.id} with IP ${self.public_ip}'"&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;📌 "remote-exec" Provisioner:&lt;br&gt;
Runs commands inside the created server (EC2, VM).&lt;br&gt;
Eg:&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%2Fa692nyuosdz2fgfect5p.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%2Fa692nyuosdz2fgfect5p.png" alt=" " width="322" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌"file" Provisioner:&lt;br&gt;
Copies files from local machine to remote server.&lt;br&gt;
Eg:&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%2F0cfqkss9nz24e05gqep4.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%2F0cfqkss9nz24e05gqep4.png" alt=" " width="361" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;⚠️Why Terraform Provisioners Are NOT Recommended&lt;br&gt;
     Provisioners:&lt;br&gt;
        1. Run after resource creation&lt;br&gt;
        2. Depend on SSH / network readiness&lt;br&gt;
        3. Are not idempotent (can fail on re-run)&lt;br&gt;
        4. Mix infrastructure creation with server configuration&lt;/p&gt;

&lt;p&gt;✅ Better Alternatives:&lt;br&gt;
       1. user_data (Cloud-init) - A script that runs automatically when the server boots. (Best for Bootstrapping)&lt;br&gt;
       2. Custom AMIs - Pre-built machine images with software already installed.&lt;br&gt;
       3. Configure servers after creation, but in a controlled, idempotent way using Ansible, Chef, Puppet.&lt;br&gt;
       4. Run commands on EC2 using AWS agent like AWS Systems Manager.&lt;/p&gt;

&lt;p&gt;For more details refer:&lt;br&gt;
Youtube: &lt;a href="https://youtu.be/DkhAgYa0448?si=R_b7sBYuC7CPCV2i" rel="noopener noreferrer"&gt;https://youtu.be/DkhAgYa0448?si=R_b7sBYuC7CPCV2i&lt;/a&gt;&lt;br&gt;
Github: &lt;a href="https://github.com/Nandan3/Terraform-Full-Course-Aws/tree/main/lessons/day19" rel="noopener noreferrer"&gt;https://github.com/Nandan3/Terraform-Full-Course-Aws/tree/main/lessons/day19&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Devops #Terraform #AWS
&lt;/h1&gt;

</description>
      <category>beginners</category>
      <category>aws</category>
      <category>terraform</category>
      <category>devops</category>
    </item>
    <item>
      <title>Mini project to demonstrate VPC peering in AWS using Terraform</title>
      <dc:creator>Nandan K</dc:creator>
      <pubDate>Tue, 16 Dec 2025 08:58:54 +0000</pubDate>
      <link>https://dev.to/nandan_007/demonstrate-vpc-peering-in-aws-using-terraform-3nde</link>
      <guid>https://dev.to/nandan_007/demonstrate-vpc-peering-in-aws-using-terraform-3nde</guid>
      <description>&lt;p&gt;Day 15 of #30daysofawsterraform challenge&lt;/p&gt;

&lt;p&gt;🎯 This mini project demonstrates cross-region VPC peering, enabling secure private communication between EC2 instances in different AWS regions while maintaining network isolation and controlled access. The setup enables secure, low-latency communication between resources in both VPCs using private IP addresses.&lt;/p&gt;

&lt;p&gt;✅ What is VPC Peering?&lt;/p&gt;

&lt;p&gt;VPC Peering is a networking connection between two Virtual Private Clouds (VPCs) that enables private IP communication between them as if they were part of the same network.&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%2Fbg7wu02vopwgyuzvgei2.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%2Fbg7wu02vopwgyuzvgei2.png" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Architecture:&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%2F75s993jgzg3icxpiew78.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%2F75s993jgzg3icxpiew78.png" alt=" " width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ In this demo we creates:&lt;/p&gt;

&lt;p&gt;✨ Networking section:&lt;br&gt;
    1. Two VPC in us-east-1 &amp;amp; us-west-2&lt;br&gt;
    2. Configure one public subnet in each VPC&lt;br&gt;
    3. Internet Gateways - one for each VPC to allow internet access&lt;br&gt;
    4. Custom route tables with routes to internet and peered VPC&lt;br&gt;
    5. VPC peering - Cross-region peering between the two VPCs&lt;/p&gt;

&lt;p&gt;✨ Compute Resources:&lt;br&gt;
    1. EC2 instances in each VPC&lt;/p&gt;

&lt;p&gt;✨ Configure Security Groups:&lt;br&gt;
    1. SSH access from anywhere (port 22)&lt;br&gt;
    2. ICMP (ping) allowed from peered VPC&lt;br&gt;
    3. All TCP traffic allowed between VPCs&lt;/p&gt;

&lt;p&gt;💡 Below are the detailed steps we followed to implement the project:&lt;/p&gt;

&lt;p&gt;📌Step 1: Prerequisites:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;aws cli should be installed&lt;/li&gt;
&lt;li&gt;Terraform should be installed&lt;/li&gt;
&lt;li&gt;Configure AWS Credentials using "aws configure" command&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌Step 2: Create SSH Key Pairs in each region &lt;/p&gt;

&lt;p&gt;# Create key pair in us-east-1&lt;br&gt;
   aws ec2 create-key-pair \&lt;br&gt;
   --key-name vpc-peering-demo-east \&lt;br&gt;
   --region us-east-1 \&lt;br&gt;
   --query 'KeyMaterial' \&lt;br&gt;
   --output text &amp;gt; vpc-peering-demo-east.pem&lt;/p&gt;

&lt;p&gt;# Create key pair in us-west-2&lt;br&gt;
   aws ec2 create-key-pair \&lt;br&gt;
   --key-name vpc-peering-demo-west \&lt;br&gt;
   --region us-west-2 \&lt;br&gt;
   --query 'KeyMaterial' \&lt;br&gt;
   --output text &amp;gt; vpc-peering-demo-west.pem&lt;/p&gt;

&lt;p&gt;✅ Main.tf file:&lt;/p&gt;

&lt;p&gt;📌Step 3:&lt;br&gt;
Provisioned a Primary VPC in us-east-1 and a Secondary VPC in us-west-2 using separate provider aliases.&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%2Fg103ejqwb2yq1l9wom5e.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%2Fg103ejqwb2yq1l9wom5e.png" alt=" " width="475" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌Step 4: &lt;br&gt;
Public subnet was created in each VPC using region-specific availability zones.&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%2Fjnsu9wnvn813ei6cc1k1.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%2Fjnsu9wnvn813ei6cc1k1.png" alt=" " width="605" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌Step 5:&lt;br&gt;
Internet Gateways were created and attached to both VPCs. This enables outbound internet access and inbound connectivity for public resources.&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%2Fpwv8r1yixevwjkkqkmgu.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%2Fpwv8r1yixevwjkkqkmgu.png" alt=" " width="407" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌Step 6:&lt;br&gt;
Custom route tables were created for both VPCs with a default route (0.0.0.0/0) pointing to the Internet Gateway. Each route table was associated with its corresponding subnet. This ensures proper routing for internet traffic within each VPC.&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%2F726u5rzmdo8oridv7us9.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%2F726u5rzmdo8oridv7us9.png" alt=" " width="467" height="476"&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%2Fqbonwgpz0a0ce3i2dth5.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%2Fqbonwgpz0a0ce3i2dth5.png" alt=" " width="464" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌Step 7:&lt;br&gt;
A VPC peering connection was initiated from the Primary VPC to the Secondary VPC across regions. This establishes private connectivity between the two isolated networks.&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%2Fyeguw6himuqizjau8kz6.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%2Fyeguw6himuqizjau8kz6.png" alt=" " width="650" height="418"&gt;&lt;/a&gt;&lt;br&gt;
Same has to be done from secondary VPC to primary VPC&lt;/p&gt;

&lt;p&gt;📌Step 8:&lt;br&gt;
Routes were added in both VPC route tables to direct traffic destined for the peer VPC CIDR via the peering connection. This enables bidirectional communication using private IP addresses.&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%2Fubewxwwnpjzw42jd56ri.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%2Fubewxwwnpjzw42jd56ri.png" alt=" " width="667" height="301"&gt;&lt;/a&gt;&lt;br&gt;
Same has to be done from secondary VPC to primary VPC&lt;/p&gt;

&lt;p&gt;📌Step 9:&lt;br&gt;
Security groups were defined in each VPC to allow SSH access for administration. ICMP and TCP traffic were permitted between the VPC CIDR ranges to validate connectivity.&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%2F4y6qx0a8ud2fpv83rrmb.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%2F4y6qx0a8ud2fpv83rrmb.png" alt=" " width="473" height="542"&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%2Fktsaa3mmaxcm2kkcsd6x.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%2Fktsaa3mmaxcm2kkcsd6x.png" alt=" " width="421" height="150"&gt;&lt;/a&gt;&lt;br&gt;
Same has to be done for Secondary VPC&lt;/p&gt;

&lt;p&gt;📌Step 10:&lt;br&gt;
EC2 instances were launched in each subnet using region-appropriate AMIs and key pairs.&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%2F3mimeknjwi8wcqdro1ts.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%2F3mimeknjwi8wcqdro1ts.png" alt=" " width="587" height="292"&gt;&lt;/a&gt;&lt;br&gt;
Same has to be done for Secondary instance&lt;/p&gt;

&lt;p&gt;📌Data_source.tf file:&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%2Fbeigjmjfs012breerru8.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%2Fbeigjmjfs012breerru8.png" alt=" " width="625" height="542"&gt;&lt;/a&gt;&lt;br&gt;
Same has to be done for Secondary VPC&lt;/p&gt;

&lt;p&gt;📌Locals.tf file:&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%2Fu4nfadhwcg80l0880ozh.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%2Fu4nfadhwcg80l0880ozh.png" alt=" " width="778" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌Variables.tf file:&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%2Flhidveu1ov8wqyqu9ixs.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%2Flhidveu1ov8wqyqu9ixs.png" alt=" " width="475" height="549"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Outputs:&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%2F7zw1jjt4fmgoxvheb4gq.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%2F7zw1jjt4fmgoxvheb4gq.png" alt=" " width="720" height="358"&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%2F1w1lo1k55vn73340dpd3.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%2F1w1lo1k55vn73340dpd3.png" alt=" " width="667" height="74"&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%2Fwze5zs83h5olfvychom0.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%2Fwze5zs83h5olfvychom0.png" alt=" " width="682" height="38"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For more details refer:&lt;br&gt;
Youtube: &lt;a href="https://youtu.be/WGt000THDmQ?si=bjisghj-pts6-GPu" rel="noopener noreferrer"&gt;https://youtu.be/WGt000THDmQ?si=bjisghj-pts6-GPu&lt;/a&gt;&lt;br&gt;
Github: &lt;a href="https://github.com/Nandan3/Terraform-Full-Course-Aws/tree/main/lessons/day15" rel="noopener noreferrer"&gt;https://github.com/Nandan3/Terraform-Full-Course-Aws/tree/main/lessons/day15&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Devops #Terraform #AWS
&lt;/h1&gt;

&lt;p&gt;Thanks to Piyush sachdeva The CloudOps Community&lt;/p&gt;

</description>
      <category>aws</category>
      <category>tutorial</category>
      <category>terraform</category>
      <category>networking</category>
    </item>
    <item>
      <title>Deploying a secure and scalable static website on AWS using Terraform</title>
      <dc:creator>Nandan K</dc:creator>
      <pubDate>Sat, 13 Dec 2025 10:27:55 +0000</pubDate>
      <link>https://dev.to/nandan_007/deploying-a-secure-and-scalable-static-website-on-aws-using-terraform-2n0f</link>
      <guid>https://dev.to/nandan_007/deploying-a-secure-and-scalable-static-website-on-aws-using-terraform-2n0f</guid>
      <description>&lt;p&gt;Day 14 of #30daysofawsterraform challenge&lt;/p&gt;

&lt;p&gt;🎯 This mini project demonstrates the deployment of a secure static website on AWS using Terraform. It implements an end-to-end infrastructure-as-code solution leveraging Amazon S3 for static content storage and Amazon CloudFront for global content delivery, ensuring high availability, improved performance, and HTTPS-enabled access through a custom domain.&lt;/p&gt;

&lt;p&gt;🧠 Project Architecture:&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%2F1u50qw0vulp73xupt2pd.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%2F1u50qw0vulp73xupt2pd.png" alt=" " width="800" height="289"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💡 Step-by-step approach for project implementation:&lt;/p&gt;

&lt;p&gt;📌 Step 1: &lt;br&gt;
Provisioned an S3 bucket to store static website files and blocked all public access, ensuring the bucket is not directly accessible from the internet.&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%2Ft4y4vjexjflqpamilbhe.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%2Ft4y4vjexjflqpamilbhe.png" alt=" " width="518" height="230"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Step 2: Automatically uploaded all files from the local www/ directory to S3 and set MIME content types (HTML, CSS, JS, images).&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%2Fu2v9apkgn0ulv2wsluos.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%2Fu2v9apkgn0ulv2wsluos.png" alt=" " width="750" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Step 3:&lt;br&gt;
Looked up the existing public Route 53 hosted zone for my domain.&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%2Ftmpk0feh07v03a9i97hb.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%2Ftmpk0feh07v03a9i97hb.png" alt=" " width="273" height="95"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Step 4: &lt;br&gt;
Requested an SSL Certificate through AWS Certificate Manager, which is mandatory for CloudFront access validated the certificate using DNS validation via Route 53.&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%2Fgabwvviiqycrg11c3p97.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%2Fgabwvviiqycrg11c3p97.png" alt=" " width="549" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Step 5:&lt;br&gt;
Created a CloudFront Origin Access Control (OAC), which ensures that only CloudFront can read content from your S3 bucket over HTTPS, and direct public access to S3 is completely blocked.&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%2Fb5lowm8hjg7gljaax0gx.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%2Fb5lowm8hjg7gljaax0gx.png" alt=" " width="541" height="131"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Step 6:&lt;br&gt;
Configure the CloudFront (CF) distribution through Terraform resources. &lt;br&gt;
CF is the setup that connects users to your content through AWS’s global CDN. It reduces the latency through caching content in nearest edge location.&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%2F1xhkuc9hc3b0lx7hm5zy.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%2F1xhkuc9hc3b0lx7hm5zy.png" alt=" " width="708" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Step 7:&lt;br&gt;
Applied an S3 bucket policy allowing s3:GetObject only from the CloudFront distribution using SourceArn conditions.&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%2Ffvb7sel6y65qs76mp4je.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%2Ffvb7sel6y65qs76mp4je.png" alt=" " width="630" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Step 8:&lt;br&gt;
Created a Route 53 alias record pointing your custom domain to the CloudFront distribution and enabled HTTPS access via your custom domain.&lt;br&gt;
The Route 53 alias record maps my custom domain (for example, &lt;a href="http://www.example.com" rel="noopener noreferrer"&gt;www.example.com&lt;/a&gt;) to the CloudFront distribution so users can access the website using your own domain.&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%2Fnw3pcykbjhmxe1vf6xwu.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%2Fnw3pcykbjhmxe1vf6xwu.png" alt=" " width="713" height="191"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;variable.tf file:&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%2Fg7p3amtg70pat04yx714.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%2Fg7p3amtg70pat04yx714.png" alt=" " width="471" height="188"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Outputs.tf file:&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%2Ft8hpybpmmn55cr58ewe2.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%2Ft8hpybpmmn55cr58ewe2.png" alt=" " width="683" height="235"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Outputs:&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%2F59wno4dmji69i0vixn5b.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%2F59wno4dmji69i0vixn5b.png" alt=" " 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%2F0qv76gijkygxzqq3q9mw.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%2F0qv76gijkygxzqq3q9mw.png" alt=" " width="800" height="97"&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%2Fiqaxyisbpqpew0xrrne8.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%2Fiqaxyisbpqpew0xrrne8.png" alt=" " width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ For more details refer:&lt;br&gt;
YouTube: &lt;a href="https://youtu.be/bK6RimAv2nQ?si=4wzFeWv1qBgiMKwo" rel="noopener noreferrer"&gt;https://youtu.be/bK6RimAv2nQ?si=4wzFeWv1qBgiMKwo&lt;/a&gt;&lt;br&gt;
Github: &lt;a href="https://github.com/Nandan3/Terraform-Full-Course-Aws/tree/main/lessons/day14" rel="noopener noreferrer"&gt;https://github.com/Nandan3/Terraform-Full-Course-Aws/tree/main/lessons/day14&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Devops #Terraform #AWS
&lt;/h1&gt;

&lt;p&gt;Thanks to Piyush sachdeva The CloudOps Community&lt;/p&gt;

</description>
      <category>devops</category>
      <category>aws</category>
      <category>tutorial</category>
      <category>terraform</category>
    </item>
    <item>
      <title>Terraform Data Sources</title>
      <dc:creator>Nandan K</dc:creator>
      <pubDate>Thu, 11 Dec 2025 06:32:18 +0000</pubDate>
      <link>https://dev.to/nandan_007/terraform-data-sources-2gie</link>
      <guid>https://dev.to/nandan_007/terraform-data-sources-2gie</guid>
      <description>&lt;p&gt;🧠 Hardcoding the values in code is breach of security and reusing hardcoded values again and again is not a good practice. So today I come across an interesting topic i.e. "Data Sources". &lt;/p&gt;

&lt;p&gt;🎯 Data Sources in terraform allows us to read existing information from your cloud provider without creating anything and also minimises the use of hardcoded values in terraform code.&lt;/p&gt;

&lt;p&gt;📌 Why Do We Use Data Sources?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;To get IDs of existing VPCs, subnets, AMIs, security groups&lt;/li&gt;
&lt;li&gt;To fetch latest AMI dynamically&lt;/li&gt;
&lt;li&gt;To use existing infrastructure in new Terraform code&lt;/li&gt;
&lt;li&gt;To avoid hardcoding values&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;💡 Let's take an example, we have shared VPC with multiple teams using it and has 2 subnet. We want to provision 2 EC2 instances in each subnet by giving reference of existing VPC and subnet and also use pre-existing Linux image while creating EC2 instances by using data sources.&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%2Fse2pvpppuolq8ixe4z1p.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%2Fse2pvpppuolq8ixe4z1p.png" alt=" " width="800" height="336"&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%2Fmt55j53cyl76lee36afb.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%2Fmt55j53cyl76lee36afb.png" alt=" " width="400" height="557"&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%2Fb0vdcgivn6oqv2sn5mds.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%2Fb0vdcgivn6oqv2sn5mds.png" alt=" " width="596" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My hands-on demo's:&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%2Flybogbbabluvt4xh7u4q.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%2Flybogbbabluvt4xh7u4q.png" alt=" " width="513" height="335"&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%2Fwxo9qzlu1jj4m7v5s04l.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%2Fwxo9qzlu1jj4m7v5s04l.png" alt=" " width="618" height="332"&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%2Fcmxj6cgvw82e8g4f73zy.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%2Fcmxj6cgvw82e8g4f73zy.png" alt=" " width="529" height="108"&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%2Frfo2ow7nuwk5seyyw25l.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%2Frfo2ow7nuwk5seyyw25l.png" alt=" " width="774" height="215"&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%2Ftmcr9tc8qpuqx1ju9zxq.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%2Ftmcr9tc8qpuqx1ju9zxq.png" alt=" " width="716" height="214"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Terraform Functions</title>
      <dc:creator>Nandan K</dc:creator>
      <pubDate>Tue, 09 Dec 2025 11:13:34 +0000</pubDate>
      <link>https://dev.to/nandan_007/terraform-functions-1bj0</link>
      <guid>https://dev.to/nandan_007/terraform-functions-1bj0</guid>
      <description>&lt;p&gt;Function in terraform help you transform data, build dynamic values, and write smarter infrastructure code.&lt;br&gt;
Terraform supports only built in function. Here are some details -&lt;/p&gt;

&lt;p&gt;📌 String Functions:&lt;/p&gt;

&lt;p&gt;✅ lower() - lower("HELLO")      → "hello" &lt;br&gt;
✅ upper() - upper("hello")      → "HELLO" &lt;br&gt;
✅ replace() - replace("dev-app", "dev", "prod") → "prod-app"&lt;br&gt;
✅ substr()&lt;br&gt;
✅ trim() - trim(" hello ", " ")   → "hello"&lt;br&gt;
✅ split() - split(",", "a,b,c")   → ["a", "b", "c"]&lt;br&gt;
✅ join() - join(",", ["a", "b", "c"])   → "a,b,c"&lt;br&gt;
✅ chomp() - chomp("hello\n") → "hello" hashtag#cuts off the last newline character from a string.&lt;/p&gt;

&lt;p&gt;📌 Numeric Functions&lt;br&gt;
✅ abs() - abs(-3) → 3 hashtag#Absolute value&lt;br&gt;
✅ max() - max(10, 5, 8) → 10&lt;br&gt;
✅ min() - min(10, 5, 8) → 5&lt;br&gt;
✅ ceil() - ceil(4.2) → 5 hashtag#Round UP a number&lt;br&gt;
✅ floor() - floor(4.8) → 4 hashtag#Round DOWN a number&lt;br&gt;
✅ sum() - sum([1, 2, 3]) → 6&lt;/p&gt;

&lt;p&gt;📌 Collection Functions&lt;br&gt;
✅ length() - length([1,2,3]) → 3&lt;br&gt;
✅ concat() - concat([1,2], [3,4]) → [1,2,3,4]&lt;br&gt;
✅ merge() - merge({a=1}, {b=2}) → {a=1, b=2}&lt;br&gt;
✅ reverse() - reverse([1, 2, 3, 4]) → [4, 3, 2, 1]&lt;br&gt;
✅ toset() - toset(["a", "b", "a"]) → ["a", "b"] &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Converts a list into a set.&lt;/li&gt;
&lt;li&gt;A set has unique values (no duplicates) and order does not matter
✅ tolist() - tolist(toset(["a", "b", "a"])) → ["a", "b"]&lt;/li&gt;
&lt;li&gt;Converts something (like a set or tuple) into a list.&lt;/li&gt;
&lt;li&gt;A list keeps order and allows duplicates&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 Type Conversion&lt;br&gt;
✅ tonumber() - tonumber("10") → 10&lt;br&gt;
✅ tostring() - tostring(100) → "100"&lt;br&gt;
✅ tobool() - &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;tobool("true") → true&lt;/li&gt;
&lt;li&gt;tobool(1)  → true&lt;/li&gt;
&lt;li&gt;tobool(0)  → false&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 File Functions&lt;br&gt;
✅ file() - file("message.txt") → "Hello Nandan"&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reads a file from your system and returns the text inside it.&lt;/li&gt;
&lt;li&gt;Use this when loading user-data scripts or config files.
✅ fileexists() - fileexists("config.yaml") → true/false
✅ dirname() - get folder / directory path
✅ basename() - get the filename inside the directory&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 Date/Time Functions&lt;br&gt;
✅ timestamp() - current date and time&lt;br&gt;
✅ formatdate() - formatdate("YYYY-MM-DD", timestamp()) hashtag#changes a date/time into a different format.&lt;br&gt;
✅ timeadd() - adds time (like days, hours, minutes) to a timestamp.&lt;/p&gt;

&lt;p&gt;📌 Validation Functions&lt;/p&gt;

&lt;p&gt;✅ can() - can(tolist("hello")) → false hashtag#cannot convert string "hello" to list&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It tells you if an expression will run without error.&lt;/li&gt;
&lt;li&gt;Use it to safely test something without breaking Terraform.
✅ regex() - regex("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$", "&lt;a href="mailto:nandan@gmail.com"&gt;nandan@gmail.com&lt;/a&gt;") hashtag#Check if a value looks like an email&lt;/li&gt;
&lt;li&gt;Checks if a string matches a regular expression pattern.
✅ contains() - contains(["dev", "prod"], "dev") → true&lt;/li&gt;
&lt;li&gt;Returns true if an item exists inside a list.
✅ startswith() - startswith("dev-app", "dev") → true hashtag#Returns true if the string starts with the given text.
✅ endswith() - endswith("app-prod", "dev") → false hashtag#Returns true if the string ends with the given text.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 Lookup Functions&lt;/p&gt;

&lt;p&gt;✅ lookup() - lookup({env = "dev", region = "us-east-1"}, "env", "default") → "dev"&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It returns a value from a map (key–value pair).&lt;/li&gt;
&lt;li&gt;If the key does NOT exist → it returns a default value.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;✅ element() - element(["a", "b", "c"], 1) → "b" hashtag#returns the item at a specific index from a list.&lt;br&gt;
✅ index() - index(["dev", "stage", "prod"], "stage") → 1 hashtag#Find the Position of a Value in a List.&lt;/p&gt;

&lt;p&gt;Refer: &lt;a href="https://lnkd.in/gNHnBNDe" rel="noopener noreferrer"&gt;https://lnkd.in/gNHnBNDe&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;hashtag#Devops hashtag#Terraform hashtag#AWS&lt;/p&gt;

&lt;p&gt;Thanks to Piyush sachdeva The CloudOps Community&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Terraform Expressions</title>
      <dc:creator>Nandan K</dc:creator>
      <pubDate>Tue, 09 Dec 2025 08:20:27 +0000</pubDate>
      <link>https://dev.to/nandan_007/terraform-expressions-3j3l</link>
      <guid>https://dev.to/nandan_007/terraform-expressions-3j3l</guid>
      <description>&lt;p&gt;📋 Today I have completed Terraform expression, its types and use cases with practical hands-on.&lt;/p&gt;

&lt;p&gt;📌What is terraform expression?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Help us to avoid rewriting the code again and again, make configurations dynamic, reusable, and smart.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;✅ Types:&lt;/p&gt;

&lt;p&gt;📌 Conditional expression:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Evaluates a condition and returns one of two values based on whether the condition is true or false.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Syntax:&lt;br&gt;
Condition ? True_value : false_value&lt;/p&gt;

&lt;p&gt;Eg: &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%2F8iu2dupmarf0kafshxoc.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%2F8iu2dupmarf0kafshxoc.png" alt=" " width="575" height="172"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Output:&lt;br&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%2Fhbp1dv4xmq8jc713pgcw.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%2Fhbp1dv4xmq8jc713pgcw.png" alt=" " width="543" height="65"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 Dynamic Blocks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It will used when you want to create repeated nested blocks automatically, instead of writing them manually.&lt;/li&gt;
&lt;li&gt;It’s like a loop (for-each) inside a resource block and will create one block for each item in a list or map.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Syntax:&lt;br&gt;
dynamic "block_name" {&lt;br&gt;
 for_each = var.collection&lt;br&gt;
 content {&lt;br&gt;
 # Block configuration using each.key and each.value&lt;br&gt;
 }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;🔁 How it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;for_each iterates over a list or map&lt;/li&gt;
&lt;li&gt;content defines what each block should contain&lt;/li&gt;
&lt;li&gt;Access values using block_name.value or block_name.key&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Eg:&lt;br&gt;
  main.tf:&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%2F0puhgkebajp1442z317x.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%2F0puhgkebajp1442z317x.png" alt=" " width="405" height="235"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;variable.tf:&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%2Fa7ndvgf699tcfayuljel.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%2Fa7ndvgf699tcfayuljel.png" alt=" " width="494" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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%2Fxm3vjxl5fluumxok5dzk.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%2Fxm3vjxl5fluumxok5dzk.png" alt=" " width="448" height="518"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🌀 Use Cases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Security group rules&lt;/li&gt;
&lt;li&gt;Multiple EBS volumes on EC2 instances&lt;/li&gt;
&lt;li&gt;Route table routes&lt;/li&gt;
&lt;li&gt;IAM policies&lt;/li&gt;
&lt;li&gt;Kubernetes containers&lt;/li&gt;
&lt;li&gt;CloudFront behaviors&lt;/li&gt;
&lt;li&gt;Tags&lt;/li&gt;
&lt;li&gt;Environment variables&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 Splat Expression:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Let's you get a list of values from multiple resources created using count or for_each.&lt;/li&gt;
&lt;li&gt;It’s like saying “give me this attribute from ALL the resources.”&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Syntax:&lt;br&gt;
resource_list[*].attribute_name&lt;/p&gt;

&lt;p&gt;Eg:&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%2Fqafxbri4wp68l3m2fbxn.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%2Fqafxbri4wp68l3m2fbxn.png" alt=" " width="416" height="124"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Gives the instance ids from nandan_ec2 instances.&lt;/p&gt;

&lt;p&gt;Refer: &lt;a href="https://youtu.be/R4ShnFDJwI8?si=rlAMgR-JZjdd6djf" rel="noopener noreferrer"&gt;https://youtu.be/R4ShnFDJwI8?si=rlAMgR-JZjdd6djf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks to Piyush, The Cloud Community&lt;/p&gt;

</description>
      <category>devops</category>
      <category>terraform</category>
      <category>aws</category>
    </item>
    <item>
      <title>Terraform Life Cycle Rules</title>
      <dc:creator>Nandan K</dc:creator>
      <pubDate>Wed, 03 Dec 2025 10:09:47 +0000</pubDate>
      <link>https://dev.to/nandan_007/terraform-life-cycle-rules-1odl</link>
      <guid>https://dev.to/nandan_007/terraform-life-cycle-rules-1odl</guid>
      <description>&lt;p&gt;Day 9 of #30daysofawsterraform challenge&lt;/p&gt;

&lt;p&gt;Do you really want to prevent someone from accidental deletion of resources, improve the security and improve the manageability of infrastructure in Terraform? Here is the Terraform life cycle rules comes into play.&lt;/p&gt;

&lt;p&gt;Today I have covered "Terraform life cycle rules" with practical hands-on.&lt;/p&gt;

&lt;p&gt;§ What is Terraform life cycle rules:&lt;br&gt;
    1. Terraform Lifecycle rules gives you fine-grained control over resource behavior, preventing unwanted changes and ensuring stability in production environments.&lt;/p&gt;

&lt;p&gt;§ Meta-Arguments:&lt;/p&gt;

&lt;p&gt;○ create_before_destroy:&lt;br&gt;
    1. It allows to create replacement resource first, before destroying the old one.&lt;br&gt;
        2. Ensures zero downtime&lt;br&gt;
        Eg:&lt;br&gt;
        resource "aws_instance" "nandan_ec2" {&lt;br&gt;
          ami = "ami-0ff8a91507f77f867"&lt;br&gt;
          instance_type = "t2.micro"&lt;br&gt;
          region = var.region&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      tags = var.tags

      lifecycle {
        create_before_destroy = false
      }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;ü Usecases:&lt;br&gt;
    1. Updating an AWS Load Balancer that must always remain online&lt;br&gt;
    2. Rotating EC2 instances in an Auto Scaling group&lt;br&gt;
    3. Updating an RDS instance when you want zero downtime&lt;br&gt;
    4. Replacing an S3 bucket with the same configuration safely&lt;/p&gt;

&lt;p&gt;○ prevent_destroy:&lt;br&gt;
    1. Protects resources by blocking any operation that would delete them.&lt;br&gt;
    Eg:&lt;br&gt;
        resource "aws_s3_bucket" "production_logs" {&lt;br&gt;
          bucket = "nandan-production-logs"&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      lifecycle {
        prevent_destroy = true
      }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;ü Usecase:&lt;br&gt;
    1. Protecting production databases&lt;br&gt;
    2. Preventing deletion of S3 buckets holding logs or critical data&lt;br&gt;
    3. Safeguarding VPCs, subnets, and networking components&lt;br&gt;
    4. Security groups protecting production resources&lt;br&gt;
    5. Stateful resources that should never be deleted&lt;/p&gt;

&lt;p&gt;○ ignore_changes:&lt;br&gt;
    1. Tells Terraform to ignore changes to specified resource attributes.&lt;br&gt;
        Eg:&lt;br&gt;
        resource "aws_autoscaling_group" "app_servers" {&lt;br&gt;
  desired_capacity = 2&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    lifecycle {
ignore_changes = [
  desired_capacity,  # Ignore capacity changes by auto-scaling
  load_balancers,    # Ignore if added externally
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;ü Use Cases:&lt;br&gt;
    1. Auto Scaling Group capacity (managed by auto-scaling policies)&lt;br&gt;
    2. EC2 instance tags (added by monitoring tools)&lt;br&gt;
    3. Security group rules (managed by other teams)&lt;br&gt;
    4. Database passwords (managed via Secrets Manager)&lt;/p&gt;

&lt;p&gt;○ replace_triggered_by:&lt;br&gt;
    1. Used to force the replacement of a resource when another resource or value changes.&lt;br&gt;
    Eg:&lt;br&gt;
        resource "aws_instance" "web" {&lt;br&gt;
          ami           = var.ami_id&lt;br&gt;
          instance_type = "t2.micro"&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      lifecycle {
        replace_triggered_by = [
          var.ami_id
        ]
      }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;ü Use Cases:&lt;br&gt;
    1. Replace EC2 instances when security groups change&lt;br&gt;
    2. Recreate containers when configuration changes&lt;br&gt;
    3. Force rotation of resources based on other resource updates&lt;br&gt;
    4. For immutable infrastructure patterns&lt;/p&gt;

&lt;p&gt;○ precondition:&lt;br&gt;
    1. Validates conditions BEFORE Terraform attempts to create or update a resource. Errors if condition is false.&lt;br&gt;
        Eg: &lt;br&gt;
        resource "aws_instance" "web" {&lt;br&gt;
          ami           = var.ami&lt;br&gt;
          instance_type = var.instance_type&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      lifecycle {
        precondition {
          condition     = contains(["t2.micro", "t3.micro"], var.instance_type)
          error_message = "Only t2.micro and t3.micro are allowed!"
        }
      }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;ü Use Cases:&lt;br&gt;
    1. Validate deployment region is allowed&lt;br&gt;
    2. Ensure required tags are present&lt;br&gt;
    3. Check environment variables before deployment&lt;br&gt;
    4. Validate configuration parameters&lt;/p&gt;

&lt;p&gt;○ postcondition:&lt;br&gt;
    1. Validates conditions AFTER Terraform creates or updates a resource. Errors if condition is false.&lt;br&gt;
        Eg:&lt;br&gt;
        resource "aws_instance" "web" {&lt;br&gt;
          ami           = var.ami&lt;br&gt;
          instance_type = "t2.micro"&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      lifecycle {
        postcondition {
          condition     = self.public_ip != ""
          error_message = "Instance must have a public IP assigned!"
        }
      }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;ü Use Cases:&lt;br&gt;
    1. Ensure required tags exist after creation&lt;br&gt;
    2. Validate resource attributes are correctly set&lt;br&gt;
    3. Check resource state after deployment&lt;br&gt;
    4. Verify compliance after creation&lt;/p&gt;

&lt;h1&gt;
  
  
  Devops #Terraform #AWS
&lt;/h1&gt;

&lt;p&gt;Thanks to Piyush sachdeva The CloudOps Community&lt;/p&gt;

</description>
      <category>aws</category>
      <category>devchallenge</category>
      <category>devops</category>
      <category>terraform</category>
    </item>
    <item>
      <title>Terraform Meta-arguments</title>
      <dc:creator>Nandan K</dc:creator>
      <pubDate>Tue, 02 Dec 2025 07:59:43 +0000</pubDate>
      <link>https://dev.to/nandan_007/terraform-meta-arguments-201i</link>
      <guid>https://dev.to/nandan_007/terraform-meta-arguments-201i</guid>
      <description>&lt;p&gt;Day 8 of #30daysofawsterraform challenge&lt;/p&gt;

&lt;p&gt;Today I have deep dive into use cases of meta arguments with practicle examples.&lt;/p&gt;

&lt;p&gt;What is it?&lt;br&gt;
    Meta-arguments are special arguments that can be used with "any resource type" to change the behavior of resources.&lt;/p&gt;

&lt;p&gt;Different Meta-arguments:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Count:
Create multiple resource instances based on a number
Eg:
resource "aws_s3_bucket" "nandan_bucket" {
  count  = 3
  bucket = "my-bucket-${count.index}"
  tags = var.tags
}


For_each:
Creating resources from a map or set.
Eg:
resource "aws_s3_bucket" "example" {
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;for_each = toset(["bucket1", "bucket2", "bucket3"])&lt;br&gt;
  bucket   = each.value&lt;br&gt;
}&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Depends_on:
Ensuring resources are created in specific order
Eg:
resource "aws_s3_bucket" "dependent" {
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;bucket = "my-bucket"&lt;/p&gt;

&lt;p&gt;depends_on = [aws_s3_bucket.primary]&lt;br&gt;
}&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Provider:&lt;br&gt;
Use cases:&lt;br&gt;
    Multi-region deployments&lt;br&gt;
    Multi-account setups&lt;br&gt;
    Cross-region replication&lt;br&gt;
Eg:&lt;br&gt;
resource "aws_s3_bucket" "example" {&lt;br&gt;
  provider = aws.west  # Use alternate provider&lt;br&gt;
  bucket   = "my-bucket"&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Devops #Terraform #AWS&lt;br&gt;
&lt;/h1&gt;

&lt;p&gt;Thanks to Piyush sachdeva The CloudOps Community&lt;/p&gt;

</description>
      <category>devops</category>
      <category>terraform</category>
      <category>aws</category>
    </item>
    <item>
      <title>Terraform type constraints or variable types</title>
      <dc:creator>Nandan K</dc:creator>
      <pubDate>Mon, 01 Dec 2025 13:30:31 +0000</pubDate>
      <link>https://dev.to/nandan_007/terraform-type-constraints-or-variable-types-6e3</link>
      <guid>https://dev.to/nandan_007/terraform-type-constraints-or-variable-types-6e3</guid>
      <description>&lt;p&gt;Day 7 of #30daysofawsterraform challenge&lt;/p&gt;

&lt;p&gt;Today I come across different types of variables in Terraform. &lt;/p&gt;

&lt;p&gt;$ What is variables in Terraform?&lt;br&gt;
    Variables in Terraform are like placeholders that store values, this makes your code reusable across environments (dev, staging, prod) and teams.&lt;/p&gt;

&lt;p&gt;$ Types:&lt;/p&gt;

&lt;p&gt;Basic Types:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;String - Text values
Eg:
variable "environment" {
  default = "dev"
  type = string&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Access using:&lt;br&gt;
    Environment = var.environment&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Number - Numeric values (integers and floats)
Eg:
variable "instance_count" {
  description = "Number of instances to create"
  type = number
}&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Access using:&lt;br&gt;
    count = var.instance_count&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Bool - Boolean values (true/false)&lt;br&gt;
Eg:&lt;br&gt;
variable "monitoring_enabled" {&lt;br&gt;
  description = "Enabled detailed monitoring for EC2 instance"&lt;br&gt;
  type = bool&lt;br&gt;
  default = true&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Access using:&lt;br&gt;
monitoring = var.monitoring_enabled&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Collection Types:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;List(type) - Ordered collection of values
Eg:
variable "cidr_block" {
  description = "CIDR block for VPC"
  type = list(string)
  default = ["10.0.0.0/8", "192.168.0.0/16", "172.16.0.0/12"]
}&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Access using:&lt;br&gt;
    cidr_ipv4         = var.cidr_block[2]&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Set(type) - &lt;br&gt;
Unordered collection of unique values&lt;br&gt;
Do not allow the duplicates&lt;br&gt;
It cannot access by their index - first convert it into list and then access the data.&lt;/p&gt;

&lt;p&gt;Eg:&lt;br&gt;
variable "allowed_region" {&lt;br&gt;
  description = "AWS list of allowed regions"&lt;br&gt;
  type = set(string)&lt;br&gt;
  default = ["us-east-1", "us-west-1", "us-west-2"]&lt;br&gt;
}&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Access using:&lt;br&gt;
    region = tolist(var.allowed_region)[0]&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Map(type) - Key-value pairs with string keys
Eg:
variable "tags" {
  type = map(string)
  default = {
    Environment = "dev"
    Name = "dev-EC2-instance"
  }
}&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Access using:&lt;br&gt;
    tags = var.tags&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Tuple([type1, type2, ...]) - Ordered collection with specific types for each element.
Eg:
variable "ingress_values" {
  type = tuple([number, string, number])
  default = [443, "tcp", 443]
}&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Access using:&lt;br&gt;
    from_port         = var.ingress_values[0]&lt;br&gt;
    ip_protocol       = var.ingress_values[1]&lt;br&gt;
    to_port           = var.ingress_values[2]&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Object({key1=type1, key2=type2, ...}) - Structured data with named attributes.&lt;br&gt;
Eg:&lt;br&gt;
variable "config" {&lt;br&gt;
  type = object({&lt;br&gt;
    region = string,&lt;br&gt;
    monitoring = bool,&lt;br&gt;
    instance_count = number&lt;br&gt;
  })&lt;/p&gt;

&lt;p&gt;default = {&lt;br&gt;
    region = "us-east-1",&lt;br&gt;
    monitoring = true,&lt;br&gt;
    instance_count = 1&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Access using:&lt;br&gt;
    region = var.config.region&lt;br&gt;
    monitoring = var.config.monitoring&lt;/p&gt;

&lt;h1&gt;
  
  
  Devops #Terraform #AWS
&lt;/h1&gt;

&lt;p&gt;Thanks to Piyush sachdeva The CloudOps Community&lt;/p&gt;

</description>
      <category>aws</category>
      <category>tutorial</category>
      <category>beginners</category>
      <category>terraform</category>
    </item>
  </channel>
</rss>
