Skip to main content

CI/CD Pipeline with Jenkins, Helm and Kubernetes

Written on February 19, 2018 by Ron Rivera.

2 min read
––– views

Nowadays it’s critical to get software releases out fast which requires having an automated CI/CD pipeline to perform testing and deployment to target environments. Implementing this pipeline has been challenging as this usually means engaging different infrastructure teams to get the environment ready and the release aritfacts deployed.

This is where Kubernetes comes into play. Kubernetes revolutionized the way we deploy and manage our containerized applications and makes CI/CD much easier.

This short post shows a sample Jenkins Pipeline that builds and tests a sample Django application packaged in a Docker image and deployed into a kubernetes cluster using helm.

The scripted pipeline has the following stages:

  1. Git checkout
  2. Build and run unit tests
  3. Run static code analysis
  4. Publish Docker image
  5. Deploy to kubernetes cluster
#!groovy
 
DOCKER_IMAGE_VERSION = "${utcIso8601()}"
DOCKER_NAMESPACE     = 'riverron'
DOCKER_IMAGE_NAME    = 'django-rest'
DOCKER_TARGET_IMAGE  = "${DOCKER_NAMESPACE}/${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_VERSION}"
gitRepoUrl           = 'https://github.com/roncrivera/django-rest.git'
 
node('linux') {
    ansiColor('xterm') {
 
        stage('Checkout code') {
            checkout([$class: 'GitSCM',
                branches: scm.branches,
                doGenerateSubmoduleConfigurations: false,
                extensions: [[$class: 'LocalBranch'], [$class: 'CleanCheckout']],
                submoduleCfg: [],
                userRemoteConfigs: [[credentialsId: 'pipeline-readonly', url: "${gitRepoUrl}"]]
            ])
        }
 
        try {
            withEnv(["DJANGO_TEST_RUN=1"]) {
                stage('Build Docker image') {
                    def dimg = docker.build("${DOCKER_TARGET_IMAGE}", "--no-cache .")
 
                    dimg.inside {
                        stage('Run unit tests') {
                            sh "coverage run gatekeeper/manage.py test gatekeeper -v2"
                        }
 
                        stage('Generate coverage report') {
                            sh "coverage xml"
                            stash name: 'coverage-report', includes: 'coverage.xml'
                        }
                    }
 
                    artifactoryDockerRegistry {
                        stage('Publish Docker image') {
                            dimg.push()
                            dimg.push('latest')
                        }
                    }
 
                    stage('Clean-up image') {
                        sh "docker rmi -f ${DOCKER_TARGET_IMAGE} || true"
                    }
 
                    currentBuild.result = 'SUCCESS'
                }
            }
        } catch (Exception err) {
            currentBuild.result = 'FAILURE'
        }
 
        stage('Static Code Analysis') {
            sonarQube {
                code_sources = '.'
                code_exclusions = 'gatekeeper/gatekeeper/static/**'
                python_coverage_report_path = 'coverage.xml'
            }
        }
 
        stage('Deploy to k8s cluster') {
            def branchName = sh(returnStdout: true, script: 'git rev-parse --abbrev-ref HEAD').trim()
 
            tiller_namespace = branchName == 'master' ? 'gatekeeper-dev' : 'playground'
 
            def credentialsId = "${tiller_namespace}-kubeconfig"
 
            withCredentials([[$class: "FileBinding", credentialsId: "${credentialsId}", variable: 'KUBECONFIG']]) {
                withEnv(["KUBECONFIG=${KUBECONFIG}", "TILLER_NAMESPACE=${tiller_namespace}", "PATH=$PATH:${helm_home}:${kubectl_home}"])  {
 
                    try {
                        if (branchName == "master") {
                            sh """
                                helm upgrade --install --set image.tag=${DOCKER_IMAGE_VERSION} --debug -f ./chart/values.development.yaml gatekeeper ./chart
                            """
                        } else {
                            sh """
                                helm upgrade --install --set image.tag=${DOCKER_IMAGE_VERSION} --debug -f ./chart/values.playground.yaml gatekeeper ./chart
                            """
                        }
 
                        currentBuild.result = 'SUCCESS'
 
                    } catch (Exception err) {
                        currentBuild.result = 'FAILURE'
                    }
 
                }
            }
        }
    }
}
Tweet this article

Join my newsletter

Get notified whenever I post, 100% no spam.

Subscribe Now