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.
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') {
script{
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!
Fortunately, we were positioned to move quickly to Harness based on a few of our best practices:
Now, let’s run down a Harness pipeline for an example service called the Collector:
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:
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.
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.
config:
installationKey: "<+serviceConfig.serviceDefinition.spec.variables.INSTALL_KEY>"
backendURL: <+serviceConfig.serviceDefinition.spec.variables.BACKEND_URL>
image:
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!