Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/vikashgupta498/wanderlust-blogging-app

In this demo, we will see how to deploy an end to end three tier MERN stack application on EKS cluster.
https://github.com/vikashgupta498/wanderlust-blogging-app

docker-compose docker-container docker-image dockerfile eks-cluster git jenkins kubernetes owasp-dependencycheck terraform trivy-scan

Last synced: 7 days ago
JSON representation

In this demo, we will see how to deploy an end to end three tier MERN stack application on EKS cluster.

Awesome Lists containing this project

README

        

# Wanderlust - Your Ultimate Travel Blog 🌍✈️

WanderLust is a simple MERN travel blog website ✈ This project is aimed to help people to contribute in open source, upskill in react and also master git.

![Preview Image](https://github.com/krishnaacharyaa/wanderlust/assets/116620586/17ba9da6-225f-481d-87c0-5d5a010a9538)
#

# Wanderlust Mega Project End to End Implementation

### In this demo, we will see how to deploy an end to end three tier MERN stack application on EKS cluster.
#
### Project Deployment Flow:

#

## Tech stack used in this project:
- GitHub (Code)
- Docker (Containerization)
- Jenkins (CI)
- OWASP (Dependency check)
- SonarQube (Quality)
- Trivy (Filesystem Scan)
- ArgoCD (CD)
- Redis (Caching)
- AWS EKS (Kubernetes)
- Helm (Monitoring using grafana and prometheus)

### How pipeline will look after deployment:
- CI pipeline to build and push
![image](https://github.com/user-attachments/assets/20542d8b-0701-43ed-b2f8-82f8ed28d053)

- CD pipeline to update application version
![image](https://github.com/user-attachments/assets/8fd13807-622e-45f7-af23-dcc1ba30ca5d)

- ArgoCD application for deployment on EKS
![image](https://github.com/user-attachments/assets/1ea9d486-656e-40f1-804d-2651efb54cf6)

#
> [!Important]
> Below table helps you to navigate to the particular tool installation section fast.

| Tech stack | Installation |
| -------- | ------- |
| Jenkins Master | Install and configure Jenkins |
| eksctl | Install eksctl |
| Argocd | Install and configure ArgoCD |
| Jenkins-Worker Setup | Install and configure Jenkins Worker Node |
| OWASP setup | Install and configure OWASP |
| SonarQube | Install and configure SonarQube |
| Email Notification Setup | Email notification setup |
| Monitoring | Prometheus and grafana setup using helm charts
| Clean Up | Clean up |
#

### Pre-requisites to implement this project:
#

> [!Note]
> This project will be implemented on North California region (us-west-1).

- Create 1 Master machine on AWS with 2CPU, 8GB of RAM (t2.large) and 29 GB of storage and install Docker on it.
#
- Open the below ports in security group of master machine and also attach same security group to Jenkins worker node (We will create worker node shortly)
![image](https://github.com/user-attachments/assets/4e5ecd37-fe2e-4e4b-a6ba-14c7b62715a3)

> [!Note]
> We are creating this master machine because we will configure Jenkins master, eksctl, EKS cluster creation from here.

Install & Configure Docker by using below command, "NewGrp docker" will refresh the group config hence no need to restart the EC2 machine.

```bash
sudo apt-get update
```
```bash
sudo apt-get install docker.io -y
sudo usermod -aG docker ubuntu && newgrp docker
```
#
- Install and configure Jenkins (Master machine)
```bash
sudo apt update -y
sudo apt install fontconfig openjdk-17-jre -y

sudo wget -O /usr/share/keyrings/jenkins-keyring.asc \
https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key

echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc]" \
https://pkg.jenkins.io/debian-stable binary/ | sudo tee \
/etc/apt/sources.list.d/jenkins.list > /dev/null

sudo apt-get update -y
sudo apt-get install jenkins -y
```
- Now, access Jenkins Master on the browser on port 8080 and configure it.
#
- Create EKS Cluster on AWS (Master machine)
- IAM user with **access keys and secret access keys**
- AWSCLI should be configured (Setup AWSCLI)
```bash
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
sudo apt install unzip
unzip awscliv2.zip
sudo ./aws/install
aws configure
```

- Install **kubectl** (Master machine)(Setup kubectl )
```bash
curl -o kubectl https://amazon-eks.s3.us-west-2.amazonaws.com/1.19.6/2021-01-05/bin/linux/amd64/kubectl
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin
kubectl version --short --client
```

- Install **eksctl** (Master machine) (Setup eksctl)
```bash
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
```

- Create EKS Cluster (Master machine)
```bash
eksctl create cluster --name=wanderlust \
--region=us-east-2 \
--version=1.30 \
--without-nodegroup
```
- Associate IAM OIDC Provider (Master machine)
```bash
eksctl utils associate-iam-oidc-provider \
--region us-east-2 \
--cluster wanderlust \
--approve
```
- Create Nodegroup (Master machine)
```bash
eksctl create nodegroup --cluster=wanderlust \
--region=us-east-2 \
--name=wanderlust \
--node-type=t2.large \
--nodes=2 \
--nodes-min=2 \
--nodes-max=2 \
--node-volume-size=29 \
--ssh-access \
--ssh-public-key=eks-nodegroup-key
```
> [!Note]
> Make sure the ssh-public-key "eks-nodegroup-key is available in your aws account"
#
- Setting up jenkins worker node
- Create a new EC2 instance (Jenkins Worker) with 2CPU, 8GB of RAM (t2.large) and 29 GB of storage and install java on it
```bash
sudo apt update -y
sudo apt install fontconfig openjdk-17-jre -y
```
- Create an IAM role with administrator access attach it to the jenkins worker node Select Jenkins worker node EC2 instance --> Actions --> Security --> Modify IAM role
![image](https://github.com/user-attachments/assets/1a9060db-db11-40b7-86f0-47a65e8ed68b)

- Configure AWSCLI (Setup AWSCLI)
```bash
sudo su
```
```bash
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
sudo apt install unzip
unzip awscliv2.zip
sudo ./aws/install
aws configure
```
#
- generate ssh keys (Master machine) to setup jenkins master-slave
```bash
ssh-keygen
```
![image](https://github.com/user-attachments/assets/0c8ecb74-1bc5-46f9-ad55-1e22e8092198)
#
- Now move to directory where your ssh keys are generated and copy the content of public key and paste to authorized_keys file of the Jenkins worker node.
#
- Now, go to the jenkins master and navigate to Manage jenkins --> Nodes, and click on Add node
- name: Node
- type: permanent agent
- Number of executors: 2
- Remote root directory
- Labels: Node
- Usage: Only build jobs with label expressions matching this node
- Launch method: Via ssh
- Host: \
- Credentials: Add --> Kind: ssh username with private key --> ID: Worker --> Description: Worker --> Username: root --> Private key: Enter directly --> Add Private key
- Host Key Verification Strategy: Non verifying Verification Strategy
- Availability: Keep this agent online as much as possible
#
- And your jenkins worker node is added
![image](https://github.com/user-attachments/assets/cab93696-a4e2-4501-b164-8287d7077eef)

#
- Install docker (Jenkins Worker)

```bash
sudo apt install docker.io -y
sudo usermod -aG docker ubuntu && newgrp docker
```
#
- Install and configure SonarQube (Master machine)
```bash
docker run -itd --name SonarQube-Server -p 9000:9000 sonarqube:lts-community
```
#
- Install Trivy (Jenkins Worker)
```bash
sudo apt-get install wget apt-transport-https gnupg lsb-release -y
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
echo deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main | sudo tee -a /etc/apt/sources.list.d/trivy.list
sudo apt-get update -y
sudo apt-get install trivy -y
```
#
- Install and Configure ArgoCD (Master Machine)
- Create argocd namespace
```bash
kubectl create namespace argocd
```
- Apply argocd manifest
```bash
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
```
- Make sure all pods are running in argocd namespace
```bash
watch kubectl get pods -n argocd
```
- Install argocd CLI
```bash
sudo curl --silent --location -o /usr/local/bin/argocd https://github.com/argoproj/argo-cd/releases/download/v2.4.7/argocd-linux-amd64
```
- Provide executable permission
```bash
sudo chmod +x /usr/local/bin/argocd
```
- Check argocd services
```bash
kubectl get svc -n argocd
```
- Change argocd server's service from ClusterIP to NodePort
```bash
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "NodePort"}}'
```
- Confirm service is patched or not
```bash
kubectl get svc -n argocd
```
- Check the port where ArgoCD server is running and expose it on security groups of a worker node
![image](https://github.com/user-attachments/assets/a2932e03-ebc7-42a6-9132-82638152197f)
- Access it on browser, click on advance and proceed with
```bash
:
```
![image](https://github.com/user-attachments/assets/29d9cdbd-5b7c-44b3-bb9b-1d091d042ce3)
![image](https://github.com/user-attachments/assets/08f4e047-e21c-4241-ba68-f9b719a4a39a)
![image](https://github.com/user-attachments/assets/1ffa85c3-9055-49b4-aab0-0947b95f0dd2)
- Fetch the initial password of argocd server
```bash
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo
```
- Username: admin
- Now, go to User Info and update your argocd password
#
## Steps to add email notification
- Go to your Jenkins Master EC2 instance and allow 465 port number for SMTPS
#
- Now, we need to generate an application password from our gmail account to authenticate with jenkins
- Open gmail and go to Manage your Google Account --> Security
> [!Important]
> Make sure 2 step verification must be on

![image](https://github.com/user-attachments/assets/5ab9dc9d-dcce-4f9d-9908-01095f1253cb)

- Search for App password and create a app password for jenkins
![image](https://github.com/user-attachments/assets/701752da-7703-4685-8f06-fe1f65dd1b9c)
![image](https://github.com/user-attachments/assets/adc8d8c0-8be4-4319-9042-4115abb5c6fc)

#
- Once, app password is create and go back to jenkins Manage Jenkins --> Credentials to add username and password for email notification
![image](https://github.com/user-attachments/assets/2a42ec62-87c8-43c8-a034-7be0beb8824e)

#
- Go back to Manage Jenkins --> System and search for Extended E-mail Notification
![image](https://github.com/user-attachments/assets/bac81e24-bb07-4659-a251-955966feded8)
#
- Scroll down and search for E-mail Notification and setup email notification
> [!Important]
> Enter your gmail password which we copied recently in password field E-mail Notification --> Advance

![image](https://github.com/user-attachments/assets/14e254fc-1400-457e-b3f4-046404b66950)
![image](https://github.com/user-attachments/assets/7be70b3a-b0dc-415c-838a-b1c6fd87c182)
![image](https://github.com/user-attachments/assets/cffb6e1d-4838-483e-97e0-6851c204ab21)

#
## Steps to implement the project:
- Go to Jenkins Master and click on Manage Jenkins --> Plugins --> Available plugins install the below plugins:
- OWASP
- SonarQube Scanner
- Docker
- Pipeline: Stage View
#
- Configure OWASP, move to Manage Jenkins --> Plugins --> Available plugins (Jenkins Worker)
![image](https://github.com/user-attachments/assets/da6a26d3-f742-4ea8-86b7-107b1650a7c2)

- After OWASP plugin is installed, Now move to Manage jenkins --> Tools (Jenkins Worker)
![image](https://github.com/user-attachments/assets/3b8c3f20-202e-4864-b3b6-b48d7a604ee8)
#
- Login to SonarQube server and create the credentials for jenkins to integrate with SonarQube
- Navigate to Administration --> Security --> Users --> Token
![image](https://github.com/user-attachments/assets/86ad8284-5da6-4048-91fe-ac20c8e4514a)
![image](https://github.com/user-attachments/assets/6bc671a5-c122-45c0-b1f0-f29999bbf751)
![image](https://github.com/user-attachments/assets/e748643a-e037-4d4c-a9be-944995979c60)

#
- Now, go to Manage Jenkins --> credentials and add Sonarqube credentials:
![image](https://github.com/user-attachments/assets/0688e105-2170-4c3f-87a3-128c1a05a0b8)
#
- Go to Manage Jenkins --> Tools and search for SonarQube Scanner installations:
![image](https://github.com/user-attachments/assets/2fdc1e56-f78c-43d2-914a-104ec2c8ea86)
#
- Go to Manage Jenkins --> credentials and add Github credentials to push updated code from the pipeline:
![image](https://github.com/user-attachments/assets/4d0c1a47-621e-4aa2-a0b1-71927fcdaef4)
> [!Note]
> While adding github credentials add Personal Access Token in the password field.
#
- Go to Manage Jenkins --> System and search for SonarQube installations:
![image](https://github.com/user-attachments/assets/ae866185-cb2b-4e83-825b-a125ec97243a)
#
- Now again, Go to Manage Jenkins --> System and search for Global Trusted Pipeline Libraries:Login to SonarQube server, go to Administration --> Webhook and click on create

![image](https://github.com/user-attachments/assets/16527e72-6691-4fdf-a8d2-83dd27a085cb)
![image](https://github.com/user-attachments/assets/a8b45948-766a-49a4-b779-91ac3ce0443c)
#
- Now, go to github repository and under Automations directory update the instance-id field on both the updatefrontendnew.sh updatebackendnew.sh with the k8s worker's instance id
![image](https://github.com/user-attachments/assets/3cb044b4-df88-4d68-bf7c-775cf78d5bf2)
#
- Navigate to Manage Jenkins --> credentials and add credentials for docker login to push docker image:
![image](https://github.com/user-attachments/assets/1a8287fc-b205-4156-8342-3f660f15e8fa)
#
- Create a Wanderlust-CI pipeline
![image](https://github.com/user-attachments/assets/55c7b611-3c20-445f-a49c-7d779894e232)

#
- Create one more pipeline Wanderlust-CD
![image](https://github.com/user-attachments/assets/23f84a93-901b-45e3-b4e8-a12cbed13986)
![image](https://github.com/user-attachments/assets/ac79f7e6-c02c-4431-bb3b-5c7489a93a63)
![image](https://github.com/user-attachments/assets/46a5937f-e06e-4265-ac0f-42543576a5cd)
#
- Provide permission to docker socket so that docker build and push command do not fail (Jenkins Worker)
```bash
chmod 777 /var/run/docker.sock
```
![image](https://github.com/user-attachments/assets/e231c62a-7adb-4335-b67e-480758713dbf)
#
- Go to Master Machine and add our own eks cluster to argocd for application deployment using cli
- Login to argoCD from CLI
```bash
argocd login 52.53.156.187:32738 --username admin
```
> [!Tip]
> 52.53.156.187:32738 --> This should be your argocd url

![image](https://github.com/user-attachments/assets/7d05e5ca-1a16-4054-a321-b99270ca0bf9)

- Check how many clusters are available in argocd
```bash
argocd cluster list
```
![image](https://github.com/user-attachments/assets/76fe7a45-e05c-422d-9652-bdaee02d630f)
- Get your cluster name
```bash
kubectl config get-contexts
```
![image](https://github.com/user-attachments/assets/4cab99aa-cef3-45f6-9150-05004c2f09f8)
- Add your cluster to argocd
```bash
argocd cluster add [email protected] --name wanderlust-eks-cluster
```
> [!Tip]
> [email protected] --> This should be your EKS Cluster Name.

![image](https://github.com/user-attachments/assets/0f36aafd-bab9-4ef8-ba5d-3eb56d850604)
- Once your cluster is added to argocd, go to argocd console Settings --> Clusters and verify it
![image](https://github.com/user-attachments/assets/4490b632-19fd-4499-a341-fabf8488d13c)
#
- Go to Settings --> Repositories and click on Connect repo
![image](https://github.com/user-attachments/assets/cc8728e5-546b-4c46-bd4c-538f4cd6a63d)
![image](https://github.com/user-attachments/assets/eb3646e2-db84-4439-a11a-d4168080d9cc)
![image](https://github.com/user-attachments/assets/a07f8703-5ef3-4524-aaa7-39a139335eb7)
> [!Note]
> Connection should be successful

- Now, go to Applications and click on New App

![image](https://github.com/user-attachments/assets/ec2d7a51-d78f-4947-a90b-258944ad59a2)

> [!Important]
> Make sure to click on the Auto-Create Namespace option while creating argocd application

![image](https://github.com/user-attachments/assets/55dcd3c2-5424-4efb-9bee-1c12bbf7f158)
![image](https://github.com/user-attachments/assets/3e2468ff-8cb2-4bda-a8cc-0742cd6d0cae)

- Congratulations, your application is deployed on AWS EKS Cluster
![image](https://github.com/user-attachments/assets/bc2d9680-fe00-49f9-81bf-93c5595c20cc)
![image](https://github.com/user-attachments/assets/1ea9d486-656e-40f1-804d-2651efb54cf6)
- Open port 31000 and 31100 on worker node and Access it on browser
```bash
:31000
```
![image](https://github.com/user-attachments/assets/a4b2a4b4-e1aa-4b22-ac6b-f40003d0723a)
![image](https://github.com/user-attachments/assets/06f9f1c8-094d-4d9f-a9d8-256fb18a9ae4)
![image](https://github.com/user-attachments/assets/64394f90-8610-44c0-9f63-c3a21eb78f55)
- Email Notification
![image](https://github.com/user-attachments/assets/0ab1ef47-f939-4618-8651-6aa9274721f4)

#
## How to monitor EKS cluster, kubernetes components and workloads using prometheus and grafana via HELM (On Master machine)
-

Install Helm Chart


```bash
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
```
```bash
chmod 700 get_helm.sh
```
```bash
./get_helm.sh
```

#
- Add Helm Stable Charts for Your Local Client
```bash
helm repo add stable https://charts.helm.sh/stable
```

#
- Add Prometheus Helm Repository
```bash
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
```

#
- Create Prometheus Namespace
```bash
kubectl create namespace prometheus
```
```bash
kubectl get ns
```

#
- Install Prometheus using Helm
```bash
helm install stable prometheus-community/kube-prometheus-stack -n prometheus
```

#
- Verify prometheus installation
```bash
kubectl get pods -n prometheus
```

#
- Check the services file (svc) of the Prometheus
```bash
kubectl get svc -n prometheus
```

#
- Expose Prometheus and Grafana to the external world through Node Port
> [!Important]
> change it from Cluster IP to NodePort after changing make sure you save the file and open the assigned nodeport to the service.

```bash
kubectl edit svc stable-kube-prometheus-sta-prometheus -n prometheus
```
![image](https://github.com/user-attachments/assets/90f5dc11-23de-457d-bbcb-944da350152e)
![image](https://github.com/user-attachments/assets/ed94f40f-c1f9-4f50-a340-a68594856cc7)

#
- Verify service
```bash
kubectl get svc -n prometheus
```

#
- Now,let’s change the SVC file of the Grafana and expose it to the outer world
```bash
kubectl edit svc stable-grafana -n prometheus
```
![image](https://github.com/user-attachments/assets/4a2afc1f-deba-48da-831e-49a63e1a8fb6)

#
- Check grafana service
```bash
kubectl get svc -n prometheus
```

#
- Get a password for grafana
```bash
kubectl get secret --namespace prometheus stable-grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo
```
> [!Note]
> Username: admin

#
- Now, view the Dashboard in Grafana
![image](https://github.com/user-attachments/assets/d2e7ff2f-059d-48c4-92bb-9711943819c4)
![image](https://github.com/user-attachments/assets/3d6652d0-7795-4fe9-8919-f33eac88db73)
![image](https://github.com/user-attachments/assets/13321ee5-5d7b-4976-b409-25d3b865a42a)
![image](https://github.com/user-attachments/assets/75a22e4b-ae81-4cad-9c92-21dd90d126a8)

#
## Clean Up
- Delete eks cluster
```bash
eksctl delete cluster --name=wanderlust --region=us-west-1
```

#