Skip to content

Project on End to End CI/CD pipeline for java based application using Git,Github,Jenkins,Maven,Sonarqube,Nexus,Slack,Docker and Kuberenets with ECR as private docker registry and Zero Downtime Deployment.

Notifications You must be signed in to change notification settings

NITHIN-JOHN-GEORGE/JAVA-CI-CD-PIPELINE

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Description

Project on End to End CI/CD pipeline for java based application using Git,Github,Jenkins,Maven,Sonarqube,Nexus,Slack,Docker and Kuberenets with ECR as private docker registry and Zero Downtime Deployment.

end-to-end-cicd-FLOW


Project Flow

1. Developer pushes code into Github.
2. Webhook triggers Jenkins when there is a change in the code
3. Jenkins Pulls the Code from the Github
4. Maven builds the code and generates artifacts
5. Code quality is measured with Sonarqube
6. Quality Gate Check , If Quality Gate Fails Jenkins Job will fail !!!!!! (Triggered by Sonarqube Webhooks)
7. Upload artifact generated into Sonatype Nexus . It will dynamically choose Snapshot or release repository based on the version tag in pom.xml
8. Build Docker Image based on the Dockerfile with projectname && commit-id as tag . So each time it will be different.
9. Push Docker Image to private ECR docker registry.
10.Dynamically change image in pod template in manifest file.
11.Deploy to K8s cluster created with kubeadm . It will pull image from private registry.
12. Send Build Notification over Slack Channel and email notification when build is success/failure.

Note: We can add an approval step before deploying to K8s cluster as an input from user.

Features

1. Zero downtime deployment with rolling update as deployment strategy
2. Complete automation as when developer check in code , deployed to k8s cluster
3. Versioning of docker images , build artifacts.
4. Code checked against Code coverage and whether coding stantards are met.

Pipeline Execution

JENKINS-PIPELINE-VIEW-MAIN

Execution Results

SONARQUBE REPORTS

SONAR REPORT

NEXUS UPLOADING

NEXUS REPOSITORY

ECR

ECR REPO

JOB TRIGGERED BY WEBHOOKS

GITHUB-WEBHOOK-PUSH

K8s CLUSTER

Controller --> Deployment
Strategy --> Rolling Update

K8S cluster

SLACK NOTIFICATION

SLACK - NOTIFICATION

EMAIL NOTIFICATION

EMAIL NOTIFICATION

FINAL RESULT

FINAL UPDATE

Jenkins Pipeline

Change account number and credentials as per your environment.

def COMMIT
def BRANCH_NAME
def GIT_BRANCH
pipeline
{
 agent any
 environment
 {
     AWS_ACCOUNT_ID="<Your account Id>"
     AWS_DEFAULT_REGION="us-east-1" 
     IMAGE_REPO_NAME="mavenwebapp"
     REPOSITORY_URI = "${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${IMAGE_REPO_NAME}"
     
 }
 tools
 {
      maven 'MAVEN_3.8.4'
 }   

 options 
 {
  buildDiscarder logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '4', daysToKeepStr: '', numToKeepStr: '4')
  timestamps()
}
 stages
 {
     stage('Code checkout')
     {
         steps
         {
             script
             {
                 checkout([$class: 'GitSCM', branches: [[name: '*/development']], extensions: [], userRemoteConfigs: [[url: 'https://github.com/NITHIN-JOHN-GEORGE/JAVA-CI-CD-PIPELINE.git']]])
                 COMMIT = sh (script: "git rev-parse --short=10 HEAD", returnStdout: true).trim()  
                 
                 
                 

             }
             
         }
     }
     stage('Build')
     {
         steps
         {
             sh "mvn clean package"
         }
     }
     stage('Execute Sonarqube Report')
     {
         steps
         {
            withSonarQubeEnv('Sonarqube-Server') 
             {
                sh "mvn sonar:sonar"
             }  
         }
     }
     stage('Quality Gate Check')
     {
         steps
         {
             timeout(time: 1, unit: 'HOURS') 
             {
                waitForQualityGate abortPipeline: true, credentialsId: 'SONARQUBE-CRED'
            }
         }
     }
     
     stage('Nexus Upload')
     {
         steps
         {
             script
             {
                 def readPom = readMavenPom file: 'pom.xml'
                 def nexusrepo = readPom.version.endsWith("SNAPSHOT") ? "wallmart-snapshot" : "wallmart-release"
                 nexusArtifactUploader artifacts: 
                 [
                     [
                         artifactId: "${readPom.artifactId}",
                         classifier: '', 
                         file: "target/${readPom.artifactId}-${readPom.version}.war", 
                         type: 'war'
                     ]
                ], 
                         credentialsId: 'Nexus-Cred', 
                         groupId: "${readPom.groupId}", 
                         nexusUrl: '3.82.213.203:8081', 
                         nexusVersion: 'nexus3', 
                         protocol: 'http', 
                         repository: "${nexusrepo}", 
                         version: "${readPom.version}"

             }
         }
     }
     stage('Login to AWS ECR')
     {
         steps
         {
             script
             {
                 sh "/usr/local/bin/aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com"
             }
         }
     }
     stage('Building Docker Image')
     {
         steps
         {
             script
             {
              sh "docker build . -t ${REPOSITORY_URI}:mavenwebapp-${COMMIT}"
             }
         }
     }
     stage('Pushing Docker image into ECR')
     {
         steps
         {
             script
             {
                 sh "docker push ${REPOSITORY_URI}:mavenwebapp-${COMMIT}"
             }
         }

     }
     stage('Update image in K8s manifest file')
     {
         steps
         {
             
                 sh """#!/bin/bash
                 sed -i 's/VERSION/$COMMIT/g' deployment.yaml
                 """
             }
         }
     
     stage('Deploy to K8s cluster')
     {
         steps
         {
             sh 'kubectl apply -f deployment.yaml --record=true'
             sh """#!/bin/bash
             sed -i 's/$COMMIT/VERSION/g' deployment.yaml
             """

         }
     }
 }

 post
 {
     always
     {
         cleanWs()
     }
     success
     {
        slackSend channel: 'build-notifications',color: 'good', message: "started  JOB : ${env.JOB_NAME}  with BUILD NUMBER : ${env.BUILD_NUMBER}  BUILD_STATUS: - ${currentBuild.currentResult} To view the dashboard (<${env.BUILD_URL}|Open>)"
        emailext attachLog: true, body: '''BUILD IS SUCCESSFULL - $PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS:
 
        Check console output at $BUILD_URL to view the results.
 
        Regards,
 
        Nithin John George
        ''', compressLog: true, replyTo: '<Your mail id>', 
        subject: '$PROJECT_NAME - $BUILD_NUMBER - $BUILD_STATUS', to: 'njdevops321@gmail.com'
     }
     failure
     {
         slackSend channel: 'build-notifications',color: 'danger', message: "started  JOB : ${env.JOB_NAME}  with BUILD NUMBER : ${env.BUILD_NUMBER}  BUILD_STATUS: - ${currentBuild.currentResult} To view the dashboard (<${env.BUILD_URL}|Open>)"
         emailext attachLog: true, body: '''BUILD IS FAILED - $PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS:
 
        Check console output at $BUILD_URL to view the results.
 
        Regards,
 
        Nithin John George
        ''', compressLog: true, replyTo: '<Your mail id>', 
        subject: '$PROJECT_NAME - $BUILD_NUMBER - $BUILD_STATUS', to: '<Your mail id>'
     }
 }

}

K8s manifest File (Deployment)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mavenwebapp-dp
  labels:
    app: mavenwebapp
spec:
  replicas: 4
  revisionHistoryLimit: 10
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 2
      maxUnavailable: 1
  minReadySeconds: 30
  selector:
    matchLabels:
       app: mavenwebapp
  template:
    metadata:
      name: mavenwebapp-pod
      labels:
        app: mavenwebapp
    spec:
      imagePullSecrets:
      - name: regcrd
      containers:
      - name: mavenwebapp-container
        image: <AWS_ACCOUNT_NUMBER>.dkr.ecr.us-east-1.amazonaws.com/mavenwebapp:mavenwebapp-VERSION
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
        resources:
          requests:
            cpu: 300m
            memory: 256Mi
          limits:
            cpu: 800m
            memory: 1Gi
 
---

apiVersion: v1
kind: Service
metadata:
  name: mavenwebapp-svc
spec:
  type: NodePort
  selector:
    app: mavenwebapp
  ports:
  - port: 8080
    targetPort: 8080
    nodePort: 30003

Docker File

FROM tomcat:8.0.20-jre8
 
COPY target/java-web-app*.war /usr/local/tomcat/webapps/java-web-app.war

About

Project on End to End CI/CD pipeline for java based application using Git,Github,Jenkins,Maven,Sonarqube,Nexus,Slack,Docker and Kuberenets with ECR as private docker registry and Zero Downtime Deployment.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published