Jenkins Configuration as Code (JCasC) lets you manage your Jenkins setup using YAML files, treating your entire Jenkins configuration as code.
Let’s see JCasC in action. Imagine you have a Jenkins instance and you want to configure a new global security realm, specifically using Jenkins’ built-in security with an embedded database.
Here’s how you’d define that in a JCasC YAML file:
jenkins:
securityRealm:
# Use Jenkins' built-in security with an embedded database
granite: {}
Now, let’s say you want to add a user named admin with a password. You’d extend that YAML:
jenkins:
securityRealm:
granite: {}
users:
- id: admin
password: "{AQ:1}mySecurePasswordHash" # Replace with a real hashed password
To make this active, you need to tell Jenkins where to find this configuration. You’d typically mount this YAML file into the Jenkins container or place it in a specific directory on your Jenkins controller. For example, if you’re using Docker, you might mount it:
docker run -v /path/to/your/jenkins.yaml:/usr/share/jenkins/ref/jenkins.yaml jenkins/jenkins:lts
When Jenkins starts, it reads this jenkins.yaml file and applies the configuration. The granite: {} tells Jenkins to use its internal security store. The users section then defines the admin user. The password hash is crucial; you’d generate this using the hudson.util.Secret class in a Groovy script or via the Jenkins CLI.
This isn’t just about security. JCasC can manage almost every aspect of your Jenkins instance: agents, plugins, global tool configurations, system properties, and more.
Consider configuring an agent. You can define its properties, labels, and even the JNLP connection details directly in YAML.
jenkins:
agentProtocols:
- jnlp
agents:
- name: "my-docker-agent"
remoteFS: "/home/jenkins"
labels: "docker linux"
mode: "exclusive"
type: "permanent"
launchMethods:
- jnlp:
args: "-webUrl http://your-jenkins-url"
This defines a permanent agent named my-docker-agent that will connect via JNLP, running on Linux and tagged with the docker label. The remoteFS specifies where Jenkins will operate on the agent.
The power of JCasC lies in its idempotency and declarative nature. You define the desired state of your Jenkins configuration, and JCasC ensures Jenkins reaches that state, regardless of its current configuration. This makes it incredibly robust for managing Jenkins in production environments, enabling version control, and facilitating disaster recovery.
One of the most powerful, yet often overlooked, aspects of JCasC is its ability to manage plugin configurations. For instance, if you’re using the Pipeline plugin and want to set a default script path for all pipelines, you’d do this:
jenkins:
globalPipelineConfig:
scriptRoots:
- "vars"
- "src/main/groovy"
This tells Jenkins that when a pipeline job is created without a specific script path defined, it should look for pipeline scripts in vars and src/main/groovy directories within the job’s SCM. This is a small but significant configuration that can streamline pipeline development by enforcing a consistent project structure.
The next logical step is to explore how JCasC integrates with plugin updates and managing multiple configuration files.