Multi-Stage DevSecOps CI-CD Project

In this article, I am deploying the Zomato clone application by using Jenkins as a CI-CD tool & deploying it to the Docker container...!

Multi-Stage DevSecOps CI-CD Project

Prerequisites:

Ubuntu (20.02) instance with a minimum of 2 CPU, 16 GB of RAM and 30 GB of storage
Required ports:

8080 for Jenkins
9000 for SonarQube

3000 for Docker container deployment

465 for SMTP (Simple Mail Transfer Protocol)
Required Jenkins Plugins:

under settings Manage Jenkins >> Manage Plugins >> Available Plugins

Eclipse Temurin

extended email notification

Sonarqube Scanner

Nodejs

OWASP Dependency check

Docker

docker pipeline

docker-build-step

cloud bees docker build and publish

Install Java, Jenkins, Docker and trivy tool, in the docker container, create a SonarQube service with the help of the official Docker Image using below command
docker run -d --name sonarqube -p 9000:9000 sonarqube:lts-community

#!/bin/bash
sudo apt update -y
sudo apt install OpenJDK-11-jre -y

curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | sudo tee \
  /usr/share/keyrings/jenkins-keyring.asc > /dev/null
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

sudo systemctl enable jenkins
sudo systemctl start jenkins
sudo systemctl status jenkins

Create a file Jenkins.sh

give execute permission to the Jenkinsfile

sudo chmod +x Jenkins.sh
./Jenkins.sh # This command will install the Jenkins Service
Connect the Jenkins Server by using the

<Ubuntu VM Public IP Address:8080> (Make sure to allow port 8080 under the networking section)

for the initial admin password use the below command

sudo cat /var/lib/jenkins/secrets/initialAdminPassword

Create a Pipeline Project

Install Docker:

sudo apt-get update
sudo apt-get install docker.io -y
sudo usermod -aG docker $Ubuntu   #my case is ubuntu
newgrp docker
sudo chmod 777 /var/run/docker.sock

install sonarQube service

docker run -d --name sonar -p 9000:9000 sonarqube:lts-community

install trivy tool
create a file trivy.sh

#!/bin/bash
sudo apt-get install wget apt-transport-https gnupg lsb-release -y
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] 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
sudo apt-get install trivy -y

give execution permission to trivy.sh file

sudo chmod +x trivy.sh
./trivy.sh # This will installl trivy

all the services are up and running
now will create a secrete token & web-hook for sonarqube & Jenkins integration
create a token under administration and copy the token

create a web-hook under configuration

add all the credentials under manage Jenkins > credentials

Under Manage Jenkins →Plugins → Available Plugins

Install below plugins
Eclipse Temurin

extended email notification

Sonarqube Scanner

Nodejs

OWASP Dependency check

Docker

docker pipeline

docker-build-step

cloud bees docker build and publish
Configure Java and Nodejs in Global Tool Configuration

Go to Manage Jenkins → Tools → Install JDK and NodeJs→ Click on Apply and Save

Configure Sonarqube & extended Email Service Under System configuration

to integrate Gmail with Jenkins enable port 465 under the networking security group

SMTP server name: smtp.gmail.com

User name: User_email_id@gmail.com

Password: app_pass Use ssl > You will get the app password under the security settings of the Gmail Account

enable 2 step verification and create a app password

This Password is pasted inside the SMTP authentication. And credentials above

Checked SMTP Port: 465

Test the email connectivity by clicking the test email notification option

you will receive a email notification like this

Google Mail, SonarQube, and Docker integration is completed successfully.

Create a Job

create a job as Zomato-clone-project Name, select pipeline, and click on OK.
Let’s go to our Pipeline and add the script in our Pipeline Script.

pipeline {
    agent any

    tools {
        git 'git'
        jdk 'JDK'
        nodejs 'nodejs'
    }

    environment {
        SCANNER_HOME=tool 'sonar-scanner'
        IMAGE_TAG = "${BUILD_NUMBER}"
    }

    stages {

        stage('Clean WorkSpace') {
            steps {
                cleanWs()
            }
        }

        stage ('Docker_Image_CleanUp') {
            steps {
                sh 'docker image prune --all --filter "until=1h" -f'
            }
        }

        stage('Git CheckOut') {
            steps {
                git branch: 'main', url: 'https://github.com/Raghava0684/Zomato-Clone-code.git'
            }
        }

        stage('SonarQube-Analysis') {
            steps {
                withSonarQubeEnv('sonar-server') {
                    sh ''' $SCANNER_HOME/bin/sonar-scanner -Dsonar.projectName=zomato \
                    -Dsonar.projectKey=zomato '''
                }
            }
        }

        stage('Wait For Quality Gate') {
            steps {
                waitForQualityGate abortPipeline: false, credentialsId: 'Sonar-Cred'
            }
        }

        stage ('Install npm Dependencies') {
            steps {
                sh 'npm install'
            }
        }

        stage ('OWASP-Dependency Check') {
            steps {
                dependencyCheck additionalArguments: '--scan ./ --disableYarnAudit --disableNodeAudit', odcInstallation: 'Dependency-check'
                dependencyCheckPublisher pattern: '**/dependency-check-report.xml'
            }
        }

        stage ('trivy FS scanning') {
            steps {
                sh "trivy fs . > trivyfs.txt"
            }
        }

        stage ("Docker Build && Push") {
            steps {
                script {

                withDockerRegistry(credentialsId: 'Docker-Cred', toolName: 'docker') {

                    sh "docker build -t  raghava017/zomato:${BUILD_NUMBER} ."
                    sh "docker push raghava017/zomato:${BUILD_NUMBER} "
                    }

                }
            }
        }


        stage ("Scan Docker Image With Trivy") {
            steps {
                sh 'trivy image raghava017/zomato:latest > trivy.txt'
            }
        }

        stage ("Deploy Docker Image ") {
            steps {
                sh "docker run -d --name zomato -p 3000:3000 raghava017/zomato:latest"
            }
        }
    }

    post {
        always {
            echo 'This will always run'
        }
        success {
            mail to: 'ajayreddimalla123@gmail.com',
                 subject: "Jenkins Pipeline Status: SUCCESSFUL",
                 body: "Your Jenkins Build pipeline has been completed successfully."
        }
        failure {
            mail to: 'ajayreddimalla123@gmail.com',
                 subject: "Jenkins Pipeline Status: FAILED",
                 body: "Your Jenkins Build pipeline hasbeen failed. Please check the logs for more information."
        }
    }

}

save and run the job

SonarQube Report

once the build is successful we will get an email notification like the build is successful.

deployment is done now browse the publicIp:3000 in the browser

Finally, Delete the Virtual machine to avoid more billing

for the source code check the below link

https://github.com/Raghava0684/Zomato-Clone-code.git

Jenkinsfile
https://github.com/Raghava0684/Zomato-Clone-code/blob/main/Jenkinsfile

Thank you so much for reading my blog...!!!