<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Untitled Publication]]></title><description><![CDATA[Untitled Publication]]></description><link>https://shreyashsinghchauhan.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Mon, 12 Oct 2026 15:26:52 GMT</lastBuildDate><atom:link href="https://shreyashsinghchauhan.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How to Install SonarQube 9.9.2 LTS on an EC2 Instance Running Ubuntu]]></title><description><![CDATA[Introduction:
SonarQube is an effective tool for the continuous inspection of code quality. This step-by-step guide will provide detailed instructions on setting up SonarQube 9.9.2 LTS on an Amazon EC2 instance running Ubuntu. Upon completing this tu...]]></description><link>https://shreyashsinghchauhan.hashnode.dev/how-to-install-sonarqube-992-lts-on-an-ec2-instance-running-ubuntu</link><guid isPermaLink="true">https://shreyashsinghchauhan.hashnode.dev/how-to-install-sonarqube-992-lts-on-an-ec2-instance-running-ubuntu</guid><dc:creator><![CDATA[Chauhan Shreyash]]></dc:creator><pubDate>Sat, 18 Oct 2025 23:36:05 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1760829919114/cd9f0aee-b272-4ee0-9e53-d8932ab3a4b4.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-introduction"><strong>Introduction:</strong></h1>
<p>SonarQube is an effective tool for the continuous inspection of code quality. This step-by-step guide will provide detailed instructions on setting up SonarQube 9.9.2 LTS on an Amazon EC2 instance running Ubuntu. Upon completing this tutorial, you will have a fully operational SonarQube server to analyse your code quality.</p>
<h1 id="heading-prerequisites"><strong>Prerequisites:</strong></h1>
<p>Before you get started, make sure you have these things ready:</p>
<ul>
<li><p>An AWS account with an active EC2 instance.</p>
</li>
<li><p>A basic understanding of the Linux command line.</p>
</li>
<li><p>Internet access from your EC2 instance.</p>
</li>
</ul>
<h2 id="heading-step-1-create-and-connect-to-an-ec2-instance"><strong>Step 1: Create and Connect to an EC2 Instance</strong></h2>
<p>First up, you'll need to create and connect to an EC2 instance. If you're not sure how to do this, check out for a detailed guide. Once your EC2 instance is all set, you can move on to installing SonarQube.</p>
<h2 id="heading-step-2-update-ubuntu"><strong>Step 2: Update Ubuntu</strong></h2>
<p>After connecting to your EC2 instance, it's important to keep your system updated. Run these commands to refresh the package list and upgrade the installed packages:</p>
<pre><code class="lang-powershell">sudo apt update
sudo apt upgrade <span class="hljs-literal">-y</span>
</code></pre>
<p><strong>Step 3: Install Java 17</strong></p>
<p>SonarQube requires Java 17. Install it using the following command:</p>
<pre><code class="lang-powershell">sudo apt install fontconfig openjdk<span class="hljs-literal">-17</span><span class="hljs-literal">-jre</span> <span class="hljs-literal">-y</span>
</code></pre>
<p><strong>Step 4: Download SonarQube 9.9.2 LTS</strong></p>
<p>Download SonarQube 9.9.2 LTS and place it in the <code>/opt</code> directory. You can use the <code>wget</code> command to download the package:</p>
<pre><code class="lang-powershell">sudo <span class="hljs-built_in">wget</span> https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube<span class="hljs-literal">-9</span>.<span class="hljs-number">9.2</span>.<span class="hljs-number">77730</span>.zip <span class="hljs-literal">-P</span> /opt
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760830048804/0c7331ce-9795-4a0d-afb0-0223e1d8407e.png" alt class="image--center mx-auto" /></p>
<p><strong>Step 5: Add a User for SonarQube</strong></p>
<p>Create a user named "sonar" that will be used to run the SonarQube service:</p>
<pre><code class="lang-powershell">sudo useradd sonar
</code></pre>
<p><strong>Step 6: Install Unzip</strong></p>
<p>If unzip is not already installed, you can install it with the following command:</p>
<pre><code class="lang-powershell">sudo apt install unzip <span class="hljs-literal">-y</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760830117573/165d9d0a-6c15-45d8-9795-218f5ba63869.png" alt class="image--center mx-auto" /></p>
<p><strong>Step 7: Rename the Extracted Directory</strong></p>
<p>Unzip the SonarQube package and rename the extracted directory to "sonar":</p>
<pre><code class="lang-powershell">sudo unzip /opt/sonarqube<span class="hljs-literal">-9</span>.<span class="hljs-number">9.2</span>.<span class="hljs-number">77730</span>.zip <span class="hljs-literal">-d</span> /opt
sudo <span class="hljs-built_in">mv</span> /opt/sonarqube<span class="hljs-literal">-9</span>.<span class="hljs-number">9.2</span>.<span class="hljs-number">77730</span> /opt/sonar
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760830197839/001991d6-0da4-49f3-836c-9f95a50c371b.png" alt class="image--center mx-auto" /></p>
<p><strong>Step 8: Set Permissions for the Sonar Directory</strong></p>
<p>Give the "sonar" user ownership of the SonarQube directory:</p>
<pre><code class="lang-powershell">sudo chown <span class="hljs-literal">-R</span> sonar:sonar /opt/sonar
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760830298933/1edf8e57-c232-487b-a381-fe1e692d5370.png" alt class="image--center mx-auto" /></p>
<p><strong>Step 9: Add Sonar User to the sudoers File</strong></p>
<p>To allow the "sonar" user to execute commands without a password prompt, add the following line to the sudoers file:</p>
<pre><code class="lang-powershell">sudo vim /etc/sudoers
</code></pre>
<p>Add the following line under the "User privilege specification" section:</p>
<pre><code class="lang-powershell">sonar   ALL=(ALL:ALL) NOPASSWD:ALL
</code></pre>
<p>Save and exit the visudo editor.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760830371251/652529ad-b173-4099-8c77-5f45d236919a.png" alt class="image--center mx-auto" /></p>
<p><strong>Step 10: Write a Service for SonarQube</strong></p>
<p>Create a systemd service unit file for SonarQube. Create a file named <code>/etc/systemd/system/sonar.service</code></p>
<pre><code class="lang-powershell">sudo vim /etc/systemd/system/sonar.service
</code></pre>
<p>and add the following content:</p>
<pre><code class="lang-powershell">[<span class="hljs-type">Unit</span>]
Description=SonarQube service
After=network.target

[<span class="hljs-type">Service</span>]
<span class="hljs-built_in">Type</span>=forking
User=sonar
ExecStart=/opt/sonar/bin/linux<span class="hljs-literal">-x86</span><span class="hljs-literal">-64</span>/sonar.sh <span class="hljs-built_in">start</span>
ExecStop=/opt/sonar/bin/linux<span class="hljs-literal">-x86</span><span class="hljs-literal">-64</span>/sonar.sh stop
Restart=always
LimitNOFILE=<span class="hljs-number">65536</span>

[<span class="hljs-type">Install</span>]
WantedBy=multi<span class="hljs-literal">-user</span>.target
</code></pre>
<p><strong>Step 11: Start the SonarQube Service</strong></p>
<p>Start the SonarQube service using the following commands:</p>
<pre><code class="lang-powershell">sudo systemctl <span class="hljs-built_in">start</span> sonar
sudo systemctl enable sonar
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760830472263/32fc6486-0df0-4de9-8fb1-98d2a9fcf246.png" alt class="image--center mx-auto" /></p>
<p><strong>Step 12: Access SonarQube with the Public IP</strong></p>
<p>You can access your SonarQube server by opening a web browser and navigating to <a target="_blank" href="http://your-public-ip:9000/"><code>http://your-public-ip:9000</code></a>. Replace <code>your-public-ip</code> with the actual public IP address of your EC2 instance.</p>
<p><strong>Step 13: Log in to SonarQube</strong></p>
<p>Log in to SonarQube using the default username and Password "admin".</p>
<p>Congratulations! You have successfully set up SonarQube 9.9.2 LTS on your EC2 instance. You can now use it to analyze the quality of your code and improve your software development process.</p>
]]></content:encoded></item><item><title><![CDATA[🧱 End-to-End Three-Tier Architecture Deployment on AWS EKS — Stan’s Robot Shop]]></title><description><![CDATA[❄️Introduction.
If you’ve ever wanted to see how a real-world microservices-based e-commerce app runs inside Kubernetes, Stan’s Robot Shop is the perfect project to explore.It’s a sample application designed for learning — a playground where you can ...]]></description><link>https://shreyashsinghchauhan.hashnode.dev/end-to-end-three-tier-architecture-deployment-on-aws-eks-stans-robot-shop</link><guid isPermaLink="true">https://shreyashsinghchauhan.hashnode.dev/end-to-end-three-tier-architecture-deployment-on-aws-eks-stans-robot-shop</guid><dc:creator><![CDATA[Chauhan Shreyash]]></dc:creator><pubDate>Thu, 16 Oct 2025 09:03:48 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1760610852512/f05a14d0-5bcb-4ba7-97d4-26e77adde0aa.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-introduction"><strong>❄️Introduction.</strong></h1>
<p>If you’ve ever wanted to see how a real-world microservices-based e-commerce app runs inside Kubernetes, <em>Stan’s Robot Shop</em> is the perfect project to explore.<br />It’s a sample application designed for learning — a playground where you can deploy multiple services, connect databases, monitor everything, and actually see how cloud-native systems behave.</p>
<p>This project isn’t meant to be production-ready or secure — and that’s okay. It’s intentionally simple, so you can focus on understanding how things fit together: how microservices communicate with each other, how monitoring tools capture data, and how AWS EKS manages everything under the hood.So let’s get started.</p>
<h1 id="heading-whats-inside-stans-robot-shop">🧩 What’s Inside Stan’s Robot Shop</h1>
<p>Stan’s Robot Shop is built using a mix of technologies that represent what you’d find in a modern e-commerce platform. Each microservice is written in a different language to show how diverse systems can work together inside containers.</p>
<p>Here’s what it includes:</p>
<ul>
<li><p><strong>Frontend:</strong> AngularJS (1.x) served using <strong>Nginx</strong></p>
</li>
<li><p><strong>Backend Services:</strong></p>
<ul>
<li><p><strong>Node.js (Express)</strong> — handles parts of the shop’s logic</p>
</li>
<li><p><strong>Java (Spring Boot)</strong> — manages key backend services</p>
</li>
<li><p><strong>Python (Flask)</strong> — supports some lightweight microservices</p>
</li>
<li><p><strong>Golang</strong> — for performance-oriented modules</p>
</li>
<li><p><strong>PHP (Apache)</strong> — for older service components</p>
</li>
</ul>
</li>
<li><p><strong>Databases:</strong></p>
<ul>
<li><p><strong>MongoDB</strong> — stores product and user data</p>
</li>
<li><p><strong>MySQL</strong> — used for structured data (includes Maxmind data)</p>
</li>
</ul>
</li>
<li><p><strong>Messaging &amp; Cache:</strong></p>
<ul>
<li><p><strong>RabbitMQ</strong> — handles asynchronous communication</p>
</li>
<li><p><strong>Redis</strong> — for caching</p>
</li>
</ul>
</li>
<li><p><strong>Monitoring:</strong></p>
<ul>
<li>Integrated <strong>Instana agents</strong> for full end-to-end tracing and metrics</li>
</ul>
</li>
</ul>
<p>Every service already comes pre-configured with monitoring and tracing — so when you deploy it, you can instantly visualise requests, database queries, and performance metrics across all layers.</p>
<h1 id="heading-architecture-overview-the-three-tiers">🏗️ Architecture Overview — The Three Tiers</h1>
<p>Stan’s Robot Shop follows the classic <strong>three-tier architecture</strong>, broken into:</p>
<ol>
<li><p><strong>Presentation Layer (Frontend):</strong></p>
<ul>
<li><p>The AngularJS UI served through Nginx.</p>
</li>
<li><p>It’s what customers see when they visit the robot shop website.</p>
</li>
</ul>
</li>
<li><p><strong>Application Layer (Backend Services):</strong></p>
<ul>
<li><p>The core logic of the shop — all the Node.js, Java, Python, Go, and PHP services live here.</p>
</li>
<li><p>This layer manages products, orders, users, and payment flows.</p>
</li>
</ul>
</li>
<li><p><strong>Data Layer (Databases &amp; Cache):</strong></p>
<ul>
<li><p>Uses MySQL and MongoDB for persistent data storage.</p>
</li>
<li><p>Redis is used for caching frequently accessed data to improve performance.</p>
</li>
</ul>
</li>
</ol>
<p>All these components run as <strong>individual pods</strong> inside an <strong>AWS EKS cluster</strong>, communicating internally using <strong>Kubernetes Services</strong>.<br />An <strong>Ingress Controller</strong> (like NGINX or AWS ALB) exposes the frontend to users over the internet, while internal services stay private.</p>
<h1 id="heading-prerequisites">📌 Prerequisites</h1>
<h4 id="heading-before-performing-this-project-you-need-to-install-these-commands-on-you-terminal">Before performing this project, you need to install these commands on you terminal :</h4>
<h5 id="heading-kubectl">kubectl</h5>
<p>A command-line tool for working with Kubernetes clusters. For more information, see Installing or updating kubectl.</p>
<p>LINK : <a target="_blank" href="https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html">https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html</a></p>
<h5 id="heading-eksctlhttpsdocsawsamazoncomekslatestuserguideinstall-kubectlhtml"><a target="_blank" href="https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html">eksctl</a></h5>
<p>A command-line tool for working with EKS clusters that automates many individual tasks. For more information, see Installing or updating.</p>
<p>LINK : <a target="_blank" href="https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html">https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html</a></p>
<h5 id="heading-aws-clihttpsdocsawsamazoncomekslatestuserguideinstall-kubectlhtml"><a target="_blank" href="https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html">AWS CLI</a></h5>
<p>A command-line tool for working with AWS services, including Amazon EKS. For more information, see Installing, updating, and uninstalling the AWS CLI in the AWS Command Line Interface User Guide. After installing the AWS CLI, we recommend that you also configure it. For more information, see Quick configuration with aws configure in the AWS Command Line Interface User Guide.</p>
<p>LINK: <a target="_blank" href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html">https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html</a></p>
<h5 id="heading-once-you-have-installed-these-commands-on-your-terminal-then-do">Once you have installed these commands on your Terminal, then do</h5>
<pre><code class="lang-bash">aws configure
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760464943311/203fc38b-69ee-4b05-90cc-df342fa080d0.png" alt class="image--center mx-auto" /></p>
<p>You can get your AWS access and secret access key, just sign in to your AWS Account and go to <strong>Security credentials</strong> → <strong>Access keys</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760465048377/baf1fc22-fcfc-47e7-91ef-3d25028b9d98.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760465073291/400551a9-fdf4-4b8b-bfec-4a8568f4abf4.png" alt class="image--center mx-auto" /></p>
<p>Just copy the things from here and paste them over there.</p>
<p>Why AWS configure ??!!</p>
<p>The aws configure command helps you set up your AWS CLI by entering your credentials, choosing a default region, and picking how you want your AWS service results displayed.</p>
<h1 id="heading-docker-setup-for-microservices">📌 Docker Setup for Microservices</h1>
<p>In this project, each microservice has its <strong>own Dockerfile</strong>, customised for its language and runtime. Instead of showing all 10 Dockerfiles (which might make the blog a bit too much), we'll highlight <strong>one example Dockerfile</strong> and provide a <strong>quick summary table</strong> for the others.</p>
<p>This way, the blog stays <strong>neat, professional, and easy to follow</strong>, while still showing off your technical skills.</p>
<hr />
<h3 id="heading-example-dockerfile-cart-microservice-nodejs">Example Dockerfile — <strong>Cart Microservice (Node.js)</strong></h3>
<pre><code class="lang-dockerfile"><span class="hljs-keyword">FROM</span> node:<span class="hljs-number">14</span>

<span class="hljs-comment"># Enable Instana auto-profiling for monitoring</span>
<span class="hljs-keyword">ENV</span> INSTANA_AUTO_PROFILE true

<span class="hljs-comment"># Set working directory</span>
<span class="hljs-keyword">WORKDIR</span><span class="bash"> /opt/server</span>

<span class="hljs-comment"># Copy package.json and install dependencies</span>
<span class="hljs-keyword">COPY</span><span class="bash"> package.json /opt/server/</span>
<span class="hljs-keyword">RUN</span><span class="bash"> npm install</span>

<span class="hljs-comment"># Copy service code</span>
<span class="hljs-keyword">COPY</span><span class="bash"> server.js /opt/server/</span>

<span class="hljs-comment"># Expose service port</span>
<span class="hljs-keyword">EXPOSE</span> <span class="hljs-number">8080</span>

<span class="hljs-comment"># Start the service</span>
<span class="hljs-keyword">CMD</span><span class="bash"> [<span class="hljs-string">"node"</span>, <span class="hljs-string">"server.js"</span>]</span>
</code></pre>
<blockquote>
<p>💡 Note: Other microservices follow a similar structure, adjusted for their runtime (Node.js, Python, Go, Java, PHP) and dependencies.</p>
</blockquote>
<hr />
<h3 id="heading-overview-of-all-10-microservices">Overview of All 10 Microservices</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Microservice</td><td>Language / Runtime</td><td>Base Image</td><td>Port</td><td>Notes</td></tr>
</thead>
<tbody>
<tr>
<td>Cart</td><td>Node.js</td><td>node:14</td><td>8080</td><td>Example microservice</td></tr>
<tr>
<td>Catalogue</td><td>Node.js</td><td>node:14</td><td>8080</td><td>Similar setup</td></tr>
<tr>
<td>Dispatch</td><td>Go</td><td>golang:1.17</td><td>8080</td><td>Port assumed standard, not explicitly exposed</td></tr>
<tr>
<td>Loadgen</td><td>Python</td><td>python:3.9</td><td>N/A</td><td>Load testing script, does not serve traffic</td></tr>
<tr>
<td>Payment</td><td>Python</td><td>python:3.9</td><td>8080</td><td>uWSGI + payment logic</td></tr>
<tr>
<td>Shipping</td><td>Java</td><td>openjdk:8</td><td>8080</td><td>Built with Maven</td></tr>
<tr>
<td>User</td><td>Node.js</td><td>node:14</td><td>8080</td><td>Microservice logic</td></tr>
<tr>
<td>Ratings</td><td>Node.js</td><td>node:14</td><td>8080</td><td>Microservice logic</td></tr>
<tr>
<td>MongoDB</td><td>Database</td><td>mongo:5</td><td>27017</td><td>Pre-loaded scripts</td></tr>
<tr>
<td>MySQL</td><td>Database</td><td>mysql:5.7</td><td>3306</td><td>Pre-configured DB</td></tr>
</tbody>
</table>
</div><hr />
<h3 id="heading-full-dockerfiles">Full Dockerfiles</h3>
<p>For all <strong>complete Dockerfiles of every microservice</strong>, you can explore the GitHub repo:</p>
<p><a target="_blank" href="https://github.com/shreyash81/three-tier-architecture-demo-project.git">three-tier-architecture-demo-project</a></p>
<h1 id="heading-kubernetes-amp-eks-setup-for-microservices-deployment">☸️ Kubernetes &amp; EKS Setup for Microservices Deployment</h1>
<h2 id="heading-setting-up-the-cluster">📌 Setting up the cluster</h2>
<p>You can create your cluster through the AWS Console, but here we are creating the cluster through CLI.</p>
<pre><code class="lang-bash">eksctl create cluster --name demo-cluster-app1 --region ap-south-1
</code></pre>
<p>Here, --region will be your region.</p>
<p>It will take some time to create ............</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760610466666/76d72675-a55e-4a6c-82af-e146fd107f37.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760610548239/671ec8c0-0551-4814-b9b7-9e6881e92577.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-kubernetes-deployment-and-service-setup-using-helm">🧩 Kubernetes Deployment and Service Setup (Using Helm)</h2>
<p>After setting up the EKS cluster, I deployed all my microservices (like <code>cart</code>, <code>user</code>, <code>payment</code>, etc.) using <strong>Helm charts</strong>.<br />Helm made it easier to manage all my Kubernetes YAML files for deployment, service, and ingress.</p>
<p>Below is one simple example for the <strong>Cart microservice</strong> 👇</p>
<h4 id="heading-deployment-example-cart">🏗️ Deployment (Example: Cart)</h4>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">apps/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Deployment</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">cart</span>
  <span class="hljs-attr">labels:</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">cart</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">replicas:</span> <span class="hljs-number">1</span>
  <span class="hljs-attr">selector:</span>
    <span class="hljs-attr">matchLabels:</span>
      <span class="hljs-attr">service:</span> <span class="hljs-string">cart</span>
  <span class="hljs-attr">template:</span>
    <span class="hljs-attr">metadata:</span>
      <span class="hljs-attr">labels:</span>
        <span class="hljs-attr">service:</span> <span class="hljs-string">cart</span>
    <span class="hljs-attr">spec:</span>
      {{ <span class="hljs-string">if</span> <span class="hljs-string">.Values.psp.enabled</span> }}
      <span class="hljs-attr">serviceAccountName:</span> <span class="hljs-string">robot-shop</span>
      {{ <span class="hljs-string">end</span> }}
      <span class="hljs-attr">containers:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">cart</span>
        <span class="hljs-attr">image:</span> {{ <span class="hljs-string">.Values.image.repo</span> }}<span class="hljs-string">/rs-cart:{{</span> <span class="hljs-string">.Values.image.version</span> <span class="hljs-string">}}</span>
        <span class="hljs-attr">imagePullPolicy:</span> {{ <span class="hljs-string">.Values.image.pullPolicy</span> }}
        <span class="hljs-comment"># agent networking access</span>
        <span class="hljs-attr">env:</span>
          <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">INSTANA_AGENT_HOST</span>
            <span class="hljs-attr">valueFrom:</span>
              <span class="hljs-attr">fieldRef:</span>
                <span class="hljs-attr">fieldPath:</span> <span class="hljs-string">status.hostIP</span>
        <span class="hljs-attr">ports:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">containerPort:</span> <span class="hljs-number">8080</span>
        <span class="hljs-attr">resources:</span>
          <span class="hljs-attr">limits:</span>
            <span class="hljs-attr">cpu:</span> <span class="hljs-string">200m</span>
            <span class="hljs-attr">memory:</span> <span class="hljs-string">100Mi</span>
          <span class="hljs-attr">requests:</span>
            <span class="hljs-attr">cpu:</span> <span class="hljs-string">100m</span>
            <span class="hljs-attr">memory:</span> <span class="hljs-string">50Mi</span>
      {{<span class="hljs-bullet">-</span> <span class="hljs-string">with</span> <span class="hljs-string">.Values.cart.affinity</span> }}
      <span class="hljs-attr">affinity:</span>
        {{<span class="hljs-bullet">-</span> <span class="hljs-string">toYaml</span> <span class="hljs-string">.</span> <span class="hljs-string">|</span> <span class="hljs-string">nindent</span> <span class="hljs-number">8</span> }}
      {{<span class="hljs-bullet">-</span> <span class="hljs-string">end</span> }}
      {{<span class="hljs-bullet">-</span> <span class="hljs-string">with</span> <span class="hljs-string">.Values.cart.nodeSelector</span> }}
      <span class="hljs-attr">nodeSelector:</span>
        {{<span class="hljs-bullet">-</span> <span class="hljs-string">toYaml</span> <span class="hljs-string">.</span> <span class="hljs-string">|</span> <span class="hljs-string">nindent</span> <span class="hljs-number">8</span> }}
      {{<span class="hljs-bullet">-</span> <span class="hljs-string">end</span> }}
      {{<span class="hljs-bullet">-</span> <span class="hljs-string">with</span> <span class="hljs-string">.Values.cart.tolerations</span> }}
      <span class="hljs-attr">tolerations:</span>
        {{<span class="hljs-bullet">-</span> <span class="hljs-string">toYaml</span> <span class="hljs-string">.</span> <span class="hljs-string">|</span> <span class="hljs-string">nindent</span> <span class="hljs-number">8</span> }}
      {{<span class="hljs-bullet">-</span> <span class="hljs-string">end</span> }}
</code></pre>
<hr />
<h4 id="heading-service-example-cart">🌐 Service (Example: Cart)</h4>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Service</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">cart</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">ports:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">http</span>
    <span class="hljs-attr">port:</span> <span class="hljs-number">8080</span>
    <span class="hljs-attr">targetPort:</span> <span class="hljs-number">8080</span>
  <span class="hljs-attr">selector:</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">cart</span>
</code></pre>
<p>👉 <strong>Meaning:</strong><br />This service exposes the Cart pod inside the cluster so that other microservices can communicate with it.</p>
<h4 id="heading-ingress-for-robot-shop-on-eks">🌐 Ingress for Robot Shop on EKS</h4>
<p>Ingress allows external traffic to reach your services in Kubernetes. For AWS EKS, we can use <strong>ALB (Application Load Balancer) Ingress</strong>.</p>
<h5 id="heading-alb-ingress-yaml">🏗️ ALB Ingress YAML</h5>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">networking.k8s.io/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Ingress</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">namespace:</span> <span class="hljs-string">robot-shop</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">robot-shop</span>
  <span class="hljs-attr">annotations:</span>
    <span class="hljs-attr">alb.ingress.kubernetes.io/scheme:</span> <span class="hljs-string">internet-facing</span>   <span class="hljs-comment"># Public-facing ALB</span>
    <span class="hljs-attr">alb.ingress.kubernetes.io/target-type:</span> <span class="hljs-string">ip</span>          <span class="hljs-comment"># Targets pods by IP</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">ingressClassName:</span> <span class="hljs-string">alb</span>
  <span class="hljs-attr">rules:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">http:</span>
        <span class="hljs-attr">paths:</span>
          <span class="hljs-bullet">-</span> <span class="hljs-attr">path:</span> <span class="hljs-string">/</span>                                     <span class="hljs-comment"># All requests to "/" path</span>
            <span class="hljs-attr">pathType:</span> <span class="hljs-string">Prefix</span>
            <span class="hljs-attr">backend:</span>
              <span class="hljs-attr">service:</span>
                <span class="hljs-attr">name:</span> <span class="hljs-string">web</span>                               <span class="hljs-comment"># Routes to 'web' service</span>
                <span class="hljs-attr">port:</span>
                  <span class="hljs-attr">number:</span> <span class="hljs-number">8080</span>
</code></pre>
<ul>
<li><p><a target="_blank" href="http://alb.ingress.kubernetes.io/scheme"><code>alb.ingress.kubernetes.io/scheme</code></a><code>: internet-facing</code> → Makes the ALB public-facing so it can be accessed from the internet.</p>
</li>
<li><p><a target="_blank" href="http://alb.ingress.kubernetes.io/target-type"><code>alb.ingress.kubernetes.io/target-type</code></a><code>: ip</code> → Targets the IPs of the pods.</p>
</li>
<li><p><code>ingressClassName: alb</code> → Specifies that this uses ALB Ingress.</p>
</li>
<li><p><a target="_blank" href="http://service.name"><code>service.name</code></a><code>: web</code> → Specifies that it routes to the pods of the web service.</p>
</li>
<li><p><code>path: /</code> → All requests will be forwarded to the root path.</p>
</li>
</ul>
<h2 id="heading-helm-charts-for-microservices-deployment">⚙️ Helm Charts for Microservices Deployment</h2>
<p>I used Helm to organise all the deployments and services neatly.<br />My Helm chart structure looks like this 👇</p>
<pre><code class="lang-bash">three-tier-architecture-demo-project/
 ├── EKS/helm/
 ├── Chart.yaml         <span class="hljs-comment"># Chart metadata (name, version, description)</span>
 ├── values.yaml        <span class="hljs-comment"># Default values for images, replicas, ports, affinity, etc.</span>
 └── templates/         <span class="hljs-comment"># Kubernetes manifests templates</span>
      ├── cart-deployment.yaml
      ├── cart-service.yaml
      ├── user-deployment.yaml
      ├── user-service.yaml
      ├── payment-deployment.yaml
      ├── payment-service.yaml
      └── ...           <span class="hljs-comment"># similar for all other microservices</span>
</code></pre>
<ul>
<li><p><strong>Chart.yaml</strong> – Defines the chart’s metadata, like name and version.</p>
</li>
<li><p><strong>values.yaml</strong> – Holds configurable parameters like Docker image name, version, replicas, ports, affinity, and tolerations.</p>
</li>
<li><p><strong>templates/</strong> – Contains all deployment, service, ingress, and other Kubernetes manifest templates.</p>
</li>
</ul>
<h3 id="heading-full-code-on-github">🔗 Full Code on GitHub</h3>
<p>You can check the complete Helm chart and all microservices’ Kubernetes manifests on my GitHub repository here:<br />👉 <a target="_blank" href="https://github.com/shreyash81/three-tier-architecture-demo-project"><strong>GitHub Repository – three-tier-architecture-demo-project</strong></a></p>
<h1 id="heading-configure-iam-oidc-provider">📌 <strong>Configure IAM OIDC provider</strong></h1>
<p>We use <strong>OIDC (OpenID Connect)</strong> in our EKS cluster to allow Kubernetes pods to <strong>securely access AWS resources</strong> without storing AWS credentials inside the containers.</p>
<p>In this project, <strong>Redis</strong> requires a <strong>persistent volume</strong> on AWS (EBS) to store its data. By using OIDC:</p>
<ul>
<li><p>The Redis pod can <strong>assume an IAM role</strong> with permissions to access EBS.</p>
</li>
<li><p>This ensures <strong>secure, scoped, and managed access</strong> to the persistent storage.</p>
</li>
<li><p>No AWS keys are hardcoded in the pods, making the setup <strong>safe and maintainable</strong>.</p>
</li>
</ul>
<p>✅ <strong>In short:</strong> OIDC lets Redis pods access EBS securely and efficiently.</p>
<p>Now Commands to configure IAM OIDC provider</p>
<pre><code class="lang-bash"><span class="hljs-built_in">export</span> cluster_name=&lt;CLUSTER-NAME&gt;
</code></pre>
<pre><code class="lang-bash">oidc_id=$(aws eks describe-cluster --name <span class="hljs-variable">$cluster_name</span> --query <span class="hljs-string">"cluster.identity.oidc.issuer"</span> --output text | cut -d <span class="hljs-string">'/'</span> -f 5)
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760606688893/b85f6278-7dfe-4ce0-9b72-41b666d4b5df.png" alt class="image--center mx-auto" /></p>
<p>Check whether the IAM OIDC is already configured or not :</p>
<pre><code class="lang-bash">aws iam list-open-id-connect-providers | grep <span class="hljs-variable">$oidc_id</span> | cut -d <span class="hljs-string">"/"</span> -f4
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760606703659/bca55ff3-990e-449f-891c-eefe9eb66ed2.png" alt class="image--center mx-auto" /></p>
<p>If not, run the below command</p>
<pre><code class="lang-bash">eksctl utils associate-iam-oidc-provider --cluster <span class="hljs-variable">$cluster_name</span> --approve
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760606758627/b3671a11-d96d-4834-b889-d761b60e401e.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-installation-of-alb-controller-using-helm-chart"><strong>📌Installation of ALB-CONTROLLER using helm-chart</strong></h1>
<p>Before creating the alb-controller, you have to do these steps so that your alb-controller, which is running as a pod in the kube-system namespace in Kubernetes that can talk to AWS services to create an alb-load-balancer.</p>
<h2 id="heading-set-up-alb-add-on"><strong>✔️Set up alb add-on</strong></h2>
<p>Download IAM policy</p>
<pre><code class="lang-powershell"><span class="hljs-built_in">curl</span> <span class="hljs-literal">-O</span> https://raw.githubusercontent.com/kubernetes<span class="hljs-literal">-sigs</span>/aws<span class="hljs-literal">-load</span><span class="hljs-literal">-balancer</span><span class="hljs-literal">-controller</span>/v2.<span class="hljs-number">5.4</span>/docs/install/iam_policy.json
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760607198281/810310f9-343c-4c38-96db-4fc327660b39.png" alt class="image--center mx-auto" /></p>
<p>Create IAM Policy</p>
<pre><code class="lang-powershell">aws iam create<span class="hljs-literal">-policy</span> \
    -<span class="hljs-literal">-policy</span><span class="hljs-literal">-name</span> AWSLoadBalancerControllerIAMPolicy \
    -<span class="hljs-literal">-policy</span><span class="hljs-literal">-document</span> file://iam_policy.json
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760607224526/d5b32bb6-d46c-47dd-93b9-e6dcf6c58f0a.png" alt class="image--center mx-auto" /></p>
<p>Here, you will error, but this is not any type of error, this is saying that your policy already exists, that’s why this is showing, because I have done this many times before.</p>
<p>Create IAM Role</p>
<pre><code class="lang-powershell">eksctl create iamserviceaccount \
  -<span class="hljs-literal">-cluster</span>=&lt;your<span class="hljs-literal">-cluster</span><span class="hljs-literal">-name</span>&gt; \
  -<span class="hljs-literal">-namespace</span>=kube<span class="hljs-literal">-system</span> \
  -<span class="hljs-literal">-name</span>=aws<span class="hljs-literal">-load</span><span class="hljs-literal">-balancer</span><span class="hljs-literal">-controller</span> \
  -<span class="hljs-literal">-role</span><span class="hljs-literal">-name</span> AmazonEKSLoadBalancerControllerRole \
  -<span class="hljs-literal">-attach</span><span class="hljs-literal">-policy</span><span class="hljs-literal">-arn</span>=arn:aws:iam::&lt;your<span class="hljs-literal">-aws</span><span class="hljs-literal">-account</span><span class="hljs-literal">-id</span>&gt;: policy/AWSLoadBalancerControllerIAMPolicy \
  -<span class="hljs-literal">-approve</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760607377968/1bfc2732-9fe7-45b8-bb21-584c72f277ca.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-deploy-alb-controller"><strong>✔️Deploy ALB controller</strong></h2>
<p>Add helm repo</p>
<pre><code class="lang-powershell">helm repo add eks https://aws.github.io/eks<span class="hljs-literal">-charts</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760607478913/e7fbdc69-da33-48e1-b53f-0b2b566e5830.png" alt class="image--center mx-auto" /></p>
<p>Update the repo</p>
<pre><code class="lang-bash">helm repo update eks
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760607502398/44fd5191-aeaa-4fd8-848c-eecdba02f792.png" alt class="image--center mx-auto" /></p>
<p>Install</p>
<pre><code class="lang-powershell">helm install aws<span class="hljs-literal">-load</span><span class="hljs-literal">-balancer</span><span class="hljs-literal">-controller</span> eks/aws<span class="hljs-literal">-load</span><span class="hljs-literal">-balancer</span><span class="hljs-literal">-controller</span> \            
  <span class="hljs-literal">-n</span> kube<span class="hljs-literal">-system</span> \
  -<span class="hljs-literal">-set</span> clusterName=&lt;your<span class="hljs-literal">-cluster</span><span class="hljs-literal">-name</span>&gt; \
  -<span class="hljs-literal">-set</span> serviceAccount.create=false \
  -<span class="hljs-literal">-set</span> serviceAccount.name=aws<span class="hljs-literal">-load</span><span class="hljs-literal">-balancer</span><span class="hljs-literal">-controller</span> \
  -<span class="hljs-literal">-set</span> region=&lt;region&gt; \
  -<span class="hljs-literal">-set</span> vpcId=&lt;your<span class="hljs-literal">-vpc</span><span class="hljs-literal">-id</span>&gt;
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760607550761/5c6b8c89-bcf3-4922-83be-4057e284341a.png" alt class="image--center mx-auto" /></p>
<p>Verify that the deployments are running.</p>
<pre><code class="lang-powershell">kubectl get deployment <span class="hljs-literal">-n</span> kube<span class="hljs-literal">-system</span> aws<span class="hljs-literal">-load</span><span class="hljs-literal">-balancer</span><span class="hljs-literal">-controller</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760607569907/098a7219-c03d-45f4-9c79-d225f6f611b0.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-ebs-csi-plugin-configuration">📌<strong>EBS CSI Plugin configuration</strong></h1>
<p>The Amazon EBS CSI plugin requires IAM permissions to make calls to AWS APIs on your behalf.</p>
<p>Create an IAM role and attach a policy. AWS maintains an AWS-managed policy or you can create your own custom policy. You can create an IAM role and attach the AWS managed policy with the following command. Replace my-cluster with the name of your cluster. The command deploys an AWS CloudFormation stack that creates an IAM role and attaches the IAM policy to it.</p>
<pre><code class="lang-powershell">eksctl create iamserviceaccount \
    -<span class="hljs-literal">-name</span> ebs<span class="hljs-literal">-csi</span><span class="hljs-literal">-controller</span><span class="hljs-literal">-sa</span> \
    -<span class="hljs-literal">-namespace</span> kube<span class="hljs-literal">-system</span> \
    -<span class="hljs-literal">-cluster</span> &lt;YOUR<span class="hljs-literal">-CLUSTER</span><span class="hljs-literal">-NAME</span>&gt; \
    -<span class="hljs-literal">-role</span><span class="hljs-literal">-name</span> AmazonEKS_EBS_CSI_DriverRole \
    -<span class="hljs-literal">-role</span><span class="hljs-literal">-only</span> \
    -<span class="hljs-literal">-attach</span><span class="hljs-literal">-policy</span><span class="hljs-literal">-arn</span> arn:aws:iam::aws:policy/service<span class="hljs-literal">-role</span>/AmazonEBSCSIDriverPolicy \
    -<span class="hljs-literal">-approve</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760607703004/b7548370-f197-43f7-8438-0ccf6746529d.png" alt class="image--center mx-auto" /></p>
<p>Run the following command. Replace with the name of your cluster with your account ID.</p>
<pre><code class="lang-powershell">eksctl create addon -<span class="hljs-literal">-name</span> aws<span class="hljs-literal">-ebs</span><span class="hljs-literal">-csi</span><span class="hljs-literal">-driver</span> -<span class="hljs-literal">-cluster</span> &lt;YOUR<span class="hljs-literal">-CLUSTER</span><span class="hljs-literal">-NAME</span>&gt; -<span class="hljs-literal">-service</span><span class="hljs-literal">-account</span><span class="hljs-literal">-role</span><span class="hljs-literal">-arn</span> arn:aws:iam::&lt;AWS<span class="hljs-literal">-ACCOUNT</span><span class="hljs-literal">-ID</span>&gt;:role/AmazonEKS_EBS_CSI_DriverRole -<span class="hljs-literal">-force</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760607723699/79c86853-7f8c-42bf-a3b0-7b15d2f14653.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-clone-the-github-repo-amp-deploy-all-microservices-using-helm">🚀 Clone the GitHub Repo &amp; Deploy All Microservices Using Helm</h1>
<p>First, clone the project repository to your local machine. Then, using Helm, you can deploy <strong>all microservices, their deployment, and their services</strong> to your Kubernetes cluster in one go. This makes deployment simple, organised, and reproducible.</p>
<h2 id="heading-git-clonning">✔️Git Clonning</h2>
<pre><code class="lang-powershell"><span class="hljs-built_in">pwd</span>
git clone https://github.com/shreyash81/three<span class="hljs-literal">-tier</span><span class="hljs-literal">-architecture</span><span class="hljs-literal">-demo</span><span class="hljs-literal">-project</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760608240560/1dcd4083-8c61-4241-a6e1-f4bc5796de53.png" alt class="image--center mx-auto" /></p>
<p>Now, after cloning, go to your repo and after go to where your helm chart is located</p>
<pre><code class="lang-powershell"><span class="hljs-comment">#Follow these commands to reach your destination</span>
<span class="hljs-built_in">cd</span> <span class="hljs-comment">#your repo name</span>
<span class="hljs-built_in">ls</span> <span class="hljs-comment">#this command will show all the files and folders in your repo.</span>
<span class="hljs-built_in">cd</span> EKS
<span class="hljs-built_in">ls</span> <span class="hljs-comment"># This command will show all the files and folders in your EKS repo.</span>
<span class="hljs-built_in">cd</span> helm
<span class="hljs-built_in">ls</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760608375629/2e440591-68a1-4fc8-9170-1af2c1a0789e.png" alt class="image--center mx-auto" /></p>
<p>Now you have finally reached the destination.</p>
<h2 id="heading-deploy-all-microservices-using-helm">✔️Deploy All Microservices Using Helm</h2>
<h3 id="heading-helm-v3x"><strong>Helm v3.x</strong></h3>
<pre><code class="lang-powershell">kubectl create ns robot<span class="hljs-literal">-shop</span>
helm install robot<span class="hljs-literal">-shop</span> -<span class="hljs-literal">-namespace</span> robot<span class="hljs-literal">-shop</span> .
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760608887806/e466ab92-c270-438b-916a-ab4f171ddc8f.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-now-check-if-all-the-microservices-are-properly-deployed-or-not">☑️Now check if all the microservices are properly deployed or not</h3>
<p>Here, we will write some Kubernetes commands to check that all our pods and services all properly running or not :</p>
<pre><code class="lang-powershell">kubectl get pods <span class="hljs-literal">-n</span> robot<span class="hljs-literal">-shop</span>

<span class="hljs-comment">#You can check the services also </span>

kubectl get svc <span class="hljs-literal">-n</span> robot<span class="hljs-literal">-shop</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760609194982/848e8e65-13f8-4d5b-93e5-8b32d31f89b2.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-apply-ingress-manually">🌐 Apply Ingress Manually</h1>
<p>After deploying all microservices and services, you can expose your application to the outside world using <strong>Ingress</strong>.</p>
<h3 id="heading-steps">Steps:👇</h3>
<ol>
<li>Go to your Kubernetes manifests folder (where the ingress YAML is):</li>
</ol>
<pre><code class="lang-powershell"><span class="hljs-built_in">cd</span> three<span class="hljs-literal">-tier</span><span class="hljs-literal">-architecture</span><span class="hljs-literal">-demo</span><span class="hljs-literal">-project</span>/EKS/helm
</code></pre>
<ol start="2">
<li>Apply the ingress YAML file manually:</li>
</ol>
<pre><code class="lang-powershell">kubectl apply <span class="hljs-operator">-f</span> ingress.yaml <span class="hljs-literal">-n</span> robot<span class="hljs-literal">-shop</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760609387108/65301467-4d14-4e4c-95b1-392921e22175.png" alt class="image--center mx-auto" /></p>
<ol start="3">
<li>Verify the ingress:</li>
</ol>
<pre><code class="lang-powershell">kubectl get ingress <span class="hljs-literal">-n</span> robot<span class="hljs-literal">-shop</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760609408979/3afeac25-60e2-46c0-ab67-e081f366872e.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-get-the-dns-from-load-balancer">🌐 Get the DNS from Load Balancer</h1>
<p>After applying the <strong>Ingress</strong>, AWS will automatically create an <strong>Application Load Balancer (ALB)</strong> to route traffic to your services. To access your application, you need the DNS name of the ALB.</p>
<p>Go to your AWS account in the load balancer section and wait for a few minutes till it becomes active from provisioning state.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760609673648/0aec1337-3b5e-406b-bc0b-847be9372106.png" alt class="image--center mx-auto" /></p>
<p>Now, here, copy the DNS name and paste it into your favourite browser</p>
<h1 id="heading-application-live-and-running">🎉 Application Live and Running!</h1>
<p>You can now access the Robot Shop application in your browser using the following DNS that you have just copied:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760610088994/050a8ac4-ded7-4592-92b0-9679ae0ca842.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760610110170/031b13fd-f8c3-43fc-9bd5-7c868bd7feb1.png" alt class="image--center mx-auto" /></p>
<p>Congratulations🥂, you have finally done this project.</p>
<h1 id="heading-cleanup-deleting-the-eks-cluster">🧹 Cleanup: Deleting the EKS Cluster</h1>
<p>Once you are done testing your Robot Shop application, it’s important to clean up resources to avoid unnecessary AWS charges. Here’s how you can delete your EKS cluster and related resources:</p>
<pre><code class="lang-powershell">
eksctl delete cluster -<span class="hljs-literal">-name</span> demo<span class="hljs-literal">-cluster</span><span class="hljs-literal">-app1</span> -<span class="hljs-literal">-region</span> ap<span class="hljs-literal">-south</span><span class="hljs-literal">-1</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760610394542/29eb412f-a752-477b-842d-1dcab9e4cd85.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760610410209/5f4a71a4-906a-4fc5-9a8d-a87ad6c9953f.png" alt class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[Aws-cost-optimization-project]]></title><description><![CDATA[Table of Contents
⭐️Introduction
In this project, we aim to optimise AWS costs by identifying and deleting stale EBS snapshots and volumes that are no longer needed. This is achieved through an AWS Lambda function that analyses the state of EBS snaps...]]></description><link>https://shreyashsinghchauhan.hashnode.dev/aws-cost-optimization-project</link><guid isPermaLink="true">https://shreyashsinghchauhan.hashnode.dev/aws-cost-optimization-project</guid><dc:creator><![CDATA[Chauhan Shreyash]]></dc:creator><pubDate>Fri, 05 Jul 2024 20:28:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1720206896846/5b18a7e8-2420-40a8-b680-d7c3ce821c4a.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-table-of-contents">Table of Contents</h1>
<h1 id="heading-introduction"><em>⭐️Introduction</em></h1>
<p>In this project, we aim to optimise AWS costs by identifying and deleting stale EBS snapshots and volumes that are no longer needed. This is achieved through an AWS Lambda function that analyses the state of EBS snapshots, their associated volumes, and related EC2 instances. By removing these unused resources, we can significantly reduce storage costs.</p>
<h1 id="heading-services-used-in-this-project">⭐️Services used in this Project</h1>
<ul>
<li><p><strong>AWS Lambda:</strong> Runs the function to manage snapshots and volumes.</p>
</li>
<li><p><strong>Amazon EC2:</strong> Manages instances and volumes.</p>
</li>
<li><p><strong>Amazon EBS:</strong> Stores snapshots and volumes.</p>
</li>
<li><p><strong>AWS IAM:</strong> Provides necessary permissions for Lambda to access EC2 and EBS.</p>
</li>
</ul>
<h1 id="heading-follow-these-steps-to-perform-this-project">Follow these steps to perform this project</h1>
<h2 id="heading-task-1-create-launch-instance">❄️Task 1: Create Launch Instance</h2>
<h3 id="heading-step-1-now-click-on-ec2-and-lets-go-for-launch-instance"><strong>✔️Step 1 : Now click on EC2, and let's go for Launch Instance</strong></h3>
<h3 id="heading-step-2-launch-an-instance-and-select-the-os-image-name"><strong>✔️Step 2: Launch an Instance and select the OS image name</strong></h3>
<p>You have to mention the name of your instance and after that select the AMI for this instance</p>
<h3 id="heading-step-3-select-your-instance-type-and-key-pair"><strong>✔️Step 3: Select your Instance type and Key-pair</strong></h3>
<p>Then go to the instance type and select t2.micro free tier eligible. After that select the key pair (login) or you can create new pair.</p>
<h3 id="heading-step-4-select-network-setting"><strong>✔️Step 4 : Select Network Setting</strong></h3>
<p>The next step is the networking setting there is a firewall (security group), select create a security group and provide the name of the security group and give a description.</p>
<h3 id="heading-step-5-create-your-security-group-rules-and-finally-launch-your-instance"><strong>✔️Step 5: Create your security group rules and finally launch your Instance</strong></h3>
<p>In the type section, we have to set up inbound security rules such as ssh and in the source type section select anywhere and after that launch your instance.</p>
<h1 id="heading-task-2-create-ebs-snapshots-and-volume">❄️Task 2: Create EBS Snapshots and Volume</h1>
<h3 id="heading-step-1navigate-to-the-ec2-dashboard">**✔️Step 1:**Navigate to the EC2 Dashboard</h3>
<p>In the AWS Management Console, find the "Services" menu at the top.Under "Compute," click on "EC2" to open the EC2 Dashboard.</p>
<h3 id="heading-step-2-select-the-volumes"><strong>✔️Step 2: Select the Volumes</strong></h3>
<p>In the EC2 Dashboard, look at the left-hand navigation pane. Under the "Elastic Block Store" section, click on "Volumes" and now this will display a list of all EBS volumes in your account. Identify and select the volume you want to snapshot by clicking the checkbox next to the volume ID.</p>
<h3 id="heading-step-3create-snapshot">**✔️Step 3:**Create Snapshot</h3>
<p>With the volume selected, click the "Actions" button at the top of the page.From the dropdown menu, select "Create Snapshot."A dialog box will appear prompting you to enter details for the snapshot.A dialog box will appear prompting you to enter details for the snapshot. Provide a meaningful description for the snapshot. This will help you identify the snapshot later.Click "Create Snapshot."</p>
<h3 id="heading-now-ebs-snapshot-creation-is-done-go-for-volumes"><strong>✔️</strong>Now EBS Snapshot Creation is done , go for Volumes</h3>
<h3 id="heading-step-1-navigate-to-the-ec2-dashboard-and-lets-go-for-creating-the-volumes"><strong>✔️Step 1:</strong> Navigate to the EC2 Dashboard and let's go for creating the Volumes</h3>
<p>In the EC2 Dashboard, look at the left-hand navigation pane. Under the "Elastic Block Store" section, click on Volumes and create Volume</p>
<h3 id="heading-step-2-select-the-volume-type-and-size"><strong>✔️Step 2: Select the Volume Type and Size</strong></h3>
<p>In this only, Select the type of volume you need (e.g., General Purpose SSD (gp2), Provisioned IOPS SSD (io1)), and the Size in Gib.</p>
<h3 id="heading-step-3-select-the-availability-zone"><strong>✔️Step 3: Select the Availability Zone</strong></h3>
<p>Select the Availability Zone where the volume will be created and do the other configuration(if needed) such as (e.g., encryption, IOPS for Provisioned IOPS SSD), and after configuring everything create the Volume.</p>
<h1 id="heading-task-3-create-lambda-function">❄️Task 3: Create Lambda Function</h1>
<h3 id="heading-step-1-now-click-on-lambda-and-lets-go-for-create-function"><strong>✔️Step 1: Now click on Lambda and let's go for Create Function</strong></h3>
<h3 id="heading-step-2-choose-the-option-to-create-your-function"><strong>✔️Step 2: Choose the Option to create your Function</strong></h3>
<p>In this, you have to choose the option in which you want to create your Function or Simply go with Author from scratch(By default).</p>
<h3 id="heading-step-3select-the-function-name-runtime-and-architecture"><strong>✔️Step 3:Select the function name, Runtime and Architecture</strong></h3>
<p>You have to just mention the name of your function and choose runtime according to your code, choose architecture and after doing this all simply create your Function</p>
<h3 id="heading-step-4-once-your-function-is-created-its-time-to-do-the-testing"><strong>✔️Step 4: Once your function is created, it's time to do the testing</strong></h3>
<p>Now the Function is created, and you have to test your code for this you have to just down scroll through your touchpad or you will see the "Code" section on the left side of the screen, in Code you will see the "test" option. In test option you have to write your codes or instead of writing you can take the reference from my GitHub for codes.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://github.com/shreyash81/AWS-Project">https://github.com/shreyash81/AWS-Project</a></div>
<p> </p>
<h3 id="heading-step-5-taking-the-code-from-github"><strong>✔️Step 5: Taking the Code from GitHub</strong></h3>
<p>In this, we will take the code from GitHub and perform various Functions.</p>
<h3 id="heading-function-1">✍️ FUNCTION 1 👇</h3>
<ol>
<li><p><strong>Identifying Stale EBS Snapshots</strong></p>
<p> In this example, we will create a Lambda function(that we have already done ) that identifies EBS snapshots that are no longer associated with any active EC2 instance and deletes them to save on storage costs. For performing this Function we need code for it.</p>
</li>
<li><p>You can take the reference my GitHub(go to my GitHub through the link( <a target="_blank" href="https://github.com/shreyash81/AWS-Project">https://github.com/shreyash81/AWS-Project</a>... )</p>
</li>
<li><p>or I have provided the link in Step 4 . Just simply click on the link and go to</p>
<p> <a target="_blank" href="https://github.com/shreyash81/AWS-Project/blob/main/EBS_Stale_snapshots.py">EBS_Stale_</a><a target="_blank" href="http://snapshots.py">snapshots.py</a> file and take the code from there and paste it in the test section option in screen)</p>
<p> OR just directly take it from here and paste it.</p>
<pre><code class="lang-python"> <span class="hljs-keyword">import</span> boto3

 <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">lambda_handler</span>(<span class="hljs-params">event, context</span>):</span>
     ec2 = boto3.client(<span class="hljs-string">'ec2'</span>)

     <span class="hljs-comment"># Get all EBS snapshots</span>
     response = ec2.describe_snapshots(OwnerIds=[<span class="hljs-string">'self'</span>])

     <span class="hljs-comment"># Get all active EC2 instance IDs</span>
     instances_response = ec2.describe_instances(Filters=[{<span class="hljs-string">'Name'</span>: <span class="hljs-string">'instance-state-name'</span>, <span class="hljs-string">'Values'</span>: [<span class="hljs-string">'running'</span>]}])
     active_instance_ids = set()

     <span class="hljs-keyword">for</span> reservation <span class="hljs-keyword">in</span> instances_response[<span class="hljs-string">'Reservations'</span>]:
         <span class="hljs-keyword">for</span> instance <span class="hljs-keyword">in</span> reservation[<span class="hljs-string">'Instances'</span>]:
             active_instance_ids.add(instance[<span class="hljs-string">'InstanceId'</span>])

     <span class="hljs-comment"># Iterate through each snapshot and delete if it's not attached to any volume or the volume is not attached to a running instance</span>
     <span class="hljs-keyword">for</span> snapshot <span class="hljs-keyword">in</span> response[<span class="hljs-string">'Snapshots'</span>]:
         snapshot_id = snapshot[<span class="hljs-string">'SnapshotId'</span>]
         volume_id = snapshot.get(<span class="hljs-string">'VolumeId'</span>)

         <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> volume_id:
             <span class="hljs-comment"># Delete the snapshot if it's not attached to any volume</span>
             ec2.delete_snapshot(SnapshotId=snapshot_id)
             print(<span class="hljs-string">f"Deleted EBS snapshot <span class="hljs-subst">{snapshot_id}</span> as it was not attached to any volume."</span>)
         <span class="hljs-keyword">else</span>:
             <span class="hljs-comment"># Check if the volume still exists</span>
             <span class="hljs-keyword">try</span>:
                 volume_response = ec2.describe_volumes(VolumeIds=[volume_id])
                 <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> volume_response[<span class="hljs-string">'Volumes'</span>][<span class="hljs-number">0</span>][<span class="hljs-string">'Attachments'</span>]:
                     ec2.delete_snapshot(SnapshotId=snapshot_id)
                     print(<span class="hljs-string">f"Deleted EBS snapshot <span class="hljs-subst">{snapshot_id}</span> as it was taken from a volume not attached to any running instance."</span>)
             <span class="hljs-keyword">except</span> ec2.exceptions.ClientError <span class="hljs-keyword">as</span> e:
                 <span class="hljs-keyword">if</span> e.response[<span class="hljs-string">'Error'</span>][<span class="hljs-string">'Code'</span>] == <span class="hljs-string">'InvalidVolume.NotFound'</span>:
                     <span class="hljs-comment"># The volume associated with the snapshot is not found (it might have been deleted)</span>
                     ec2.delete_snapshot(SnapshotId=snapshot_id)
                     print(<span class="hljs-string">f"Deleted EBS snapshot <span class="hljs-subst">{snapshot_id}</span> as its associated volume was not found."</span>)
</code></pre>
</li>
</ol>
<p>There is some Prerequisites are required for this particular process.(<strong>Identifying Stale EBS Snapshots)</strong></p>
<p>Before going to the Deploying and testing phase. You have to delete the instance to perform this process.</p>
<p>How to Delete the instance?</p>
<ol>
<li><p>Click on the EC2 Services and Navigate to EC2 Dashboard and click on Instances(running ) option.</p>
</li>
<li><p>Now you will see the option like INSTANCE STATE in your upside right-hand corner.</p>
</li>
<li><p>Just simply click on the INSTANCE STATE and terminate the Instance.</p>
</li>
<li><p>Now go for the Deploy and test code ( Fallow <strong>✔️Step 6:)</strong></p>
</li>
</ol>
<h3 id="heading-function-2">✍️ FUNCTION 2 👇</h3>
<p><strong>Identifying Stale EBS Snapshots and Volumes</strong></p>
<p>In the case of EBS snapshots are associated with volume and that volume is not attached to any running instance then delete the volume as well to save on storage costs. For performing this Function</p>
<p>we need code for it.</p>
<ol>
<li><p>You can take the reference my GitHub(go to my GitHub through this link( <a target="_blank" href="https://github.com/shreyash81/AWS-Project">https://github.com/shreyash81/AWS-Project</a>... )</p>
</li>
<li><p>or I have provided in Step 4 . Just simply click on the link and go to</p>
</li>
</ol>
<p><a target="_blank" href="https://github.com/shreyash81/AWS-Project/blob/main/Stale_resource_Volume.py">Stale_resource_</a><a target="_blank" href="http://Volume.py">Volume.py</a> file and take code <a target="_blank" href="https://github.com/shreyash81/AWS-Project/blob/main/Stale_resource_Volume.py">from there and paste it</a> in the test section option in the screen)</p>
<p>OR just Directly take it from here and paste it.</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> boto3

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">lambda_handler</span>(<span class="hljs-params">event, context</span>):</span>
    ec2 = boto3.client(<span class="hljs-string">'ec2'</span>)

    <span class="hljs-comment"># Get all EBS snapshots</span>
    response = ec2.describe_snapshots(OwnerIds=[<span class="hljs-string">'self'</span>])

    <span class="hljs-comment"># Get all active EC2 instance IDs</span>
    instances_response = ec2.describe_instances(Filters=[{<span class="hljs-string">'Name'</span>: <span class="hljs-string">'instance-state-name'</span>, <span class="hljs-string">'Values'</span>: [<span class="hljs-string">'running'</span>]}])
    active_instance_ids = set()

    <span class="hljs-keyword">for</span> reservation <span class="hljs-keyword">in</span> instances_response[<span class="hljs-string">'Reservations'</span>]:
        <span class="hljs-keyword">for</span> instance <span class="hljs-keyword">in</span> reservation[<span class="hljs-string">'Instances'</span>]:
            active_instance_ids.add(instance[<span class="hljs-string">'InstanceId'</span>])

    <span class="hljs-comment"># Iterate through each snapshot and delete if it's not attached to any volume or the volume is not attached to a running instance</span>
    <span class="hljs-keyword">for</span> snapshot <span class="hljs-keyword">in</span> response[<span class="hljs-string">'Snapshots'</span>]:
        snapshot_id = snapshot[<span class="hljs-string">'SnapshotId'</span>]
        volume_id = snapshot.get(<span class="hljs-string">'VolumeId'</span>)

        <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> volume_id:
            <span class="hljs-comment"># Delete the snapshot if it's not attached to any volume</span>
            ec2.delete_snapshot(SnapshotId=snapshot_id)
            print(<span class="hljs-string">f"Deleted EBS snapshot <span class="hljs-subst">{snapshot_id}</span> as it was not attached to any volume."</span>)
        <span class="hljs-keyword">else</span>:
            <span class="hljs-comment"># Check if the volume still exists</span>
            <span class="hljs-keyword">try</span>:
                volume_response = ec2.describe_volumes(VolumeIds=[volume_id])
                <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> volume_response[<span class="hljs-string">'Volumes'</span>][<span class="hljs-number">0</span>][<span class="hljs-string">'Attachments'</span>]:
                    ec2.delete_snapshot(SnapshotId=snapshot_id)
                    print(<span class="hljs-string">f"Deleted EBS snapshot <span class="hljs-subst">{snapshot_id}</span> as it was taken from a volume not attached to any running instance."</span>)
                    <span class="hljs-comment"># Delete the volume if it's not attached to any running instance</span>
                    ec2.delete_volume(VolumeId=volume_id)
                    print(<span class="hljs-string">f"Deleted volume <span class="hljs-subst">{volume_id}</span> as it was not attached to any running instance."</span>)
                <span class="hljs-keyword">else</span>:
                    <span class="hljs-comment"># Check if any of the volume attachments are to a running instance</span>
                    attached_to_running_instance = <span class="hljs-literal">False</span>
                    <span class="hljs-keyword">for</span> attachment <span class="hljs-keyword">in</span> volume_response[<span class="hljs-string">'Volumes'</span>][<span class="hljs-number">0</span>][<span class="hljs-string">'Attachments'</span>]:
                        <span class="hljs-keyword">if</span> attachment[<span class="hljs-string">'InstanceId'</span>] <span class="hljs-keyword">in</span> active_instance_ids:
                            attached_to_running_instance = <span class="hljs-literal">True</span>
                            <span class="hljs-keyword">break</span>

                    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> attached_to_running_instance:
                        ec2.delete_snapshot(SnapshotId=snapshot_id)
                        print(<span class="hljs-string">f"Deleted EBS snapshot <span class="hljs-subst">{snapshot_id}</span> as its associated volume was not attached to any running instance."</span>)
                        <span class="hljs-comment"># Delete the volume if it's not attached to any running instance</span>
                        ec2.delete_volume(VolumeId=volume_id)
                        print(<span class="hljs-string">f"Deleted volume <span class="hljs-subst">{volume_id}</span> as it was not attached to any running instance."</span>)
            <span class="hljs-keyword">except</span> ec2.exceptions.ClientError <span class="hljs-keyword">as</span> e:
                <span class="hljs-keyword">if</span> e.response[<span class="hljs-string">'Error'</span>][<span class="hljs-string">'Code'</span>] == <span class="hljs-string">'InvalidVolume.NotFound'</span>:
                    <span class="hljs-comment"># The volume associated with the snapshot is not found (it might have been deleted)</span>
                    ec2.delete_snapshot(SnapshotId=snapshot_id)
                    print(<span class="hljs-string">f"Deleted EBS snapshot <span class="hljs-subst">{snapshot_id}</span> as its associated volume was not found."</span>)
</code></pre>
<p>Same as we did in the previous Function we need some Prerequisites are required for this particular function. (<strong>Identifying Stale EBS Snapshots and Volumes)</strong></p>
<p>Before going to the Deploying and testing phase. You have to delete the instance to perform this process.</p>
<p>How to Delete the instance?</p>
<ol>
<li><p>Click on the EC2 Services and Navigate to EC2 Dashboard and click on Instances(running ) option.</p>
</li>
<li><p>Now you will see the option like INSTANCE STATE in your upside right-hand corner.</p>
</li>
<li><p>Just simply click on the INSTANCE STATE and terminate the Instance.</p>
</li>
<li><p>Now go for the Deploy and test code ( Fallow <strong>✔️Step 6:)</strong></p>
</li>
</ol>
<h3 id="heading-function-3">✍️ FUNCTION 3 👇</h3>
<p><strong>Identifying Stale EBS Snapshots and Volumes and Running Instances</strong></p>
<p>OR In the case of if EBS snapshot is associated with volume and that volume is attached to any active instance then firstly delete the running instance after that delete the volume and snapshots. For performing this Function we need code for it.</p>
<ol>
<li><p>You can take the reference my GitHub(go to my GitHub through the link( <a target="_blank" href="https://github.com/shreyash81/AWS-Project">https://github.com/shreyash81/AWS-Project</a>... )</p>
</li>
<li><p>or I have provided the link in Step 4 . Just simply click on the link and go to</p>
<p> <a target="_blank" href="https://github.com/shreyash81/AWS-Project/blob/main/Stale_resource_Active_Instances.py">Stale_resource_Active_</a><a target="_blank" href="http://Instances.py">Instances.py</a> <a target="_blank" href="https://github.com/shreyash81/AWS-Project/blob/main/Stale_resource_Active_Instances.py">file and take the code from there</a> and paste it in the test section option in screen)</p>
</li>
<li><p>Or Just directly take it from here and paste it<strong>.</strong></p>
</li>
</ol>
<h3 id="heading-step-6-deploy-and-test-the-code"><strong>✔️Step 6: Deploy and Test the Code</strong></h3>
<p>After writing the code you have to Deploy the code and then test the Code For these three Functions:</p>
<p>How to Deploy. How to Test.</p>
<p>Just simply click on Deploy After Deploying just simply click on</p>
<p>after you finished writing the code Test.</p>
<ol>
<li><p><strong>Identifying Stale EBS Snapshots</strong></p>
</li>
<li><p><strong>Identifying Stale EBS Snapshots and Volumes</strong></p>
</li>
</ol>
<ol start="3">
<li><strong>Identifying Stale EBS Snapshots and Volumes and Running Instances</strong></li>
</ol>
<h3 id="heading-task-3-troubleshoot-your-errors">❄️Task 3: <strong>Troubleshoot your Errors</strong></h3>
<p>After testing you will face some errors and to Troubleshoot these errors you have to follow these steps.</p>
<h3 id="heading-step-1-to-troubleshoot-your-first-error-that-is-time-out-3-sec"><strong>✔️Step 1:</strong> To troubleshoot your first error that is Time out 3 sec.</h3>
<p>/</p>
<ol>
<li><p>Click on the "Configuration" section that will appear on the left of the Screen where you created your Function.</p>
</li>
<li><p>In the "Configuration" section, you will see the "General Configuration" option.</p>
</li>
<li><p>Click the "General Configuration" option and you will see the "Edit tab" on the right side of your screen.</p>
</li>
<li><p>Click on the "Edit" option and increase the Timeout to 10 seconds.</p>
</li>
</ol>
<h3 id="heading-step-2-to-troubleshoot-your-second-error-that-is-related-to-iam-rules-and-polices"><strong>✔️Step 2 :To troubleshoot your second error that is related to IAM Rules and Polices</strong></h3>
<h3 id="heading-step-3-now-everything-is-fine-and-lets-go-for-test-the-different-function-code"><strong>✔️Step 3 : Now everything is fine and let's go for test the different Function Code</strong></h3>
<h2 id="heading-see-the-results-related-to-this-project">❄️See the Results related to this Project:</h2>
]]></content:encoded></item></channel></rss>