Operations 11 min read

Implementing CI/CD Pipelines for Microservices with Jenkins, GitLab Webhooks, and GitOps

This article provides a detailed guide on implementing CI/CD pipelines for microservices using Jenkins, GitLab webhooks, and GitOps, covering repository setup, pipeline stages, code snippets for Jenkinsfiles, webhook configuration, image building, and deployment with Helm in a cloud‑native environment.

DevOps Cloud Academy
DevOps Cloud Academy
DevOps Cloud Academy
Implementing CI/CD Pipelines for Microservices with Jenkins, GitLab Webhooks, and GitOps

CI Continuous Integration

First, download the code repository from GitHub . The CI pipeline must identify which service a commit belongs to, download its code, compile, test, scan, and build a Docker image.

The commit‑service mapping is achieved by connecting GitLab WebHook with a Jenkins job trigger. When code is pushed to GitLab, a POST request containing JSON data is sent to Jenkins, which parses the JSON to extract the changed service modules.

CI‑Scheduler Job

The scheduler job only needs to enable the webhook and configure a unique token, generating a hook URL such as

http://jenkins.idevops.site/generic-webhook-trigger/invoke?token=microservicecicd-scheduler-CI

.

pipeline {
  agent any
  stages {
    stage("GetData") {
      steps {
        script {
          echo "${webHookData}"
          data = readJSON text: "${webHookData}"
          env.branchName = data.ref - "refs/heads/"
          env.commitId = data.checkout_sha
          env.projectId = data.project_id
          commits = data["commits"]
          // extract changed services
          changeServices = []
          for (commit in commits) {
            // added, modified, removed files
            // ... (logic omitted for brevity)
          }
        }
      }
    }
    // other stages omitted for brevity
  }
}

GitLab WebHook Configuration

Enable the webhook in GitLab and set the hook URL to the same token‑based endpoint used by the CI‑Scheduler.

CI Job for Each Microservice

Each microservice has a CI job with three string parameters: branch name, commit ID, and project ID. The job checks out the specific module using sparse checkout, builds with Maven, runs unit tests, performs SonarQube scanning, builds a Docker image, and pushes it to a private registry.

String branchName = "${env.branchName}"
String moduleName = "${JOB_NAME}".split("/")[1].split("-")[1]
String srcUrl = "http://gitlab.idevops.site/microservicecicd/microservicecicd-demo-service.git"
String commitId = "${env.commitId}"
String projectId = "${env.projectId}"

pipeline {
  agent { node { label "build" } }
  stages {
    stage('GetCode') { /* checkout code */ }
    stage('Build&Test') { /* mvn clean package */ }
    stage('SonarScan') { /* sonar-scanner command */ }
    stage('BuildImage') { /* docker build & push */ }
  }
}

GitOps – CI Extension

After pushing the Docker image, the pipeline updates the environment repository (GitOps) by modifying the values.yaml file with the new image tag and commit ID, then commits the change back to GitLab.

stage("PushFile") {
  script {
    if ("${env.branchName}".contains("RELEASE-")) {
      env.branchName = "master"
    } else {
      env.branchName = "feature"
    }
    // download, modify, and update values.yaml
    response = GetRepoFile(40, "${moduleName}%2fvalues.yaml", "${env.branchName}")
    yamlData = readYaml text: "${response}"
    yamlData.image.version = "${releaseVersion}-${env.nowDate}"
    yamlData.image.commit = "${commitId}"
    // commit back to GitLab
    base64Content = newYaml.bytes.encodeBase64().toString()
    UpdateRepoFile(40, "${moduleName}%2fvalues.yaml", base64Content, "${env.branchName}")
  }
}

GitOps – CD Part

The CD‑Scheduler job also receives GitLab webhook requests, but from the environment repository. It triggers CD jobs for the services that changed.

pipeline {
  agent any
  stages {
    stage('GetCommitService') { /* parse webhook JSON */ }
    stage('DefineService') { /* trigger microservice‑CD jobs */ }
  }
}

CD Job for a Service

The CD job checks out the environment repository, creates a namespace, and deploys the service with Helm (install or upgrade). It lists Helm releases and history for verification.

String serviceName = "${JOB_NAME}".split("-")[1]
String nameSpace = "${JOB_NAME}".split("-")[0].split("/")[-1]

pipeline {
  agent { node { label "k8s" } }
  stages {
    stage('GetCode') { /* checkout env repo */ }
    stage('HelmDeploy') {
      steps {
        sh "kubectl create ns ${nameSpace}-uat || echo false"
        sh "helm install ${serviceName} --namespace ${nameSpace}-uat ./... || helm upgrade ${serviceName} --namespace ${nameSpace}-uat ./..."
        sh "helm list --namespace ${nameSpace}-uat"
        sh "helm history ${serviceName} --namespace ${nameSpace}-uat"
      }
    }
  }
}

Overall, the guide walks through setting up CI and CD pipelines, integrating GitLab webhooks, automating Docker image builds, applying GitOps for environment updates, and deploying services with Helm in a Kubernetes cluster.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

DevOpsGitLabCIGitOpsJenkins
DevOps Cloud Academy
Written by

DevOps Cloud Academy

Exploring industry DevOps practices and technical expertise.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.