Moving to the left
Author’s Note - This article is a continuation of my last one here. Also a big shoutout to the internet and a number of blog posts out there that allowed me get this up and running.
In my last post, I went through building a Jenkins docker container and using it to run Azure CLI to demonstrate Infrastructure as Code principles. In this post, I’m going to take things a step further by automating the setup and configuration of Jenkins and recreating all the Jenkins pipelines I had previously created manually last time.
This allows my Jenkins instance itself to be managed and is more suitable for an immutable infrastructure environment where you can ‘throw away’ the infrastructure and rebuild it any time that it is required (such as upgrading it, or moving the platform).
I do this using two Jenkins plugins - Jenkins Configuration as Code (aka ‘JCasC’) & Job DSL.
First thing, in order for those two plugins to be present, I needed to change how I was building Jenkins and also add in some necessary files to the Docker image - specifically, jenkinsCAS.yaml, jenkinsPlugins.txt and seedjob.groovy. I also disable the first time setup of Jenkins using an environment variable.
I’m not going to show the full contents of those files here, but if anyone in interested, let me know and I’m happy to share them.
Example of the jenkinsCAS.yaml file. This file is the one that essentially, sets up Jenkins the way we want it using a yaml file format. One of the nice things that assisted in creating this file is that the JCasC plugin allows you to export an existing Jenkins configuration so you can use that as the basis for creating the contents of this file.
Included in the above file is the below line. This line is the one that calls the seedjob.groovy code to create the 'Seed Job.
jenkinsPlugins.txt file which is called by docker file to install the Jenkins plugins. It should be noted here that I'm only adding in the ones which are required to be upgraded - at some point I'll modify this to include all the plugins I need (and maybe prune some of the ones I don't want!) -
Code which creates the seed job. This is meant to be very basic job which when runs, points to the repository of the Job DSL files to create those jobs. The example below I still need to do some work on - for example, I'm planning on adding in some parameters so this is a little more dynamic and also triggered automatically (so that I don't need to manually run it :)).
An example of one of the Job DSL files which creates the actual jobs themselves. In this example, it's creating the job that would create an Azure Availability Set when it's run. Again, this is a work in progress and I will likely make some changes in the future to make it more portable.
With the above done, I’m now ready to build the docker container -
docker build . -f <path>/Dockerfile -t jenkins.azurecli:latest
Once the above has run, I can now run the container. One security concern here - I’m taking a shortcut on creating the login ID to Jenkins using environment variables; obviously in a production environment this is not something you’d do this way - at some point I’ll look at how I can do this in a more secure manner.
docker run --name jenkins -p 8080:8080 -v jenkins_home:jenkins --env JENKINS_ADMIN_USER=<> --env JENKINS_ADMIN_PASS=<> jenkins.azurecli:latest
Provided I’ve done everything correctly (in real life a number of frustrating hours passed with me debugging\googling various aspects!), I should now have a Jenkins instance running and after I login I now have the below job!
At this point, I should mention that there are a few things missing from the configuration in my current iteration I do manually. It’s not a good practice to store credentials in code and as I don’t have a password vault of some sort I can use to retrieve them I currently create blank credentials that I have added in my ‘JCasC’ code which the above job (and subsequent jobs that are created) can then reference. So in order to actually run this job, I first need to go and update the credential I use to be able to access my GitHub repository.
Once I do that and run the ‘Seed Job’, I’m back in business and have successfully moved my configuration to the left!
Just to prove it, I add my Azure Credentials into Jenkins and then run the 'Create Resource Group' job
Have any comments or want more information? Feel free to leave one below.