Skip to content

Deploying a Helm Chart with Jenkins ๐Ÿ—๏ธ

This tutorial walks through a declarative Jenkins pipeline (40-Jenkinsfile-helm) that orchestrates the deployment of a Helm chart across different environments (dev, qa, prod).

๐Ÿ“Š Pipeline Overview

Here is the high-level flow of our Helm deployment pipeline:

flowchart LR
    Jenkins["<img src='https://upload.wikimedia.org/wikipedia/commons/e/e9/Jenkins_logo.svg' width='30' /> Jenkins"] --> P[Pipeline]
    P -->|dev| H1["<img src='https://helm.sh/img/helm.svg' width='30' /> Helm (Dev)"]
    P -->|qa| H2["<img src='https://helm.sh/img/helm.svg' width='30' /> Helm (QA)"]
    P -->|prod| H3["<img src='https://helm.sh/img/helm.svg' width='30' /> Helm (Prod)"]

    H1 --> K1["<img src='https://upload.wikimedia.org/wikipedia/commons/3/39/Kubernetes_logo_without_workmark.svg' width='30' /> K8s"]
    H2 --> K2["<img src='https://upload.wikimedia.org/wikipedia/commons/3/39/Kubernetes_logo_without_workmark.svg' width='30' /> K8s"]
    H3 --> K3["<img src='https://upload.wikimedia.org/wikipedia/commons/3/39/Kubernetes_logo_without_workmark.svg' width='30' /> K8s"]

[!TIP] Prerequisites: Ensure that the Helm CLI is installed on the underlying Jenkins agent and correctly configured in your system's PATH.


๐Ÿ› ๏ธ Step-by-Step Breakdown

1. Configuration & Parameters

The pipeline begins by defining global options and the parameters required to trigger the build.

pipeline {
  agent any
  options {
    disableConcurrentBuilds()
    disableResume()
    buildDiscarder(logRotator(numToKeepStr: '10'))
    timeout(time: 1, unit: 'HOURS')
  }
  parameters {
    choice(name: 'ENVIRONMENT', choices: ['dev', 'qa', 'prod'], description: 'Choose Environment to deploy')
    string(name: 'IMAGE_TAG', defaultValue: '1.0', description: 'Docker image tag to deploy')
  }
  • disableConcurrentBuilds(): Prevents multiple jobs from running simultaneously, avoiding race conditions during deployment.
  • Parameters:
  • ENVIRONMENT determines the target deployment destination.
  • IMAGE_TAG specifies which version of the Docker container should be deployed in the Helm chart.

2. Environment Variables

  environment {
    HELM_CHART_PATH = "deployment/helm-chart"
    RELEASE_NAME    = "hello-world"
  }

Defining these as global variables ensures that we have a single source of truth for the chart's path and release name, making maintaining the script much easier.

3. Deployment Stages

The pipeline utilizes when conditions to strictly execute only the stage corresponding to the selected environment parameter.

  stages {
    stage('Deploy to Dev') {
      when { environment name: 'ENVIRONMENT', value: 'dev' }
      steps {
        sh """
          helm upgrade --install ${RELEASE_NAME} ${HELM_CHART_PATH} \
            -f ${HELM_CHART_PATH}/values-dev.yaml \
            --set image.tag=${params.IMAGE_TAG} \
            --namespace dev --create-namespace
        """
      }
    }
    // (Similar stages exist for QA and Prod)
  }
  • helm upgrade --install: This crucial command installs the chart if it doesn't exist, and upgrades it if it does.
  • -f values-dev.yaml: Injects environment-specific configuration values (like replica counts or specific DB URLs).
  • --set image.tag: Overrides the image tag dynamically during the pipeline run using our input parameter.

[!TIP] Always use upgrade --install in CI/CD pipelines as it securely handles both first-time deployments and subsequent updates without failing.

4. Post Cleanup

  post {
    always {
      deleteDir()
    }
  }
}

The always block ensures that the Jenkins workspace is wiped clean after every run, avoiding disk bloat or residual state.


๐Ÿง  Knowledge Check

#

What is the advantage of using helm upgrade --install in a pipeline?

#

How does the pipeline ensure only one deployment happens at a time to prevent conflicts?

#

How do you override the image tag locally injected by the Jenkins parameter during the deployment?

๐Ÿ“ฌ DevopsPilot Weekly โ€” Learn DevOps, Cloud & Gen AI the simple way.
๐Ÿ‘‰ Subscribe here