jenkins-gitops-deploy-k8s / Jenkinsfile
Jenkinsfile
Raw
pipeline {
    agent any
    options {
        buildDiscarder(logRotator(numToKeepStr: '5'))
    }
    tools {
        jdk 'jdk-17'
        maven 'maven'
    }
    environment {
        SERVER_IP=""
        DOCKERHUB_CREDENTIALS=credentials('dockerhub')
        IMAGE_REPO="agnes4im/demo-app"
        SCANNER_HOME=tool 'sonar-scanner'
    }
    def gv
    stages {
        stage('Load groovy script') {
            steps {
                script {
                    echo 'loading groovy script...'
                    gv = load "script.groovy"
                }
            }
        }
        stage("Provision Kubernetes Cluster") {
            environment {
                TF_VAR_jenkins_ip = ""
            }
            steps {
                script {
                    echo 'provisioning cluster ...'
                    dir('terraform-dir') {
                        withAWS(credentials: 'aws-creds', region: 'us-east-1') {
                            sh 'terraform init'
                            sh 'terraform apply --auto-approve'  
                        }
                    }     
                }
            }
        }
        stage('Increment application version') {
            steps {
                script {
                    echo 'incrementing app version...'
                    dir('app/spring-petclinic') {
                        sh ''' mvn build-helper:parse-version versions:set \
                               -DnewVersion=\\\${parsedVersion.majorVersion}.\\\${parsedVersion.minorVersion}.\\\${parsedVersion.nextIncrementalVersion} \ 
                               versions:commit '''
                        def matcher = readfile('pom.xml') =~ '<version>(.+)</version>'
                        def version = matcher[0][1]
                        IMAGE_TAG = "$version-$BUILD_NUMBER"
                    }
                }
            }
        }
        stage('Compile source code...') {
            steps {
                script {
                    echo "compiling source code..."
                    dir('app/spring-petclinic') {
                        sh 'mvn clean compile'
                    }
                }
            }
        }
        stage('Run test...') {
            steps {
                script {
                    echo "running tests on source code..."
                    dir('app/spring-petclinic') {
                        sh 'mvn clean test'
                    }
                }
            }
        }
        stage('SonarQube Analysis') {
            steps {
                script {
                    echo "running analysis on source code..."
                    dir('app/spring-petclinic') {
                        withSonarQubeEnv('sonar-server') {
                            sh ''' $SCANNER_HOME/bin/solar-scanner -Dsonar.ProjectName=Petclinic \
                                -Dsonar.java.binaries=. \
                                -Dsonar.ProjectKey=Petclinic '''
                        }
                    }
                }
            }
        }
        stage('Build jar') {
            steps {
                script {
                    echo "building jar..."
                    dir('app') {
                        sh 'mvn clean package'
                    }
                }
            }
        }
        stage('OWASP Dependency Check') {
            steps {
                script {
                    echo "Running dependency check on jar file..."
                    dependencyCheck additionalArguments: '--scan app/target/' odcInstallation: 'owasp'
                        dependencyCheckPublisher pattern: '**/dependency-check-report.xml'
                }
            }
        }
        stage('Build docker image') {
            steps {
                echo 'building docker image'
                sh "docker build -t ${IMAGE_REPO}:${IMAGE_TAG} ."
            }
        }
        stage('Trivy scan of docker image') {
            steps {
                echo 'running Trivy scan on docker image ...'
                sh "trivy image ${IMAGE_REPO}:${IMAGE_TAG}"
            }
        }
        stage('Login to dockerhub') {
            steps {
                echo 'login to dockerhub ...'
                sh "echo $DOCKERHUB_CREDENTIALS_PSW | docker login -u $DOCKERHUB_CREDENTIALS_USR --password-stdin"
            }
        }
        stage('Push docker image') {
            steps {
                echo 'pushing docker image ...'
                sh "docker push ${IMAGE_REPO}:${IMAGE_TAG}"
            }
        }
        stage('Deploy docker image') {
            steps {
                script {
                    echo 'deploying image to cluster...'
                    environment {
                        APP_NAME = 'demo-app'
                    }
                    withAWS(credentials: 'aws-creds', region: 'us-east-1') {
                        def cluster_name = 'demo-cluster'
                        sh "aws eks update-kubeconfig --name ${cluster_name}"   // Will need aws cli and kubectl installed on Jenkins server
                        sh 'envsubst < yaml-file/config.yaml | kubectl apply -f -' 
                    }
                }
            }
        }
        stage('Update Git') {
            steps {
                script {
                    echo "commiting changes to github..."
                    withCredentials([usernamePassword(credentialsId: 'github-creds', passwordVariable: 'PASS', usernameVariable: 'USER')]) {
                        sh 'git config --global user.emal "jenkins@examle.com"'
                        sh 'git config --global user.name "jenkins"'
                        sh "git remote set-url origin https://${USER}:${PASS}@github.com/Agnes4Him/jenkins-gitops-demo.git"
                        sh 'git add .'
                        sh 'git commit -m "Implementing version bump"'
                        sh 'git push origin HEAD:main'  // This would be 'git push origin HEAD:name_of_build_branch' in GitOps
                    }
                }
            }
        }
    }
    post {
        always {
            sh 'docker logout'
        }
        changed {
            // Send email notification on build failure
            script {
                if (currentBuild.currentResult == 'FAILURE') { 
                    emailext subject: '$DEFAULT_SUBJECT',
                        body: '$DEFAULT_CONTENT',
                        recipientProviders: [
                            [$class: 'CulpritsRecipientProvider'],
                            [$class: 'DevelopersRecipientProvider'],
                            [$class: 'RequesterRecipientProvider'] 
                        ], 
                        replyTo: '$DEFAULT_REPLYTO',
                        to: '$DEFAULT_RECIPIENTS'
                }
            }
        }
    }
}