Jenkins Configuration as Code : step towards stateless CI
Jenkins is one of the best Continuous Integration Server out there in the market with over 1000 plugins. Back in the days, creating a Jenkins job is as easy as navigating through some pages selecting the type of job, source code management tool, build tool etc. but, as time progressed, we entered an era of “Things-as-Code” or “Things-as-Config” started gaining popularity. Provisioning “Things-as-Code” or “Things-as Config” has its own benefits like Zero-touch provisioning, Version controlling your configurations, creating consistent systems etc. In this article we will take a look at the Jenkins Configuration as Code Plugin.
Jenkins came up with its version of “Jenkins-pipeline-as-code” with the release of version 2.0. The pipeline as code enabled us to configure entire job flow right in our IDE, also opened up a lot of features that would have otherwise been almost impossible or tedious to implement using freestyle jobs. One example could be designing a job spanning over multiple nodes which feels like a breeze using pipeline jobs but is an upstream-downstream hell(pardon my language) using freestyle jobs. Backing up our job is as easy as adding our Jenkinsfile to source control. As pipeline as code eased up the management work on Jenkins jobs, Docker made setting up the Jenkins infrastructure very easy. However, a manual touch is always needed in the Jenkins global configuration.
Here are a few things we will touch upon in this article:
- A typical Jenkins setup flow
- Is Jenkins config as code really possible?
- ‘Jenkins Configuration as Code’ plugin hands-on
Here is a simple flow of steps involved in setting up a Jenkins instance:
In simple words, most of the configurations(if not all) that goes under “Manage Jenkins” requires manual setup, some of these configurations include,
- Setting up security
- Configuring LDAP settings
- Setting up tool installations eg: GIT, ANT, Sonar etc.
- Any custom global settings for plugins installed eg: kubernetes plugin
Now, let’s try to answer the most important question in context to this article. As previously discussed, Jenkins pipeline as code and Docker to some extent help us take a step closer to a “stateless” Jenkins server. Even most of the administrative tasks mentioned above can be automated using initscripts. However, it requires a deeper understanding of Jenkins plugins and expertise in groovy.
Configuration as code is not a new concept in Jenkins, it’s just not as easy to achieve and once achieved, maintain.
Let’s look at the high-level functioning of the Jenkins Config as Code Plugin using a simple example.
Let’s start with a simple
dockerfile for Jenkins.
# Skip initial setup
ENV JAVA_OPTS -Djenkins.install.runSetupWizard=false
RUN /usr/local/bin/install-plugins.sh configuration-as-code configuration-as-code-support mstest matrix-auth workflow-aggregator docker-workflow blueocean credentials-binding ldap
The highlighted line is the necessary
CASC_JENKINS_CONFIGenvironment variable as instructed in the official documentation for jenkins-configuration-as-code-plugin. Providing the raw GitHub URL for the Jenkins configuration yaml file will help us to update the configuration without rebuilding the container 🙂
Now, let’s take a look at our very first Jenkins Configuration as Code file below,
systemMessage: "Jenkins configured automatically by Jenkins Configuration as Code Plugin\n\n"
- server: ldap.acme.com
- domain :
description: "test.com domain"
Let’s try to understand this file now,
We are configuring 3 things here,
- Jenkins basic configuration – Line # 1-5
- Setting up LDAP configurations – Line # 6-16
- Creating a Jenkins credential of type username and password – Line # 16-31
The official documentation for jenkins-configuration-as-code-plugin lists some more configurations with examples!
Great! Now its time for the moment of truth. Let’s build and run our Jenkins image.
Let’s build our container using the following command,
docker build -t jcasc .
We are tagging our container as
jcasc. Here are our build logs.
Let’s run our container now.
docker run -p 8080:8080 jcasc
Let’s intentionally not run Jenkins in the detached mode so that we can see the full logs. Jenkins is listening to port 8080 which we have forwarded to 8080 on our local, thus Jenkins will be available under http://localhost:8080
And, we are welcomed with our familiar Jenkins dashboard, we can observe that the system message and the executor count got updated as per our configurations. Let’s look at the credentials and the LDAP settings below.
Pretty neat! We were able to configure these otherwise manual steps, automagically! This is just a demo of what Jenkins Configurations as Code can do.
Another neat feature of this plugin is the export functionality that it provides, that is, once all the configurations are done(assumingly manually), the configurations can simply be exported and can be used for other instances. Thus, identical instances can be spun up each time and everytime.
As we conclude this article, we realize that the “Jenkins Configuration as Code Plugin” is a positive step towards a truly stateless CI server. The plugin is still under development and there are some surprises here and some searching through documentations there but, after all of that, we were able to get things done using a simple yaml based template which would have otherwise taken us numerous lines of groovy scripting or some third party solutions using Jenkins APIs. It will be really interesting to see how this plugin matures in the future.
All the codebase used in this article is available here! Feel free to fork and work on it and get your hands dirty! Please share your thoughts, questions and suggestions in the comment section below. Let us know what else you would like to see an article on.
Please subscribe to our blog to stay up to date on any new articles!