Setup Continuous Integration for Helm chart

Intakhab Ali
5 min readSep 7, 2019

--

Introduction:

Helm is a package manager for Kubernetes that allows developers and operators to more easily package, configure, and deploy applications and services onto Kubernetes clusters.

Helm is now an official Kubernetes project and is part of the Cloud Native Computing Foundation, a non-profit that supports open source projects in and around the Kubernetes ecosystem.

In this tutorial, we will Setup a continuous integration of helm chart, here we will package the helm chart with the help of CI tool like(Travis, Jenkins) and push it to chart registry like(Harbor, Chartmuseum,

Prerequisites:

  • Registry to store helm like Harbor or Chartmuseum
  • knowledge of helm and any of CI platform(Travis, Jenkins, circle ci)
  • A Git Repository to maintains version control of helm chart

I am going to use Travis as a CI platform and Harbor as a helm registry to host the helm.

As I choose Travis here, .travis.yml consist of job lifecycle, let us write job cycle for the helm chart

Lifecycle 1:

choose base language python

---
language: python

we need to have some environment variable so that we can update whenever new version of the Helm release or change the registry URL

here is the list of a variable we need

HELM_URL=https://storage.googleapis.com/kubernetes-helm(this url where we can download the helm package)

HELM_TGZ=helm-v2.4.2-linux-amd64.tar.gz(it is the helm tar file name)

REPO_DIR=/home/travis/build/inyee786/test-helm (this is path where travis keep git folder)

YAMLLINT_VERSION=1.8.1(this is yamllint version use to check lint of file)

HARBOR_CHART_URL=https://harbor-test.mayadata.io/chartrepo ( change it according to you chart registry url{harbor or Chartmuseum}

HARBOR_PROJECT_NAME=maya (this is Harbor project name where we will store the chart)

CHART_FOLDER=charts (this is folder name where we can keep the helm charts

It looks like this

env:
global:
- HELM_URL=https://storage.googleapis.com/kubernetes-helm
- HELM_TGZ=helm-v2.4.2-linux-amd64.tar.gz
- REPO_DIR=/home/travis/build/inyee786/test-helm
- YAMLLINT_VERSION=1.8.1
- HARBOR_CHART_URL=https://harbor-test.mayadata.io/chartrepo
- HARBOR_PROJECT_NAME=maya
- CHART_FOLDER=charts

we need some private where we can store the credential to push to helm registry(Harbor has a very good feature where we can have bot user, you can use the bot credential ). we have to put the

HARBOR_USERNAME:
HARBOR_PASSWORD:

Inside Travis go to (settings > Environment Variables )to set the private env

Lifecycle 2 :

Install the Prerequisites to Setup a CI environment to build and check the yaml lint.

Download helm and untar the chart after downloading

  • wget ${HELM_URL}/${HELM_TGZ}
  • tar xzfv ${HELM_TGZ}
  • PATH=`pwd`/linux-amd64/:$PATH

initialise the helm client and update the helm repo

  • helm init — client-only
  • helm repo update

install helm plugin to push chart on the registry

install yamllint python package to check the lint

  • sudo pip install yamllint==”${YAMLLINT_VERSION}”

It looks like below config

install:
# Installing Helm
- wget ${HELM_URL}/${HELM_TGZ}
- tar xzfv ${HELM_TGZ}
- PATH=`pwd`/linux-amd64/:$PATH
- helm init --client-only
# helm plugin to push helm chart
- helm plugin install https://github.com/chartmuseum/helm-push --version v0.7.1
# Installig pip deps
- sudo pip install yamllint=="${YAMLLINT_VERSION}"
- helm repo update

Lifecycle 3 :

Before going forward to build a chart we need to run some script to check the lint in chart and Travis file. It is good practice to check the lint

check the helm lint of all helm chart

  • for dir in `ls ${REPO_DIR}/${CHART_FOLDER}`; do
    helm lint ${REPO_DIR}/${CHART_FOLDER}/$dir
    if [ $? != 0 ]; then
    travis_terminate 1
    fi

To check the yaml lint for travis.yml, chart.yaml and value.yaml we use yamllint python package and we need arule to check the lint.

  • yamllint -c .yamllint.yml -s .travis.yml .yamllint.yml
  • yamllint -c .yamllint.yml -s $(find . -type f -name “Chart.yaml”)
  • yamllint -c .yamllint.yml -s $(find . -type f -name “values.yaml”)

The script section should look like the below config

script:
# Check charts format
- >
for dir in `ls ${REPO_DIR}/${CHART_FOLDER}`; do
helm lint ${REPO_DIR}/${CHART_FOLDER}/$dir
if [ $? != 0 ]; then
travis_terminate 1
fi
done
# Check YAML styling
- yamllint -c .yamllint.yml -s .travis.yml .yamllint.yml
- yamllint -c .yamllint.yml -s $(find . -type f -name "Chart.yaml")
- yamllint -c .yamllint.yml -s $(find . -type f -name "values.yaml")

Here comes the interesting part where we are going to build and package the chart.

Lifecycle 4:

It’s better to build and push to when we merge the chart in the master branch. so we run below command when we merge the chart in the master branch

we need a temporary directory where we will build and package the chart

  • BUILD_DIR=$(mktemp -d)

Run a loop to all the charts to build, package and push it to the registry. The commands below will run on each charts

  • helm dep update ${REPO_DIR}/${CHART_FOLDER}/$dir

Package the chart with the below command

  • helm package ${REPO_DIR}/${CHART_FOLDER}/$dir

Then push the chart to registry

  • helm push — username ${HARBOR_USERNAME} — password ${HARBOR_PASSWORD} ${REPO_DIR}/${CHART_FOLDER}/$dir ${HARBOR_CHART_URL}/maya

below is the config look like

# Temporary dir for storing new packaged charts and index files
BUILD_DIR=$(mktemp -d)
# Push temporary directory to the stack
pushd $BUILD_DIR
# Iterate over all charts are package them push it to Harbor
for dir in `ls ${REPO_DIR}/${CHART_FOLDER}`; do
helm dep update ${REPO_DIR}/${CHART_FOLDER}/$dir
helm package ${REPO_DIR}/${CHART_FOLDER}/$dir
helm push --username ${HARBOR_USERNAME} --password ${HARBOR_PASSWORD} ${REPO_DIR}/${CHART_FOLDER}/$dir ${HARBOR_CHART_URL}/maya
if [ $? != 0 ]; then
travis_terminate 1
fi
done
# Pop temporary directory from the stack
popd

wow, we completed all the step now our setup is ready to build and push the helm chart to registry

Here is the full Travis file

https://gist.github.com/inyee786/d779f347d7fa272aed4ee8457182af35.js

Here is .yamllint.yml file which contains lint rule for charts.yaml values.yaml and .travis.yaml

https://gist.github.com/inyee786/ef15b05c98bb4761b41af5f4fe268239.js

Conclusion:

  • Here we packaged the helm chart and push it to helm registry

About me

You can follow me at the below profiles and can ask any questions related to Angular, JavaScript, Travis, Kubernetes, etc.

--

--

Intakhab Ali

Javascript is in my veins and DevOps is in my Nature #javascript_developer