Setting up a Jenkins instance with Configuration as Code (using yaml configuration)
Published: 2022-06-29 18:55:39

Sometimes we want to have visibility and keep track of how our Jenkins instance is configured and parameterized. 

Doing these changes from the *Jenkins UI* is pretty straightforward, but in the other hand we don't keep track of history changes and we need to jump to one menu item to another to get the big picture of how the setup is as a whole.

[According to *Jenkins Configuration as Code plugin* docs:](https://github.com/jenkinsci/configuration-as-code-plugin)
> The Configuration as Code plugin is an opinionated way to configure Jenkins based on human-readable declarative configuration files. Writing such a file should be feasible without being a Jenkins expert, just translating into code a configuration process one is used to executing in the web UI

In another post we talked about [the importance of using a Jenkinsfile to keep track of all pipeline changes](https://rodrigocprates.hashnode.dev/jenkins-pipeline-essentials).

Now, we can still have the same approach to set up our *Jenkins instance* with 
*Configuration as Code*, meaning we define and declare all instance parameters and configurations and keep track of any changes made to our CI/CD tool.

Let's see below how it can be done in practice.

## Use case
Since we want a pretty simple Jenkins setup, let's:
- start a fresh Jenkins installation
- define some environment variables
- define a JDK tool installation

Then we'll setup a Jenkins pipeline with a *Jenkinsfile* that:
- prints some environment variables
- runs _java --version_ to see the Java 11 version printed


## Setup a Jenkins instance
To simplify (if you already have a Docker up and running), [start your Jenkins instance](https://hub.docker.com/r/jenkins/jenkins): 

`docker pull jenkins/jenkins:lts-jdk11
docker run -p 8080:8080 -p 50000:50000 --restart=on-failure jenkins/jenkins:lts-jdk11`

Now we are going to use [Configuration as Code plugin](https://github.com/jenkinsci/configuration-as-code-plugin) and some other plugins. 

Go to _Manage Jenkins -> Manage Plugins -> Available_ and install the following plugins:
- Configuration as Code
- AdoptOpenJDK installer

## Create you configuration files

Now we need to declare the *configurations for our Jenkins *instance and also define *how our pipeline is going to work*.

[You can create them in a public repository, like I'm doing here.](https://github.com/rodrigocprates/jenkins-configuration-as-code)

## Create your _Configuration as Code_ yaml file (Jenkins configs)
It will define 2 new global environment vars on Jenkins and setup a JDK11 tool.

```
jenkins:
  systemMessage: "Jenkins instance using Configuration as Code."
  globalNodeProperties:
  - envVars:
      env:
      - key: SOME_ENV_PATH
        value: "/path/to/somewhere"
      - key: AWS_REGION
        value: us-west-2
tool:
    jdk:
      installations:
        - name: jdk11
          home: "/jdk"
          properties:
            - installSource:
                installers:
                  - adoptOpenJdkInstaller:
                      id: "jdk-11.0.14+9"
```


## Create your _Jenkinsfile_ (Pipeline definition)
It will create two stages:
1. print the variables we defined
2. run the *java version* command to print it's version


```
pipeline {
  agent any
  environment {
    somePath = "${env.SOME_ENV_PATH}"
    awsRegion = "${env.AWS_REGION}"
  }
  stages {
    stage('Print my stuff') {
      steps {
        echo "somePath environment var is [${somePath}]"
        echo "awsRegion environment var is [${awsRegion}]"
      }
    }
    stage("Check JAVA version") {
      steps {
        sh "java --version"
      }
    }

  }
  post {
    always {
      cleanWs()
    }
  }
}
```


## Using *Configuration as Code* plugin

### Updating your Jenkins configurations
Whenever you want to update your configurations described on your _yaml_ file:

1. Update your *yaml* file with the changes

2. Go to _Manager Jenkins -> Configuration as Code_:
  - Provide the path/URL to your _yaml file_ (in my case, that's the github raw url to the file)
  - Click _Apply New Configuration_

3. Click _View Configuration_ below to see the latest configs.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h02f8d1z0pj00og2e492.png)

## Run a pipeline

- Create a `Pipeline` job type pointing to a `Jenkinsfile`([you can find the sample here](https://github.com/rodrigocprates/jenkins-configuration-as-code/blob/main/Jenkinsfile)):

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j7tf4g3stnzrjt07mrue.png)

- When clicking on `Build` you will see the respective *outputs* on the `Console` log:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/olgibi11jryy95wfekub.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i5wsgknlhddlfca1cbu9.png)

## Conclusions
Making use of *Configuration as Code* plugin definitely helps to keep track of any changes done to your Jenkins configurations and also gives visibiliy to everybody in your team/company.

You can still setup more complex things ([as you can see some demos here](https://github.com/jenkinsci/configuration-as-code-plugin/tree/master/demos)) and also automate the way you update your Jenkins configurations (ironically, with a Jenkins pipeline).

**Feel free to check the files used for this exercise [on my github repo here](https://github.com/rodrigocprates/jenkins-configuration-as-code).**