CI/CD as Code Part IV – Stateless Jenkins Docker Container: Jobs as Code – Advanced

Stateless Jenkins Container with Docker

In the previous article of this example series, we created a stateless Jenkins docker container that can be initialized solely by scripts. In that example, a seed job for the jobDsl plugin was also implemented. This job was later on used to create an automated simple Jenkins job,-inline-. Now we are ready to shape our Stateless Jenkins container to meet more advanced requirements, – advanced jobs as code-.

We will extend previous seedJob implementation further to create more complex jobs programmatically. Our extended seedJob will poll a job definition repository, and it will gather the information on how to create new jobs for some other remote repositories.

Using Jenkins Docker container to have a stateless Continuous delivery environment.
Stateless Jenkins Container: jobs as code process flow

Summary of the steps:

  1. Extend jenkins/init.groovy/1-init-dsl-seed-job.groovy script to enable polling of remote repositories so that it can check these repositories for new job descriptions.
  2. Automate the installation of the tools, which will be needed by the builds (e.g. maven, JDK, etc.)
  3. Implement some job description scripts in the repository (folder), which will be polled by the seed job initialization script.
  4. Add Jenkinsfile(s) to the target projects which are referenced in the job definition script(s).
  5. Run and test the example.

1. Extend jobDsl script

The jobDsl script 1-init-dsl-seed.job.groovy in the previous example is implemented to create a simple “Hello world” job. We passed a DSL job script to the seed job’s “scriptText” attribute to achieve this.

Implement “Job Configuration Repository” configuration

As we stated earlier, we are going to extend this script to define more advanced jobs via groovy scripts. The extended seed job will poll a remote repository, then it will scan the contents for groovy based job descriptions. To achieve this goal, we need to define an SCM and pass this to the freestyle job (the seed job):

In addition to SCM definition, we also defined where and how to find the job definition scripts in that SCM,-“jobScriptFile“-. The snippet below shows how the “jobScriptFile” variable is used: It defines a jobDsl executor ( ExecuteDslScripts)instance and passes jobScriptFile variable to the ‘targets‘ attribute of this instance:

The final form of the seed job script and summary of the tasks

In order to save some space, I will not show the full script here. You can reach the final version from the example “CI as Code” repository.

Let’s summarize what this script is doing for our “Jenkins Jobs as Code” goal:

  1. It will poll the master branch of the repository ‘https://github.com/entrofi/oyunbahcesi.git
  2. Check for groovy scripts under the folder ci_cd/jenkins/configs/jobdsl/
  3. Execute found groovy scripts to create new Jenkins jobs. The scripts in this remote repository can poll any number of repositories and can define different types of Jenkins jobs or views.

2. Installing Tools

Every build-job has it’s own tooling requirements and in order to keep our “stateless CI/CD” goal, we should be able to automate such kind of tool installations. The example projects that we are going to define in the next section are java projects with maven build support. Let’s showcase how to install these tools via Jenkins initialization scripts:
The “2-install-tools.groovy” script installs two different versions of JDK and maven for us.

Java Installation

Maven Installation

The final form tool installation script can be found here

3. Implementing Job Descriptions

In this section, we are going to implement some example job descriptions in the remote repository. Go to jenkins/configs/jobdsl folder, and add a groovy script file called createJobs.groovy:

This groovy script uses jobDsl API to create multibranch jobs for the remote repositories which are defined in the multipbranchJobs array. The factory section of the implementation checks if the remote repositories have Jenkinsfiles, and creates the pipelines for each accordingly.
This snippet demonstrates how to create a multi-branch job using jobDsl API; however, we are not limited in terms of the variety of job descriptions. We can define any kind of Jenkins jobs, including build monitors, list views, free-style jobs, simple pipeline jobs, etc., using this API.

4. Adding Jenkinsfile to the target projects

The rest is easy; in section three we defined a target project, – “entrofi/spring/restassured-asciidoctor” -, in “multiBranchJobs” array. To create her own jobs, one can define further projects in a similar way, and add a Jenkinsfile to the target project. After completing this, it’s just a matter of running the stateless Jenkins Docker image.