Loose Ends
Lets talk about Jenkins CI and Infrastructure as code.
I recently discovered a very nice Jenkins plugin called SCM Sync Configuration, which takes your
Jenkins configuration (all the XML files under $JENKINS_HOME) incl. all your job configuration files
(everything under $JENKINS_HOME/jobs) and keeps them in sync with your SCM system.
As new every change of your Jenkins configuration is reflected in your SCM system, this
can be very useful in combination with an infrastructure as code approach.
In case you want to automate your CI servers (which is in general a very good idea), this plugin can
provide you with the latest configuration that exists on your current servers.
Lets picture this:
Anytime you change something in your Jenkins configuration, this change is transfered to your SCM system (GitHub in our case).
With that you know exactly who changed what, when and why in your CI configuration, which is an value on it own already.
But now we use this repository in our automation runs. In Chef this could look like this:
Given we have an attribute list with all Jenkins jobs we have to create. Each attribute would look like:
default[:jenkins][:job][:someJobKey][:name] = 'JenkinsJobName'
default[:jenkins][:job][:someJobKey][:create] = true
we can iterate over this attributes and create each job within our automation run:
# Iterate over all jobs
node[:jenkins][:job].each do |key, job|
if job[:name] == nil then next end
if job[:create] == false then next end
# Create job dir
directory "#{node[:jenkins][:jobDir]}/#{job[:name]}" do
mode 00775
owner node[:sap_jenkins][:user]
group node[:sap_jenkins][:group]
action :create
recursive true
not_if { ::File.directory?("#{node[:jenkins][:jobDir]}/#{job[:name]}") }
end
# Copy job config.xml from config repository
remote_file "#{node[:jenkins][:jobDir]}/#{job[:name]}/config.xml" do
source "#{node[:jenkins][:configRepo]}/jobs/#{job[:name]}/config.xml"
mode '0644'
owner node[:sap_jenkins][:user]
group node[:sap_jenkins][:group]
not_if do ::File.exists?("#{node[:jenkins][:jobDir]}/#{job[:name]}/config.xml") end
end
end
The magic happens in line 20 where we just get the latest configuration from our GitHub repo (keep in mind to use the “raw” resource link to get the actual file via http).
Another way would be to clone the repository to your Chef temp. directory and copy the files on the node into their target directory.
That completes the setup. Every new Jenkins instance you create, will always contain the latest configuration. And everything is completly under version control. 😎
Note: Yes you can do this for sure with other SCM systems, CI servers and other configuration frameworks as well.