Cloud costs
January 27, 2022
min read

Migrating CD Jenkins Pipelines to Harness Using Helm


As a new team joining Harness with an existing product, we already had Continuous Integration/Continuous Deployment (CI/CD) pipelines built on Jenkins. I wanted to share our experience migrating to Harness CD. Spoiler alert: it was a snap! 

Looking back at our deployment solution before using Harness, we were stuck using a CI tool to perform basic CD functionally. After being freed of these trappings, it became clear that we had all of the symptoms of Stockholm syndrome. To highlight the differences, a comparison of features in CI/CD tools has been previously covered

Let's look at a basic overview of a Jenkins pipeline, which deploys nightly builds to a dev or QA environment for non-production use.

Basic Jenkins Pipelines Example

Our Jenkins CD pipeline utilized containers that were published from CI, as well as Helm charts/values from git. In our example, the pipeline deployed multiple services and a client app that will smoke test everything within a K8s namespace. Pretty standard stuff so far, but let's take a snippet from the Jenkins pipeline:

stage('Deploy to Nightly K8S') {
when {
expression { params.DEPLOY_TO_NIGHTLY == true }
steps {
script {

dir('runtime/serviceA') {
sh ( script:"/usr/local/bin/helm upgrade --install --atomic --timeout 10m -n ${nightly_namespace} -f ./helm/serviceA/nightly/nightly-values.yaml --set image.tag=${tagName} --set service.deploymentName=${tagName} ${backend_release} helm-repo/helm-chart")

Some of the stages within the Jenkins pipelines became wrappers for Helm, which uses the dynamic variables. In lieu of rich CD functionality in Jenkins, we instead relied on Helm to manage deployed versions and rollbacks. Using Jenkins for CD felt like playing a modern PC game on old hardware – it can be done, but it won’t be pretty!

Moving to Harness, No More Scripting!

Fortunately, we were positioned to move quickly to Harness based on a few of our best practices:

  • CI already published container images ready to run in a variety of environments.
  • We had mature Helm charts which reduced the logic within CD pipelines.
  • Environment specifics were stored in Helm values in a private git repository.

Now, let’s run down a Harness pipeline for an example service called the Collector:

Collector Service for Harness CD Pipeline

Harness was designed for this kind of deployment. Therefore, recreating the pipeline is simply a matter of basic configuration with no code! By using connectors, Harness defined and accessed the same components (e.g., containers, Helm charts, Helm values). The highlights above show the Manifest section containing both the Helm chart and Helm values, along with the location. The Artifact section contains all of the required container image configuration. Moreover, infrastructure is handled in the same way – set up a Kubernetes connector and select a namespace! 

And finally, the pipeline itself:

Harness CD Pipeline

That’s it! A single stage and a single step for this service! This particular pipeline gets triggered whenever a new container image gets published. Rollout deployments are just one example. Other complex deployments, such as Canary or Blue-Green, can be used without recreating the logic in a Jenkins pipeline or other tool.

Harness also has capabilities such as Continuous Verification, which can make sure that a deployment is healthy, and even recommend a rollback. When compared to Helm, which often relies on basic K8s probes at deployment time, Harness is deployment-aware to help the user make rollback decisions.

Bonus Tip: Harness Templing with Helm Values

Harness also has a templating engine. If you are familiar with Helm, templating in Harness works in a similar way. A common use case is to pass dynamic pipeline values to your Helm chart, which is often done with the command line arg set. However, it’s not always needed. The example below from a values.yaml file shows the use of Harness variables that then get replaced during pipeline execution.

installationKey: "<+serviceConfig.serviceDefinition.spec.variables.INSTALL_KEY>"
backendURL: <+serviceConfig.serviceDefinition.spec.variables.BACKEND_URL>

repository: harness/serviceB
tag: <+artifact.tag>

A basic case is to use the triggered artifact tag. However, other examples could be user input or environment-specific values. Another layer of templating never hurts! Take a look at the Built-in Harness Variable Reference for more examples.


Chances are, if your deployments are anything like how ours were, then you’re struggling to make do with a primitive CI tool for your cloud-native deployments. Moving to Harness will certainly give you the same “Aha!” experience that we had. 

When deploying with a product designed for CD from the ground up, things like Continuous Verification and Canary Deployments are not only possible, but also integrated within the solution offered by Harness. Now that your pipelines have gained enough XP to reach the next level, it’s time to upgrade that old PC and spend some of that time you’ll save with some next-gen gaming!

In the coming weeks, we'll share our experience moving our CI Jenkins pipelines over to Harness as well. We'll update this article with the link when it comes out!

Sign up now

Sign up for our free plan, start building and deploying with Harness, take your software delivery to the next level.

Get a demo

Sign up for a free 14 day trial and take your software development to the next level


Learn intelligent software delivery at your own pace. Step-by-step tutorials, videos, and reference docs to help you deliver customer happiness.

Case studies

Learn intelligent software delivery at your own pace. Step-by-step tutorials, videos, and reference docs to help you deliver customer happiness.

We want to hear from you

Enjoyed reading this blog post or have questions or feedback?
Share your thoughts by creating a new topic in the Harness community forum.

Sign up for our monthly newsletter

Subscribe to our newsletter to receive the latest Harness content in your inbox every month.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Continuous Delivery & GitOps