Your cluster is bound to run quite a few third-party applications. They need to be installed and managed somehow. This article offers one possible way to install and maintain third-party applications using Jenkins X Apps. We’ll use Istio as an example of such an application and try to figure out how to convert its official Helm charts into Jenkins X Apps and, during that process, explore some of the benefits they provide.
If you hope to run the examples in this article, you’ll need a Kubernetes cluster with Jenkins X installed using Jenkins X Boot.
If you read Istio documentation, you’ll discover that two charts need to be installed;
istio. You’ll also find out that the repository where the charts are stored is available from https://storage.googleapis.com/istio-release/releases/1.3.2/charts/. Given than one Jenkins X App references one Helm chart, we’ll need to add two Apps; one for
istio-init and the other for
istio. Equipped with that knowledge, we can add the first of the two Apps. The command is as follows.
jx add app istio-init \ --repository https://storage.googleapis.com/istio-release/releases/1.3.2/charts/
Just as before, the output of that command will differ depending on whether you used Jenkins X Boot with the
dev repo, or you didn’t.
You should see the link to the newly created pull request. Open it and click the Files changed tab so that we review the suggested changes.
istio-init, the same files changed as with Prometheus, except that two (of three) are in different directories.
env/istio-init/README.MD file contains information about the App and the whole README from the original chart. Next, we have
env/istio-init/templates/app.yaml that is the definition of the App, with the information about the repository
jenkins.io/chart-repository, the name of the chart (
jenkins.io/app-name), and the version(
istio-init was added together with other dependencies in
As you can see, it does not matter much whether an App was added from the catalog of those supported by the Jenkins X community, or from any available Helm chart. In all the cases, it is based on a Helm chart, and as long as Jenkins X has the information about the name, version, and the repository where the chart resides, it will convert it into an App.
To finish the process, please select the Conversation tab, and click Merge pull request, followed with the Confirm Merge button. As you already know, that will trigger a webhook that will notify the cluster that there is a change in one of the repositories and, as a result, a new pipeline activity will be created.
CLUSTER_NAME=[...] # Replace `[...]` with the name of your cluster jx get activity \ --filter environment-$CLUSTER_NAME-dev/master \ --watch
Press ctrl+c to stop watching the activity once it is successfully finished.
Finally, we’ll confirm that
istio-init was installed correctly by outputting the Custom Resource Definitions (CRDs) that contain
istio.io in their name. If you’re not familiar with Istio, all that
istio-init does is install those CRDs. The rest of the setup comes afterward.
kubectl get crds | grep 'istio.io'
Unless Istio changed since the time I wrote this (October 2019), there should be twenty-three CRDs in the output, and we can conclude that the first part of the Istio setup was done correctly.
That’s it. You saw how you can create Jenkins X Apps through the
jx add app command. We also explored how those Apps can be updated or removed. If you’re using the
dev repository, you saw some of the benefits of the Apps, mainly their support for GitOps processes. Every time an App is added or removed,
jx creates a new branch and a pull request, and it waits for you to review and approve the changes by merging it to the master.
In some cases, however, you might want to skip reviewing and merging pull requests. You might want to let Jenkins X do that for you, as well. In such cases, you can add the
--auto-mergeargument might not work due to the issues 5761. Feel free to monitor it to see whether it was resolved.
You should understand that
jx add app and
jx delete app commands are only manipulating files in the
dev repository and pushing them to Git. Everything else is done by Jenkins X running in the cluster. That means that you do not have to use those commands. Think of them more as "helpers" than as requirements for working with Apps. We can accomplish the same without them. We can create the files we need and push them to Git. As a result, a new App will be added without us executing any command (excluding
We still need to apply the second chart (
istio), so we’ll use that as an excuse to try to add an App without executing
Since we are about to create and modify a few files in the local copy of the
dev repository, we should start by pulling the latest codebase from GitHub.
Now that we have a local copy of the latest version of the repository, we can create a new App. Remember, this time, we’re exploring how to do that by creating the files ourselves instead of using the
jx add app command.
We can approach this challenge from two directions. One option could be to create all the files from scratch. The other is to copy a directory of one of the existing Apps and modify it to suit our needs. We’ll go with the second option since it is probably an easier one. Given that we already have the App that’s using
istio-init, its files are probably the best candidate to be used as the base for
cp -r env/istio-init env/istio
Now that we copied the
istio-init directory as
istio, all we have to do is change a few files. We’ll skip modifying the README. It is important only for humans (we might read it), but it plays no role in the process. In the "real world" situations, I’d expect you to change it as well. But since this is not the "real world" but rather a learning experience, there’s no need for us to spend time with it.
There are three files that we might need to change. We might create
env/istio/templates/values.yaml if we’d like to change any of the chart’s default values. We’ll skip that one because
istio is good as-is. Instead, we’ll focus on the other two files.
That’s the definition of the App we’re about to add to the cluster. It is a copy of
istio-init, so all we need to do is change the
name values from
istio. We’ll also change
jenkins.io/chart-description. It serves only informative purposes. But, since we’re nice people and don’t want to confuse others, changing it might provide additional clarity to whoever might explore it later.
The command that should make those changes is as follows.
cat env/istio/templates/app.yaml \ | sed -e 's@istio-init@istio@g' \ | sed -e \ 's@initialize Istio CRDs@install Istio@g' \ | tee env/istio/templates/app.yaml
The definition of an App is useless by itself. Its existence will not result in it running inside the cluster. We need to add it as yet another dependency in
env/requirements.yaml. So, let’s take a quick peek at what’s inside it.
The output is a follows.
dependencies: - name: jxboot-resources repository: http://chartmuseum.jenkins-x.io - alias: tekton name: tekton repository: http://chartmuseum.jenkins-x.io - alias: prow condition: prow.enabled name: prow repository: http://chartmuseum.jenkins-x.io - alias: lighthouse condition: lighthouse.enabled name: lighthouse repository: http://chartmuseum.jenkins-x.io - name: jenkins-x-platform repository: http://chartmuseum.jenkins-x.io - name: istio-init repository: https://storage.googleapis.com/istio-release/releases/1.3.2/charts/ version: 1.3.2
All but the last dependency are those of the system at its default configuration. Later on, we used
jx add app to add
istio-init to the mix. Now we’re missing an entry for
istio as well. The
repository and the
version are the same, and the only difference is in the
echo "- name: istio repository: https://storage.googleapis.com/istio-release/releases/1.3.2/charts/ version: 1.3.2" \ | tee -a env/requirements.yaml
All that’s left is to push the changes to GitHub and let the system converge the actual into the desired state, which we just extended with an additional App. Normally, we’d create a branch, push the changes there, create a pull request, and merge it to the master branch. That would be the correct way to handle this or any other change. But, in the interest of time, we’ll skip that with the assumption that you already know how to create PRs. If you don’t, you’re in the wrong industry.
git add . git commit -m "Added Istio" git push jx get activity \ --filter environment-$CLUSTER_NAME-dev/master \ --watch
We committed and pushed the changes to the master branch and started watching the activities to confirm that the changes are applied to the cluster. Once the new activity is finished, please press ctrl+c to stop watching.
Istio should be fully up-and-running. We can confirm that by listing all the Pods that contain
istio in their names.
kubectl get pods | grep istio
This is neither the time nor the place to dive deeper into Istio. That was not the goal. I used it only as an example of different ways to add Jenkins X Apps to the system.
Speaking of the Apps, let’s see which ones are currently running in the cluster. You already saw that
jx has a helper command for almost anything, so it should be no surprise to find out that retrieving the
apps is available as well.
jx get apps
The output is as follows, at least for those who installed Jenkins X using the Boot.
Name Version Chart Repository Namespace Status Description istio-init 1.3.2 https://storage.googleapis.com/istio-release/releases/1.3.2/charts/ READY FOR DEPLOYMENT Helm chart to initialize Istio CRDs istio 1.3.2 https://storage.googleapis.com/istio-release/releases/1.3.2/charts/ READY FOR DEPLOYMENT Helm chart to install Istio
That’s it. We explored a few commonly used ways to add, manage, and delete Jenkins X Apps. We’ll have a short discussion around them soon. For now, we’ll remove
istio-init since we do not need them anymore.
git pull jx delete app istio
You know what to do next. Merge the PR so that the change (
istio removal) is applied to the system. We can see that through the proposed changes to the
You’ll notice that the
jx delete app command works no matter whether the App was added through
jx add app or by fiddling with the files directly in Git. It always operates through Git (unless you are NOT using the
The next in line for elimination is
istio-init, and the process is the same.
git pull jx delete app istio-init
I’ll leave you to do the rest yourself (if you’re using the Boot). Merge that PR!
That’s it. You learned the basics of extending the Jenkins X platform by adding Apps. As a matter of fact, it’s not only about extending Jenkins X but more about having a reliable way to add any third-party application to your cluster. However, not all are equally well suited to be Jenkins X Apps.
Jenkins X Apps are beneficial for at least two scenarios. When we want to extend Jenkins X, adding Apps is, without a doubt, the best option. Given that the Apps can be any Helm chart, we can convert any application to be an App.
Besides those designed to extend Jenkins X, excellent candidates are the charts that do not need to be in multiple repositories. For example, if we’d like to run two instances of Prometheus (one for testing and the other for production), we’re better of adding them to the associated permanent environment repositories. However, many are not well suited to run in testing or are not worth validating. Prometheus might be such a case. If we upgrade it and that turns out to be a bad choice, no harm will be done to the cluster. We might not be able to retrieve some metrics, but that would be only temporary until we roll back to the previous version. The exception would be if we hook HorizontalPodAutoscaler to Prometheus metrics, in which case testing it before deploying a new version to production is paramount. So, when applications should run only in production (without a second instance used for testing), Apps are a better way to manage them due to a few additional benefits they provide.
At the core, Jenkins X Apps follow the same GitOps principles as any other. Their definitions are stored in Git, we can create pull requests and review changes, and only a merge to the master branch will change the state of the cluster. Using Apps is not much different from defining dependencies in staging, production, or any other permanent environment repository. What makes them "special" is the addition of a few helper features and a few conventions that make management easier. We have a better-defined pipeline. Branches and pull requests are created automatically. Secrets are stored in Vault. Dependencies are better organized. And so on, and so forth. We explored only a few of those features. Later on, we’ll see a few more in action, and the community is bound to add more over time.
The DevOps 2.6 Toolkit: Jenkins X
The article you just read is an extract from The DevOps 2.6 Toolkit: Jenkins X.
You can get the book from Amazon, LeanPub, or look for it through your favorite book seller.
I’d like to convert wordpress helm from the following repository but getting error.
~$ jx add app wordpress –repository https://github.com/helm/charts/tree/master/stable/wordpress
Adding missing Helm repo: github.com https://github.com/helm/charts/tree/master/stable/wordpress
error: adding helm repo: failed to add the repository ‘github.com’ with URL ‘https://github.com/helm/charts/tree/master/stable/wordpress’: failed to run ‘helm repo add github.com https://github.com/helm/charts/tree/master/stable/wordpress‘ command in directory ”, output: ‘Error: Looks like “https://github.com/helm/charts/tree/master/stable/wordpress” is not a valid chart repository or cannot be reached: Failed to fetch https://github.com/helm/charts/tree/master/stable/wordpress/index.yaml : 404 Not Found’
You referenced the code repository instead the repository where the chart is stored. Stable charts are in https://kubernetes-charts.storage.googleapis.com. Please use that one as the value of `–repository` and let me know how it went.