<?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[E Commerce Three Tier application on EKS]]></title><description><![CDATA[E Commerce Three Tier application on EKS]]></description><link>https://e-commerce-three-tier-application-on-eks.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Mon, 31 Aug 2026 01:27:15 GMT</lastBuildDate><atom:link href="https://e-commerce-three-tier-application-on-eks.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Deploying a Three-Tier Microservices Architecture on AWS EKS with Helm]]></title><description><![CDATA[📦 Introduction
In this guide, we’ll deploy Stan’s Robot Shop, a sample e-commerce application that showcases a three-tier microservices architecture, onto an Amazon EKS (Elastic Kubernetes Service) cluster using Helm charts.
The application is compo...]]></description><link>https://e-commerce-three-tier-application-on-eks.hashnode.dev/deploying-a-three-tier-microservices-architecture-on-aws-eks-with-helm</link><guid isPermaLink="true">https://e-commerce-three-tier-application-on-eks.hashnode.dev/deploying-a-three-tier-microservices-architecture-on-aws-eks-with-helm</guid><dc:creator><![CDATA[sushma amarneni]]></dc:creator><pubDate>Sun, 13 Jul 2025 10:26:05 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-introduction">📦 Introduction</h2>
<p>In this guide, we’ll deploy <strong>Stan’s Robot Shop</strong>, a sample e-commerce application that showcases a <strong>three-tier microservices architecture</strong>, onto an <strong>Amazon EKS (Elastic Kubernetes Service)</strong> cluster using <strong>Helm charts</strong>.</p>
<p>The application is composed of several microservices (~8 in total) and a couple of backend databases, mimicking a realistic production environment. This tutorial covers:</p>
<ul>
<li><p>Project architecture</p>
</li>
<li><p>AWS infrastructure prerequisites (IAM roles, VPC, ALB Ingress Controller, EBS CSI Driver)</p>
</li>
<li><p>Helm chart installation on EKS</p>
</li>
<li><p>Accessing and optionally load testing or monitoring the application</p>
</li>
</ul>
<p>The goal is to provide a <strong>comprehensive, step-by-step walkthrough</strong> that gets the full system running on AWS, giving you hands-on experience with deploying cloud-native applications on Kubernetes.</p>
<hr />
<h2 id="heading-project-overview-amp-architecture">🧱 Project Overview &amp; Architecture</h2>
<p><strong>Stan’s Robot Shop</strong> is a cloud-native application built on a <strong>three-tier architecture</strong>:</p>
<ol>
<li><p><strong>Presentation Layer</strong>: Web UI</p>
</li>
<li><p><strong>Application Logic Layer</strong>: Backend microservices</p>
</li>
<li><p><strong>Data Layer</strong>: Databases and message queues</p>
</li>
</ol>
<p>Rather than a monolithic app, Robot Shop is broken into <strong>independent microservices</strong> that handle distinct domains such as user registration, product catalog, cart, shipping, and payments. The architecture is both <strong>polyglot</strong> and <strong>microservice-driven</strong>, with services written in various languages:</p>
<hr />
<h3 id="heading-tech-stack-overview">🔷 Tech Stack Overview</h3>
<ul>
<li><p><strong>Frontend</strong>:</p>
<ul>
<li><p>AngularJS-based web UI</p>
</li>
<li><p>Served via <strong>Nginx</strong></p>
</li>
</ul>
</li>
<li><p><strong>Backend Microservices (Logic Layer)</strong>:</p>
<ul>
<li><p><strong>Node.js (Express)</strong> – e.g., Cart service</p>
</li>
<li><p><strong>Java (Spring Boot)</strong> – e.g., Orders service</p>
</li>
<li><p><strong>Python (Flask)</strong> – e.g., User service</p>
</li>
<li><p><strong>Go</strong> – e.g., Shipping service</p>
</li>
<li><p><strong>PHP</strong> – e.g., Payment service</p>
</li>
<li><p>Services communicate internally using <strong>REST APIs</strong> or <strong>messaging</strong></p>
</li>
</ul>
</li>
<li><p><strong>Data Layer</strong>:</p>
<ul>
<li><p><strong>MongoDB</strong> – NoSQL DB for product/user info</p>
</li>
<li><p><strong>MySQL</strong> – Relational DB</p>
</li>
<li><p><strong>Redis</strong> – In-memory cache/store for session/cart data</p>
</li>
<li><p><strong>RabbitMQ</strong> – Message broker for asynchronous communication between services</p>
</li>
</ul>
</li>
</ul>
<hr />
<h3 id="heading-architecture-highlights">🏗️ Architecture Highlights</h3>
<ul>
<li><p><strong>Microservices architecture</strong> enables <strong>independent scaling</strong>, <strong>development</strong>, and <strong>deployment</strong>.</p>
</li>
<li><p>Each service runs in <strong>EKS</strong> as a <strong>Deployment</strong> or <strong>StatefulSet</strong>, exposed via <strong>Kubernetes Services</strong>.</p>
</li>
<li><p>Databases are backed by <strong>EBS volumes</strong> for persistence.</p>
</li>
<li><p>Ingress is managed by the <strong>AWS Load Balancer Controller</strong> using an <strong>Application Load Balancer (ALB)</strong>.</p>
</li>
<li><p>This represents a <strong>realistic, resilient, and scalable three-tier cloud architecture</strong> deployed entirely on AWS using <strong>infrastructure as code and Helm charts</strong>.</p>
</li>
</ul>
<h3 id="heading-prerequisite-configure-aws-cli-install-kubectl-and-eksctl-and-helm-in-ubuntu-ec2-machine"><strong>Prerequisite- Configure AWS CLI, install Kubectl and eksctl and helm in ubuntu ec2 machine.</strong></h3>
<h3 id="heading-1-create-an-eks-cluster-with-eksctl"><strong>1. Create an EKS Cluster with eksctl</strong></h3>
<pre><code class="lang-plaintext">eksctl create cluster --name demo-cluster-three-tier --region us-east-1
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752399031455/1bf7ac58-ce84-41f2-80ea-bbe57d02f691.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-2-enable-iam-oidc-provider-for-the-cluster"><strong>2. Enable IAM OIDC Provider for the Cluster</strong></h3>
<pre><code class="lang-plaintext">export cluster_name="demo-cluster-three-tier"
# Get the OIDC issuer ID for the cluster
oidc_id=$(aws eks describe-cluster --name $cluster_name --query "cluster.identity.oidc.issuer" --output text | cut -d '/' -f5)
# Check if OIDC provider is already associated
aws iam list-open-id-connect-providers | grep "$oidc_id" || echo "OIDC provider not found"
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752399118095/727b5411-2d30-4900-bbfe-5db1ba3eee3b.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-plaintext">eksctl utils associate-iam-oidc-provider --cluster "$cluster_name" --region us-east-1 --approve
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752399272795/d9daf0cb-3fb9-4b6a-a0d6-e1053f78c3c1.png" alt class="image--center mx-auto" /></p>
<p>This command sets up the <strong>IAM OIDC (OpenID Connect) provider</strong> for your Amazon EKS cluster. By enabling OIDC, you allow <strong>Kubernetes service accounts</strong> to be associated with <strong>IAM roles</strong> using annotations. This is a critical step for enabling <strong>fine-grained permissions</strong> for specific pods.</p>
<p>With OIDC in place, IAM roles can be assumed by pods via service accounts — a requirement for deploying components like:</p>
<ul>
<li><p><strong>AWS Load Balancer Controller</strong> (to manage ALBs/target groups)</p>
</li>
<li><p><strong>EBS CSI Driver</strong> (to dynamically provision persistent volumes)</p>
</li>
</ul>
<p>In essence, this integration ensures your workloads in Kubernetes can securely access AWS resources using IAM roles <strong>without embedding credentials in pods</strong>.</p>
<h3 id="heading-3-enable-the-ebs-csi-driver-persistent-storage"><strong>3 Enable the EBS CSI Driver (Persistent Storage)</strong></h3>
<p>Our application includes stateful services (MongoDB, MySQL, Redis), which require persistent storage in Kubernetes. AWS EKS supports the <strong>EBS CSI Driver</strong> to provision Amazon EBS volumes for Kubernetes PersistentVolumeClaims. We need to install this driver (as an EKS add-on) so that our database pods can have durable storage. Before installing, we must create an IAM role for the CSI driver.</p>
<p><strong>a. Create IAM Role for EBS CSI:</strong> We will create an IAM role that grants permissions for EBS volume operations, and associate it with the EBS CSI driver’s service account:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752399745651/030dba13-1053-42b5-be6f-1c5a07ea3422.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-plaintext">
eksctl create iamserviceaccount --name ebs-csi-controller-sa --namespace kube-system --cluster $cluster_name \
  --role-name "AmazonEKS_EBS_CSI_DriverRole" --role-only \
  --attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy \
  --region us-east-1 --approve
</code></pre>
<p>This command creates an IAM role named <code>AmazonEKS_EBS_CSI_DriverRole</code> with the Amazon-managed policy <code>AmazonEBSCSIDriverPolicy</code> attached (which allows Kubernetes to manage EBS volumes). We used <code>--role-only</code> because EKS Add-ons will create the service account for us; we just need the role ready.</p>
<p><strong>b. Install the EBS CSI Driver Add-on:</strong> Now enable the EBS CSI driver for your cluster:</p>
<pre><code class="lang-plaintext">eksctl create addon --name aws-ebs-csi-driver --cluster $cluster_name \
  --service-account-role-arn arn:aws:iam::&lt;YOUR_AWS_ACCOUNT_ID&gt;:role/AmazonEKS_EBS_CSI_DriverRole --region us-east-1 --force
</code></pre>
<p>This command tells EKS to install the official <strong>aws-ebs-csi-driver</strong> add-on in the cluster, using the IAM role we just created for its service account. After a short time, the EBS CSI driver pods will be running in <code>kube-system</code> namespace (you can check with <code>kubectl get pods -n kube-system -l app=ebs-csi-controller</code>). Once this is complete, your cluster can dynamically provision EBS volumes for any PersistentVolumeClaims that our application’s StatefulSets might create. In summary, the cluster is now configured with everything needed: an OIDC provider, the ALB ingress controller, and the EBS CSI driver – fully ready to host our microservices application.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752399426537/fd191827-be59-409f-bdb9-d4c7c604f4c2.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-4-deploying-the-microservices-with-helm"><strong>4 Deploying the Microservices with Helm</strong></h2>
<p>With the infrastructure in place, we can deploy the Robot Shop application onto the EKS cluster using Helm. The GitHub repository we cloned contains a pre-built Helm chart that defines all the Kubernetes objects (Deployments, Services, StatefulSets, etc.) for the 3-tier app. We will use that chart to install the whole stack in one go.</p>
<h3 id="heading-1-clone-the-repository-if-not-already-done">1. Clone the Repository (if not already done)</h3>
<p>git clone <a target="_blank" href="https://github.com/sushma777/three-tier-architecture-demo.git">https://github.com/sushma777/three-tier-architecture-demo.git</a></p>
<pre><code class="lang-plaintext">cd three-tier-architecture-demo/EKS/helm
</code></pre>
<p>This repository contains the code and manifests for the Robot Shop application. In particular, the <code>EKS/helm</code> directory contains a <code>Chart.yaml</code>, templates, and an <code>ingress.yaml</code> file – everything needed to deploy on EKS with one Helm command. (If you already cloned the repo earlier for local testing, just navigate to <code>EKS/helm</code>.)</p>
<blockquote>
<p><strong><em>Note: The Helm chart is configured to use pre-built Docker images for all services (hosted on Docker Hub), so you do not need to build or push any images manually. The default values should work out-of-the-box for a demo deployment.</em></strong></p>
</blockquote>
<h3 id="heading-2-install-the-helm-chart-on-eks"><strong>2. Install the Helm Chart on EKS</strong></h3>
<p>We’ll deploy all components into a dedicated Kubernetes namespace (for cleanliness). Create the namespace and install the Helm release:</p>
<pre><code class="lang-plaintext">kubectl create namespace robot-shop
helm install robot-shop . -n robot-shop
</code></pre>
<p>This tells Helm to install the chart in the current directory (<code>.</code>) into the <code>robot-shop</code> namespace, with the release name <code>robot-shop</code>. Helm will then create all the necessary objects: deployments for each microservice, stateful sets for database components, services for internal communication, etc. After running the above commands, Helm’s output should indicate it created a number of Kubernetes resources. Indeed, this single step provisions <em>“all the services, deployments, and configurations necessary for the Robot Shop application to run inside your EKS cluster.</em></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752401173155/beaabdb1-6ac3-4a40-a468-d9a4bce3f45d.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-plaintext">kubectl get pods -n robot-shop
</code></pre>
<p>All pods should eventually show as <strong>Running</strong> (or <strong>Completed</strong> for any one-time jobs). If any pods are in <code>CrashLoopBackOff</code>, you may need to check logs, but in a normal scenario they should start correctly since we’re using known-good images.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752401197881/a20354f0-154f-4044-826e-13ba1e3ec73a.png" alt class="image--center mx-auto" /></p>
<ol start="3">
<li><strong>Configure Ingress and Load Balancer (Expose the Application)</strong></li>
</ol>
<p>At this point, the application is running internally in the cluster, but we need to make it accessible from the outside. To do that, we’ll create a Kubernetes <strong>Ingress</strong> resource which the AWS ALB Controller will pick up and create an external Application Load Balancer for. The Helm chart directory provides an <code>ingress.yaml</code> file with the necessary Ingress configuration (it likely defines path routing to the <code>web</code> service, which is the frontend).</p>
<p>Apply the ingress manifest: <strong>kubectl apply -f ingress.yaml</strong></p>
<p>This creates an Ingress resource (in the <code>robot-shop</code> namespace) that maps incoming HTTP requests to the <code>web</code> service of our application. The AWS Load Balancer Controller we installed will notice this and immediately start provisioning an ALB to satisfy the Ingress. Within a few minutes, a new ALB will be created in your AWS account (you can check the <strong>EC2 &gt; Load Balancers</strong> section in the AWS console to watch its progress). The Ingress controller will also create a corresponding Kubernetes Service of type <code>LoadBalancer</code> under the hood, but you primarily interact with the Ingress itself.</p>
<p>It may take <strong>5-10 minutes</strong> for the Application Load Balancer to be fully provisioned and in an “active” state. You can verify that the Ingress has been assigned an address by running:</p>
<p><strong>Deploy the ALB Controller via Helm</strong></p>
<pre><code class="lang-plaintext">helm repo add eks https://aws.github.io/eks-charts
helm repo update
</code></pre>
<pre><code class="lang-plaintext">eksctl create iamserviceaccount --cluster=demo-cluster-three-tier --namespace=kube-system   --name=aws-load-balancer-controller   --role-name AmazonEKSLoadBalancerControllerRole   --attach-policy-arn=arn:aws:iam::450221254409:policy/AWSLoadBalancerControllerIAMPolicy  --region us-east-1  --approve 
helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system \
  --set clusterName=$cluster_name \
  --set serviceAccount.create=false \
  --set serviceAccount.name=aws-load-balancer-controller \
  --set region=us-east-1 \
  --set vpcId=&lt;YOUR_VPC_ID&gt;
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752401594875/dfe6c30a-31af-4b87-9b6c-8363784e4cd0.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752401748743/23f1f712-108c-4dd7-92e6-e007e4afce39.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752401763036/debb60b5-c80b-4460-bb53-ee4687349956.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752401818972/15a8bd93-7e4d-49d5-9f2e-003d46ab1500.png" alt class="image--center mx-auto" /></p>
<p>Once the STATUS shows an address (which will be an AWS ALB DNS name), your application is available on that URL. For example, you might see an address like  <a target="_blank" href="http://k8s-robotsho-robotsho-c4f0ee37ee-504582236.us-east-1.elb.amazonaws.com">k8s-robotsho-robotsho-c4f0ee37ee-504582236.us-east-1.elb.amazonaws.com</a>. You can also get the ALB’s DNS by checking the AWS console.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752401865645/bef03c09-ba42-4b89-b153-5cfc92cf9986.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-4-access-the-application">4. Access the Application</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752401945534/c2c0b37c-35b2-493b-82c7-bf0185d3a7db.png" alt class="image--center mx-auto" /></p>
<p>When the ALB is ready, copy its <strong>DNS name</strong> and try opening it in your web browser (it will be serving on HTTP port 80 by default). You should see the <strong>Robot Shop</strong> storefront load in your browser, confirming that the frontend service is reachable. From there, you can navigate the site: create a user account, browse products, add items to your cart, and perform a checkout. These actions will trigger the various microservices (user, catalogue, cart, order, payment, etc.) to work together. If all went well, the order checkout will complete and you’ll get an order confirmation, indicating the full path through the three tiers is functioning.</p>
<p>At this stage, you have successfully deployed the full microservices-based three-tier application on AWS EKS. The ALB is handling external traffic and routing through the Ingress to the <code>web</code> frontend, which in turn calls internal services. Kubernetes is managing the scaling and networking of all those components behind the scenes.</p>
<p><em>Tip:</em> You can also verify all Services are properly exposed by running <code>kubectl get svc -n robot-shop</code>. Most services are ClusterIP (internal only), but the <code>ingress</code>/ALB provides the external access point. If you described the Ingress (<code>kubectl describe ingress -n robot-shop</code>), you would see annotations that the ALB controller added (like AWS load balancer ARNs, etc.), and the rules mapping <code>/*</code> path to the web service.</p>
<h3 id="heading-5clean-up-resources">5.Clean Up Resources</h3>
<p>If you are done experimenting, remember to delete the AWS resources to avoid ongoing charges. The easiest way is to delete the EKS cluster, which will also delete node instances and load balancers:</p>
<pre><code class="lang-plaintext">eksctl delete cluster --name demo-cluster-three-tier --region us-east-1
</code></pre>
]]></content:encoded></item></channel></rss>