Using Jenkins pipelines to implement CI/CD on Red Hat OpenShift
Jenkins is a well established tool, largely used in CI/CD and DevOps implementations and, even though new and modern tools (e.g.: OpenShift pipelines, based on Tekton) are surfacing in this space, it can still make the job and is nicely integrated in OpenShift as well.
Before you start
You can just read through the article to gain a general understanding about how Jenkins can be deployed and used in OpenShift but if you prefer to follow along and actually try the technology yourself you will firstly need to have access to an OpenShift installation.
You can use whatever OpenShift service or installation you are more familiar with, I used IBM Cloud ROKS with a 4.4 version cluster. ROKS stands for “Red Hat OpenShift on Kubernetes Services”, a managed service provided by IBM Cloud.
Architecture
To show how you can use Jenkins to build and deploy containerized applications to OpenShift, I will use Windfire Restaurant Backend service component, which I developed in Node.js: you can find the code in my GitHub repository here.
The overall architecture is drawn in the following figure
As it can be seen, the architecture and use case scenario are quite straightforward:
- Jenkins gets instantiated and runs in a dedicated OpenShift project, called jenkins;
- a second project, called windfire, has been created to deploy and run the actual application artifacts;
- a webhook has been defined in the GitHub repository that holds the code for the application: it is triggered every time a push event is sent;
- an OpenShift BuildConfig of type JenkinsPipeline, called windfire-restaurants-node-pipeline, is created in windfire project: this is what starts the build and deployment process, once it gets triggered by the webhook (have a look at how the BuildConfig is configured here).
- whenever BuildConfig is triggered it runs a Jenkins Pipeline (have a look at how is defined here), which uses an appropriate OpenShift template, called windfire-restaurants-backend (have a look at how it is defined here), to build and deploy the application.
Instantiate Jenkins
Firstly I deployed a Jenkins instance; OpenShift provides a ready-to-use template that very easily allows to instantiate and run a containerized Jenkins.
- Create a new OpenShift project, you can call it whatever you want, lacking fantasy I called it, surprise surprise, jenkins
oc new-project jenkins
- Instantiate Jenkins in the project you just created with the following command
oc new-app --name jenkins --template jenkins-ephemeral -p MEMORY_LIMIT=2048Mi
this uses the native OpenShift way to instantiate applications, the oc new-app command, by taking a ready-to-use template (jenkins-ephemeral)
- Finally, you need to grant Jenkins edit role in OpenShift projects where it will need to run and deploy stuff; in our case the application is deployed to windfire project, so issue the following
oc policy add-role-to-user edit system:serviceaccount: jenkins:jenkins -n windfire
Once Jenkins is running, you will need to do just a final boring preparatory step and configure which projects Jenkins is allowed to sync BuildConfig from. To do this, open Jenkins UI console, go to Manage Jenkins → System Configuration → OpenShift Jenkins Sync and set Namespace appropriately, as in the following example
Now you are set to go and can start actually using Jenkins.
Build and Deployment process implementation
OpenShift has a very peculiar way to manage application build and deployment processes, based on BuildConfigs that can have different strategies, one being jenkinsPipelineStrategy which, not surprisingly, delegates the actual process execution to a Jenkins pipeline.
The modern versions of Jenkins make use of an “as-a-code” approach, allowing to describe what the pipeline should do in a file, which by default is called Jenkinsfile.
Create a “Jenkins Pipeline Strategy” BuildConfig
Create a yaml file (e.g.: buildconfig.yaml) with the following content to define a BuildConfig for Windfire Restaurant backend application component
Jenkins Pipeline Strategy for OpenShift BuildConfig just requires you to indicate:
1. GitHub repository and branch where it must search for Jenkinsfile
2. jenkinsFilePath: the path where Jenkins can find the file which describes what the pipeline needs to do; in our case is simply set to Jenkinsfile at the root of the source code repository (you can have a look at the Jenkinsfile used to build and deploy the component at its GitHub repo https://github.com/robipozzi/windfire-restaurants-node/blob/master/Jenkinsfile)
Once you created the appropriate yaml file, use it to create the BuildConfig in windfire project with the following commands
oc project windfire
oc create -f <path to YAML file>/buildconfig.yaml
Ensure Webhook GitHub trigger is enabled on the BuildConfig by issuing the following command
oc set triggers bc/windfire-restaurants-node-pipeline --from-github
This will allow BuildConfig to be triggered by a webhook that is configured on GitHub (we will see how to do it in the following paragraph).
Configure GitHub Webhook
Firstly you need to get the secret that is generated when the from-github trigger is set on the BuildConfig, with the following command
oc edit bc/windfire-restaurants-node-pipeline
You should find something like the following, write down the secret, you will need it in a second
Then find the GitHub Webhook URL with the following command
oc describe bc/windfire-restaurants-node-pipeline
You should find something similar to the following, write down the URL, replace <secret> with the actual secret you found before and write it down, you will need it when you are going to configure Webhooks in GitHub.
Now we have everything we need to set a Webhook trigger in GitHub.
Go to the GitHub repo, click on Settings, then Webhooks, click on Add Webhook button and configure it appropriately: set Payload URL to the Webhook URL you noted down before, just like the following
With this we are all set, whenever we push a change to GitHub repository the process will run and will build and deploy the application to OpenShift, based on Jenkins pipeline definition and the OpenShift Template the pipeline uses.
What to read next
This article is part of a series of articles exploring the options you have to build and deploy applications to OpenShift, you can read the other related articles at the following links: