Customization with Groovy Scripts and CasC
This tutorial outlines a step by step guide on how to customize Jenkins instance after you successfully deployed it.
The current configuration mechanism is based on Kubernetes Custom Resource which is automatically created during the installation phase and then used as a customization file by operator. Every time you want to customize Jenkins, it needs to be done in code by modifying existing Custom Resource file. Any manual changes from the web interface will be overridden by automation or after the Jenkins restart. In the future, we are planning to introduce web interface and infrastructure as code SDK to make these changes programmatically without Kubernetes-specific knowledge required. Sections below will show you how to configure Jenkins using Groovy Scripts and Configuration as Code (CasC).
Jenkins instance can be customized using Groovy scripts or Configuration as Code (thanks to pre-installed configuration as code plugin). CasC scripts are more readable and simplier to write, this should be your default choice. However, when something is not supported by the CasC plugin or for more complex and low-level configuration Groovy scripts are better. They allow you to use jenkins-internal-api. Let’s take a look at some examples below.
The overall process of configuration can be divided into:
Creating a Custom Resource JenkinsGroovyScript, which contains Groovy script you want to execute. Optionally creating a Kubernetes Secret if you need to store secrets like password or certificates.
We need to create a JenkinsGroovyScript config file containing the configuration we want to apply. In the data section we can use Groovy scripts to write configuration code. Since the secret is already present in the Cluster before JenkinsGroovyScript we can safely reference its value.
apiVersion: operator-service.com/v1beta1
kind: JenkinsGroovyScript
metadata:
name: groovy-script
namespace: jenkins
labels:
operator-service.com/jenkins: jenkins
spec:
secretRef:
namespace: jenkins
name: jenkins-conf-secrets
data: |
import jenkins.model.Jenkins
def systemMessage = "Hello " + secrets
Jenkins jenkins = Jenkins.getInstance()
jenkins.setSystemMessage(systemMessage)
jenkins.save()
Now we can safely create this JenkinsGroovyScript.
$ kubectl apply -f jenkins-groovy-script.yaml
In case we want to use confidential data, we have to start by creating a Secret resource to wrap it in. Kubernetes stores secrets in base64 format, so we have to encode it. Running:
$ echo -n "Hello World" | base64
will produce the following output:
SGVsbG8gd29ybGQ=
which we can place in a Secret config file as the value of secrets key.
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: jenkins-conf-secrets
namespace: jenkins
data:
SYSTEM_MESSAGE: SGVsbG8gd29ybGQ=
We have to create the Secret resource in Kubernetes using this config file, saved somewhere in the catalogue, for example in deploy folder.
$ kubectl apply -f deploy/secret.yaml
This event will trigger Jenkins Groovy script reconcile loop and our configuration will be applied automatically. You will see a tiny “Hello World” on the main page.
The overall process of customization can be divided into:
Creating a JenkinsConfigurationAsCode Custom Resource, which contains configuration code in data section. Optionally creating a Kubernetes Secret if you need to store secrets like passoword or certificates.
In case we want to use confidential data, we have to start by creating a Secret resource to wrap it in. Since it’s a secret, it would be a good idea to encode it. Let’s write into console:
$ echo -n "Hello World" | base64
The output is
SGVsbG8gd29ybGQ=
Now we can place it in a Secret config file as the value of SYSTEM_MESSAGE key.
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: jenkins-conf-secrets
namespace: jenkins
data:
SYSTEM_MESSAGE: SGVsbG8gd29ybGQ=
We have to create the Secret resource in Kubernetes using this config file, saved somewhere in the catalogue, for example in deploy folder.
$ kubectl -n jenkins apply -f deploy/secret.yaml
We need to create a JekinsConfigurationAsCode config file containing the configuration we want to apply. In the data field value we can use yaml syntax to add fields with configuration code. Since the secret is already present in the Cluster before JekinsConfigurationAsCode we can safely reference its value.
apiVersion: operator-service.com/v1beta1
kind: JenkinsConfigurationAsCode
metadata:
name: op-svc-jenkins-user-configuration
namespace: jenkins
labels:
operator-service.com/jenkins: jenkins
spec:
secretRef:
namespace: jenkins
name: jenkins-conf-secrets
data: |
jenkins:
systemMessage: ${SYSTEM_MESSAGE}
Now we can safely create this JenkinsConfigurationAsCode with following command:
$ kubectl -n jenkins apply -f jenkins-casc.yaml
Our Jenkins instance will see it and can bind it to previously created Secret, thanks to references we created. This event will trigger CasC reconcile loop and our configuration will be applied. You will see a tiny “Hello World” on the main page.