Jenkins Configuration as Code

A recent problem I had to solve was how to mirror a Jenkins instance with pretty restrictive permissions in order for our team to be able to duplicate jobs using Jenkins Job builder. I’ve installed and configured Jenkins more times than I can count, manually and through configuration management. But for most Software Developers this task is more intimidating, and even more uninteresting, than I find it. I took this opportunity to learn about Jenkins Configuration as Code (JCasC) as a possible solution and am more than pleased with the results. With JCasC (and JJB or Pipelines), you can go from a fresh Jenkins install to running jobs without ever even logging into the Jenkins UI.

The problem

In order to modify, improve, or add Jenkins jobs to existing Jenkins Job Builder templates, we needed a way to mirror our production Jenkins instance locally to ensure what we thought we were doing was what was actually going to happen. I’m not going to go into details, but pre-baking images was an issue in a repository to hold the images, and using docker images runs into issues when using a VPN as well as just enough cross-platform difficulties.

How it works

Jenkins Configuration as Code is (as per their documentation) “an opinionated way to configure jenkins based on human-readable declarative files.” This provides a way to declare Jenkins configuration via a yaml file without even clicking in the UI. JSasC uses plugins to configure Jenkins based on a yaml file declared by an environment variable.

Plugins

The plugins configuration-as-code and configuration-as-code-support are required to read and configure Jenkins based on a yaml file.

Yaml file

See the documentation for examples and more information on viewing the yaml schema.

Solution Overview

Anyone familiar with Jenkins can see the chicken and egg problem here. In order to install plugins, you first need to configure Jenkins. In order to configure Jenkins, you need to log in to the UI and install plguins. While you can do this and already see huge benefits with JSasC (install Jenkins, install JCasC plugin, point at yaml file), there is an even easier way. Here’s how I got around this.

  1. Install Jenkins
  2. Move over the JCasC yaml file to a readable place for the jenkins user
  3. Install generic config.xml in /var/lib/jenkins/config.xml
  4. Add CASC_JENKINS_CONFIG to /etc/sysconfig/jenkins to point to the yaml file
  5. Start Jenkins
  6. Using server configuration management (such as jenkins_plugins in Ansible), install required plugins
  7. Restart Jenkins
  8. Profit

More details

JCasC can use Kubernetes-secrets, Docker-secrets, or Vault for secrets management. There’s a bit more configuration there, and I haven’t used it. But, using templating and environment variables with Ansible can result in writing a configuration file with secrets only being written within the VM on your local workstation (you are using an encrypted filesystem or ${HOME} directory, right?).