Project: 3 tier App
๐น About Me I am an Engineer with 2+ years of experience in Software,python automation,linux server and Networking at Tata Communications. Currently, I am transitioning my career into DevOps and Site Reliability Engineering (SRE) with hands-on knowledge of Docker, Ansible, Jenkins, Git, CI/CD pipelines, and AWS Cloud. Key contributions include automating data gathering using Python (Selenium), developing and maintaining web portals with Django and PHP, and managing Linux server environments (Red Hat Enterprise Linux 8.7). My networking expertise spans complex troubleshooting and configuration of routers and switches (Juniper, Cisco, Huawei), with hands-on experience in routing protocols (OSPF, BGP), VLANs, MPLS, VPN, and SD-WAN technologies. I am passionate about automation, cloud infrastructure, and reliability engineering, and I am actively seeking DevOps / Site Reliability Engineer opportunities where I can contribute, learn, and grow. ๐ Skills: AWS | Docker | Ansible | Jenkins | Git | CI/CD | Linux | Python | Networking | Fortinet | ๐ Certifications: CCNA Cisco Fortinet Firewall NSE4 AWS Cloud Practitioner Certification Devops skillsup from GFG
This guide explains how I deployed a complete three-tier application (Frontend + Backend + Database) on AWS Elastic Kubernetes Service (EKS), using Docker, ECR, eksctl, Helm, and the AWS Load Balancer Controller.
Github project link : https://github.com/prernask/TWSThreeTierAppChallenge.git
โ 1. Install Prerequisites
Install Git & Docker
sudo yum install git -y
sudo yum install docker -y
sudo systemctl start docker
sudo systemctl enable docker
docker ps
sudo docker login
โ 2. Clone the Project Repository
git clone https://github.com/prernask/TWSThreeTierAppChallenge.git
cd TWSThreeTierAppChallenge/
โ 3. Install AWS CLI & Configure
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
sudo apt install unzip -y
unzip awscliv2.zip
sudo ./aws/install
aws configure
โ 4. Build & Push Frontend Docker Image to ECR
Navigate to frontend folder
cd Application-Code/frontend/
sudo rm Dockerfile
sudo nano Dockerfile
(Add your custom Dockerfile content)
Build, Tag, and Push : get commands from AWS ECR
docker build -t myecr/3tier .
docker tag myecr/3tier:latest 196061557748.dkr.ecr.us-east-1.amazonaws.com/myecr/3tier:latest
sudo docker tag myecr/3tier:latest 196061557748.dkr.ecr.us-east-1.amazonaws.com/myecr/3tier:latest
docker push 196061557748.dkr.ecr.us-east-1.amazonaws.com/myecr/3tier:latest
sudo docker push 196061557748.dkr.ecr.us-east-1.amazonaws.com/myecr/3tier:latest
aws ecr get-login-password --region us-east-1 |sudo docker login --username AWS --password-stdin 196061557748.dkr.ecr.us-east-1.amazonaws.com
sudo docker push 196061557748.dkr.ecr.us-east-1.amazonaws.com/myecr/3tier:latest
โ 5. Build & Push Backend Docker Image
cd Application-Code/backend/
sudo rm Dockerfile
sudo nano Dockerfile
docker build -t myecr/three-tier-backend .
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 196061557748.dkr.ecr.us-east-1.amazonaws.com
docker build -t myecr/three-tier-backend .
docker tag myecr/three-tier-backend:latest 196061557748.dkr.ecr.us-east-1.amazonaws.com/myecr/three-tier-backend:latest
docker push 196061557748.dkr.ecr.us-east-1.amazonaws.com/myecr/three-tier-backend:latest
cd ..
โ 6. Install eksctl & kubectl
curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
sudo mv /tmp/eksctl /usr/local/bin
eksctl version
curl -LO "https://dl.k8s.io/release/$(curl -Ls https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/
kubectl version --client
โ 7. Create EKS Cluster
eksctl create cluster \
--name mycluster \
--region us-east-1 \
--nodegroup-name node1 \
--node-type t3.small \
--nodes-min 2 \
--nodes-max 2
kubectl get nodes
โ 8. Deploy Frontend on EKS
kubectl create namespace myecr
cd Kubernetes-Manifests-file/Frontend/
kubectl apply -f deployment.yaml -n myecr
kubectl apply -f service.yaml -n myecr
kubectl get svc -n myecr
[ec2-user@ip-172-31-64-194 Frontend]$ sudo cat service.yaml
apiVersion: v1
kind: Service
metadata:
name: frontend
namespace: myecr
spec:
ports:
- port: 3000
protocol: TCP
type: ClusterIP
selector:
[ec2-user@ip-172-31-64-194 Frontend]$
Output : frontend
[ec2-user@ip-172-31-64-194 Frontend]$ kubectl get deployments -n myecr
NAME READY UP-TO-DATE AVAILABLE AGE
frontend 1/1 1 1 80m
[ec2-user@ip-172-31-64-194 Frontend]$
[ec2-user@ip-172-31-64-194 Frontend]$ kubectl get pods -n myecr
NAME READY STATUS RESTARTS AGE
frontend-dd985fb65-6cwc8 1/1 Running 12 (20m ago) 51m
[ec2-user@ip-172-31-64-194 Frontend]$ kubectl get svc -n myecr
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend LoadBalancer 10.100.194.239 af3aa4a1a5831459a946ccd6353eb766-1722602330.us-east-1.elb.amazonaws.com 80:31391/TCP 81m
[ec2-user@ip-172-31-64-194 Frontend]$
โ 9. Deploy Backend
cd Kubernetes-Manifests-file/Backend/
[ec2-user@ip-172-31-64-194 backend]$ docker build -t myecr/three-tier-backend .
[ec2-user@ip-172-31-64-194 backend]$ docker tag myecr/three-tier-backend:latest 196061557748.dkr.ecr.us-east-1.amazonaws.com/myecr/three-tier-backend:latest
[ec2-user@ip-172-31-64-194 backend]$ docker push 196061557748.dkr.ecr.us-east-1.amazonaws.com/myecr/three-tier-backend:latest
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
196061557748.dkr.ecr.us-east-1.amazonaws.com/myecr/three-tier-frontend latest 7cdee69c1c10 20 minutes ago 1.12GB
myecr/three-tier-frontend latest 7cdee69c1c10 20 minutes ago 1.12GB
196061557748.dkr.ecr.us-east-1.amazonaws.com/myecr/three-tier-backend latest 643751b845e0 2 hours ago 924MB
myecr/three-tier-backend latest 643751b845e0 2 hours ago 924MB
preranakarande/flaskapp latest 6dcc8ae81c75 16 hours ago 495MB
mysql latest f6b0ca07d79d 3 weeks ago 934MB
[ec2-user@ip-172-31-64-194 backend]$
kubectl apply -f deployment.yaml -n myecr
kubectl apply -f service.yaml -n myecr
โ 10. Deploy MongoDB Database
cd Kubernetes-Manifests-file/Database/
ec2-user@ip-172-31-64-194 Kubernetes-Manifests-file]$ cd Database/
[ec2-user@ip-172-31-64-194 Database]$
[ec2-user@ip-172-31-64-194 Database]$ ls
deployment.yaml pv.yaml pvc.yaml secrets.yaml service.yaml
[ec2-user@ip-172-31-64-194 Database]$
[ec2-user@ip-172-31-64-194 Database]$
[ec2-user@ip-172-31-64-194 Database]$ sudo cat secrets.yaml
apiVersion: v1
kind: Secret
metadata:
namespace: three-tier
name: mongo-sec
type: Opaque
data:
password: cGFzc3dvcmQxMjM= #Three-Tier-Project
username: YWRtaW4= #admin[ec2-user@ip-172-31-64-194 Database]$
[ec2-user@ip-172-31-64-194 Database]$ echo 'prerana' | base64
cHJlcmFuYQo=
[ec2-user@ip-172-31-64-194 Database]$ echo 'password123' | base64
cGFzc3dvcmQxMjMK
[ec2-user@ip-172-31-64-194 Database]$ ls
kubectl apply -f pv.yaml -n myecr
kubectl apply -f pvc.yaml -n myecr
kubectl apply -f secrets.yaml -n myecr
kubectl apply -f deployment.yaml -n myecr
kubectl apply -f service.yaml -n myecr
$ kubectl get deployment -n myecr
NAME READY UP-TO-DATE AVAILABLE AGE
frontend 1/1 1 1 118m
mongodb 0/1 1 0 64s
[ec2-user@ip-172-31-64-194 Database]$
$ kubectl apply -f pv.yaml -n myecr
persistentvolume/mongo-pv created
[ec2-user@ip-172-31-64-194 Database]$ kubectl apply -f pvc.yaml -n myecr
persistentvolumeclaim/mongo-volume-claim created
[ec2-user@ip-172-31-64-194 Database]$ kubectl get deployment -n myecr
NAME READY UP-TO-DATE AVAILABLE AGE
frontend 1/1 1 1 133m
mongodb 1/1 1 1 16m
[ec2-user@ip-172-31-64-194 Database]$
[ec2-user@ip-172-31-64-194 Database]$ kubectl get svc -n myecr
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend LoadBalancer 10.100.194.239 af3aa4a1a5831459a946ccd6353eb766-1722602330.us-east-1.elb.amazonaws.com 80:31391/TCP 133m
mongodb-svc ClusterIP 10.100.134.16 <none> 27017/TCP 16m
[ec2-user@ip-172-31-64-194 Database]$
Check status:
kubectl get deployment -n myecr
kubectl get svc -n myecr
[ec2-user@ip-172-31-64-194 Backend]$ kubectl get deployment -n myecr
NAME READY UP-TO-DATE AVAILABLE AGE
api 2/2 2 2 46s
frontend 1/1 1 1 140m
mongodb 1/1 1 1 23m
[ec2-user@ip-172-31-64-194 Backend]$
โ 11. Install Helm & AWS ALB Load Balancer Controller
Install Helm
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
helm version
[ec2-user@ip-172-31-64-194 ~]$ helm repo list
$ helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=mycluster --set s
erviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller
[ec2-user@ip-172-31-64-194 ~]$ kubectl get deployment -n kube-system aws-load-balancer-controller
NAME READY UP-TO-DATE AVAILABLE AGE
aws-load-balancer-controller 2/2 2 2 16s
Install IAM Policy & Service Account
curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.5.4/docs/install/iam_policy.json
aws iam create-policy --policy-name AWSLoadBalancerControllerIAMPolicy \
--policy-document file://iam_policy.json
eksctl utils associate-iam-oidc-provider --region us-east-1 --cluster mycluster --approve
eksctl create iamserviceaccount \
--cluster mycluster \
--namespace kube-system \
--name aws-load-balancer-controller \
--role-name AmazonEKSLoadBalancerControllerRole \
--attach-policy-arn arn:aws:iam::<AWS_ID>:policy/AWSLoadBalancerControllerIAMPolicy \
--approve \
--region us-east-1
Install Controller via Helm
helm repo add eks https://aws.github.io/eks-charts
helm repo update
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=mycluster \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller
โ 12. Deploy Ingress
cd Kubernetes-Manifests-file/
kubectl apply -f ingress.yaml -n myecr
[ec2-user@ip-172-31-64-194 Kubernetes-Manifests-file]$ kubectl get pods -n myecr
NAME READY STATUS RESTARTS AGE
api-6fbf679f4d-86q55 1/1 Running 0 40m
api-6fbf679f4d-ccsr2 1/1 Running 0 40m
frontend-dd985fb65-6cwc8 1/1 Running 12 (119m ago) 151m
mongodb-799f9bc559-bpqxc 1/1 Running 0 63m
[ec2-user@ip-172-31-64-194 Kubernetes-Manifests-file]$ kubectl get ing -n myecr
NAME CLASS HOSTS ADDRESS PORTS AGE
mainlb alb backend.myapplication.study 80 14m
#create AWSLoadBalancerControllerIAMPolicy.json and add permissions to get address of ALB
[ec2-user@ip-172-31-64-194 Kubernetes-Manifests-file]$ sudo nano AWSLoadBalancerControllerIAMPolicy.json
$ kubectl delete pod -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller
pod "aws-load-balancer-controller-7f44cbfb8-kcs7c" deleted from kube-system namespace
pod "aws-load-balancer-controller-7f44cbfb8-w49vz" deleted from kube-system namespace
[ec2-user@ip-172-31-64-194 Kubernetes-Manifests-file]$ kubectl get ingress mainlb -n myecr --watch
NAME CLASS HOSTS ADDRESS PORTS AGE
mainlb alb backend.myapplication.study 80 17h
mainlb alb backend.myapplication.study k8s-myecr-mainlb-e3049081a3-240948518.us-east-1.elb.amazonaws.com 80 17h
[ec2-user@ip-172-31-64-194 Kubernetes-Manifests-file]$
๐ Deployment Status Check
List all services:
kubectl get svc -n myecr
Your LoadBalancer URL:
- Frontend:
http://<ELB-DNS-NAME>
Example Output:
frontend LoadBalancer ... af3aa4a1a5831459a946ccd6.elb.amazonaws.com
api ClusterIP
mongodb ClusterIP
Delete Cluster
[ec2-user@ip-172-31-64-194 ~]$ eksctl delete cluster --name mycluster --region us-east-1
Create ECR on AWS for frontend and backend

IAM policy added

Output

โญ Conclusion
You have successfully deployed:
โ Frontend (React/Node)
โ Backend API (Node)
โ MongoDB Database
โ Persistent Volume & PVC
โ ALB Ingress Controller
โ Highly available EKS cluster
This is a complete production-grade three-tier architecture on AWS.