How to install and configure Jenkins using Chef Custom Resource

How to install and configure Jenkins using Chef Custom Resource


Purpose – To install and configure a basic Jenkins server using Chef Custom resource.
Pre-requisites
CentOS 7 with ChefDK installed
Here are we are going to use the concept of Chef Custom resource and try installing and configuring a very basic Jenkins server.
So, Let start it.
Before going into the concept of creating a custom resource let’s see what are the default repository listing for my centos machine and try creating a cookbook with a default recipe to install jenkins and see what happens
Below is the list of repositories that are currently configured on my default CentOS 7 machine
[root@host-1 jenkins]# yum repolist
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * base: mirror.math.princeton.edu
 * extras: mirrors.mit.edu
 * rpmforge: repoforge.spinellicreations.com
 * updates: www.gtlib.gatech.edu
repo id                                                      repo name                                                                status
base/7/x86_64                                                CentOS-7 – Base                                                          9,363
extras/7/x86_64                                              CentOS-7 – Extras                                                          451
rpmforge                                                     RHEL 7 – RPMforge.net – dag                                              4,718
updates/7/x86_64                                             CentOS-7 – Updates                                                       2,146
repolist: 16,678
Let me generate a cookbook named ‘jenkins’ and update the default recipe in it to install package named jenkins.
[root@host-1 chefspace]# pwd
/home/skytap/chefspace/cookbooks
[root@host-1 chefspace]# chef generate cookbook jenkins
[root@host-1 jenkins]# pwd
/home/skytap/chefspace/cookbooks/jenkins
[root@host-1 jenkins]# cat recipes/default.rb
#
# Cookbook Name:: jenkins
# Recipe:: default
#
# Copyright (c) 2017 The Authors, All Rights Reserved.
package ‘jenkins’ do
                action :install
end
Now, lets try to run the default recipe inside the cookbook ‘jenkins’ to install jenkins locally on the CentOS 7 machine
[root@host-1 cookbooks]# pwd
/home/skytap/chefspace/cookbooks
[root@host-1 cookbooks]# chef-client –local-mode –runlist ‘recipe[jenkins::default]’
[2017-09-11T11:21:46-07:00] WARN: No config file found or specified on command line, using command line options.
Starting Chef Client, version 12.12.15
resolving cookbooks for run list: [“jenkins::default”]
Synchronizing Cookbooks:
  – jenkins (0.1.0)
Installing Cookbook Gems:
Compiling Cookbooks…
Converging 1 resources
Recipe: jenkins::default
  * yum_package[jenkins] action install
    * No candidate version available for jenkins
    ================================================================================
    Error executing action `install` on resource ‘yum_package[jenkins]’
    ================================================================================
   
    Chef::Exceptions::Package
Running handlers:
[2017-09-11T11:23:24-07:00] ERROR: Running exception handlers
Running handlers complete
[2017-09-11T11:23:24-07:00] ERROR: Exception handlers complete
Chef Client failed. 0 resources updated in 01 minutes 36 seconds
[2017-09-11T11:23:24-07:00] FATAL: Stacktrace dumped to /root/.chef/local-mode-cache/cache/chef-stacktrace.out
[2017-09-11T11:23:24-07:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
[2017-09-11T11:23:24-07:00] ERROR: yum_package[jenkins] (jenkins::default line 7) had an error: Chef::Exceptions::Package: No candidate version available for jenkins
[2017-09-11T11:23:25-07:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
As you can see from the highlighted lines in RED, Chef client failed to run the default recipe because it is unable to find any package named jenkins to install from the default repositories that are pre-configured in the machine
To resolve these errors, we are going to create first create a repo file with the repository url for jenkins package using template resource, then we are going to create a custom resource named manageJenkins which we can use similar to resources like file, package, service and call the custom resource from the default cookbook recipe to install the Jenkins package from the repository that was configure in the first step. Lets start with the step by step procedure as outlined below to achieve our goal or purpose
Step1: Setup the Jenkins repository
[root@host-1 jenkins]# pwd
/home/skytap/chefspace/cookbooks/jenkins
[root@host-1 jenkins]# chef generate template jenkins.repository
Update the default jenkins.repository.erb file with the repo content pointing to jenkins repository as show below
[root@host-1 jenkins]# cat templates/jenkins.repository.erb
[jenkins]
name=Jenkins
baseurl=http://pkg.jenkins.io/redhat
gpgcheck=1
Now, lets configure the jenkins repository locally by using template resource in the default cookbook recipe as show below.
[root@host-1 jenkins]# cat recipes/default.rb
#
# Cookbook Name:: jenkins
# Recipe:: default
#
# Copyright (c) 2017 The Authors, All Rights Reserved.
template ‘/etc/yum.repos.d/jenkins.repo’ do
                source ‘jenkins.repository.erb’
                owner ‘root’
                group ‘root’
                mode ‘0755’
end
As you can see i have deleted the old content from the recipe wherein we were trying to install jenkins package using package resource which file. The file is now updated with the template resource to configure the jenkins repository.
Now, lets run the recipe and see what happens
Before default recipe execution
[root@host-1 jenkins]# ls -ltr /etc/yum.repos.d/
total 44
-rw-r–r–. 1 root root 1128 Mar 20  2013 rpmforge.repo
-rw-r–r–. 1 root root  728 Mar 20  2013 mirrors-rpmforge-testing
-rw-r–r–. 1 root root  717 Mar 20  2013 mirrors-rpmforge-extras
-rw-r–r–. 1 root root  739 Mar 20  2013 mirrors-rpmforge
-rw-r–r–. 1 root root 1952 Dec  9  2015 CentOS-Vault.repo
-rw-r–r–. 1 root root 1331 Dec  9  2015 CentOS-Sources.repo
-rw-r–r–. 1 root root  630 Dec  9  2015 CentOS-Media.repo
-rw-r–r–. 1 root root  290 Dec  9  2015 CentOS-fasttrack.repo
-rw-r–r–. 1 root root  649 Dec  9  2015 CentOS-Debuginfo.repo
-rw-r–r–. 1 root root 1309 Dec  9  2015 CentOS-CR.repo
-rw-r–r–. 1 root root 1664 Dec  9  2015 CentOS-Base.repo
[root@host-1 jenkins]# chef-client –local-mode –runlist ‘recipe[jenkins::default]’
[2017-09-11T11:45:48-07:00] WARN: No config file found or specified on command line, using command line options.
Starting Chef Client, version 12.12.15
resolving cookbooks for run list: [“jenkins::default”]
Synchronizing Cookbooks:
  – jenkins (0.1.0)
Installing Cookbook Gems:
Compiling Cookbooks…
Converging 1 resources
Recipe: jenkins::default
  * template[/etc/yum.repos.d/jenkins.repo] action create
    – create new file /etc/yum.repos.d/jenkins.repo
    – update content in file /etc/yum.repos.d/jenkins.repo from none to 201d31
    — /etc/yum.repos.d/jenkins.repo      2017-09-11 11:45:51.833807412 -0700
    +++ /etc/yum.repos.d/.chef-jenkins.repo20170911-7866-8n2km5        2017-09-11 11:45:51.750805465 -0700
    @@ -1 +1,5 @@
    +[jenkins]
    +name=Jenkins
    +baseurl=http://pkg.jenkins.io/redhat
    +gpgcheck=1
    – change mode from ” to ‘0755’
    – change owner from ” to ‘root’
    – change group from ” to ‘root’
    – restore selinux security context
Running handlers:
Running handlers complete
Chef Client finished, 1/1 resources updated in 03 seconds
After the execution
[root@host-1 jenkins]# ls -ltr /etc/yum.repos.d/
total 48
-rw-r–r–. 1 root root 1128 Mar 20  2013 rpmforge.repo
-rw-r–r–. 1 root root  728 Mar 20  2013 mirrors-rpmforge-testing
-rw-r–r–. 1 root root  717 Mar 20  2013 mirrors-rpmforge-extras
-rw-r–r–. 1 root root  739 Mar 20  2013 mirrors-rpmforge
-rw-r–r–. 1 root root 1952 Dec  9  2015 CentOS-Vault.repo
-rw-r–r–. 1 root root 1331 Dec  9  2015 CentOS-Sources.repo
-rw-r–r–. 1 root root  630 Dec  9  2015 CentOS-Media.repo
-rw-r–r–. 1 root root  290 Dec  9  2015 CentOS-fasttrack.repo
-rw-r–r–. 1 root root  649 Dec  9  2015 CentOS-Debuginfo.repo
-rw-r–r–. 1 root root 1309 Dec  9  2015 CentOS-CR.repo
-rw-r–r–. 1 root root 1664 Dec  9  2015 CentOS-Base.repo
-rwxr-xr-x. 1 root root   71 Sep 11 11:45 jenkins.repo
                                                                                                                         
As highlighted in yellow, our repository is now configure with the help of template resource. Let get onto our next chef creating custom resource
Step2: Create a custom resource
As a first i am create a lightweight resource provider named ‘manageJenkins’ using the below command
[root@host-1 jenkins]# chef generate lwrp manageJenkins
Recipe: code_generator::lwrp
  * directory[/home/skytap/chefspace/cookbooks/jenkins/resources] action create
    – create new directory /home/skytap/chefspace/cookbooks/jenkins/resources
    – restore selinux security context
  * template[/home/skytap/chefspace/cookbooks/jenkins/resources/manageJenkins.rb] action create
    – create new file /home/skytap/chefspace/cookbooks/jenkins/resources/manageJenkins.rb
    – update content in file /home/skytap/chefspace/cookbooks/jenkins/resources/manageJenkins.rb from none to e3b0c4
    (diff output suppressed by config)
    – restore selinux security context
  * directory[/home/skytap/chefspace/cookbooks/jenkins/providers] action create
    – create new directory /home/skytap/chefspace/cookbooks/jenkins/providers
    – restore selinux security context
  * template[/home/skytap/chefspace/cookbooks/jenkins/providers/manageJenkins.rb] action create
    – create new file /home/skytap/chefspace/cookbooks/jenkins/providers/manageJenkins.rb
    – update content in file /home/skytap/chefspace/cookbooks/jenkins/providers/manageJenkins.rb from none to e3b0c4
    (diff output suppressed by config)
    – restore selinux security context
Once our custom resource files are create, lets update the custom resource with below content. Here i am giving my custom resource a name called ‘manageJenkins’ and updating it with two action items that are install and uninstall.
In ‘install’ action we are going to install jenkins using the package resource and then enable and start up the jenkins service.
In ‘uninstall’ action we are going to remove the jenkins package from the machine
[root@host-1 cookbooks]# cat  jenkins/resources/manageJenkins.rb
resource_name : manageJenkins
action :install do
                package ‘jenkins’
                service ‘jenkins’ do
                                action [:enable, :start]
                end
end
action :uninstall do
                package ‘jenkins’ do
                                action :remove
                end
end
The next step is to call the custom resource from our cookbooks default recipe as shown in step three
Step3: Use the Custom resource in the default recipe
[root@host-1 jenkins]# cat recipes/default.rb
#
# Cookbook Name:: jenkins
# Recipe:: default
#
# Copyright (c) 2017 The Authors, All Rights Reserved.
template ‘/etc/yum.repos.d/jenkins.repo’ do
                source ‘jenkins.repository.erb’
                owner ‘root’
                group ‘root’
                mode ‘0755’
end
manageJenkins ‘install’ do
                action    :install
end
After update my default recipe as above, i tried to run the reciple with the command in Step four but it failed with below error
      ================================================================================
      Error executing action `install` on resource ‘yum_package[jenkins]’
      ================================================================================
     
      Chef::Exceptions::Exec
      ———————-
      yum -d0 -e0 -y install jenkins-2.78-1.1 returned 1:
      STDOUT: Public key for jenkins-2.78-1.1.noarch.rpm is not installed
     
      STDERR: warning: /var/cache/yum/x86_64/7/jenkins/packages/jenkins-2.78-1.1.noarch.rpm: Header V4 DSA/SHA1 Signature, key ID d50582e6: NOKEY
     
     
      Public key for jenkins-2.78-1.1.noarch.rpm is not installed
To recover from the above error, i have updated my template file with gpgkey as below and tried to rerun the Step four
[root@host-1 jenkins]# cat templates/jenkins.repository.erb
[jenkins]
name=Jenkins
baseurl=http://pkg.jenkins.io/redhat
gpgkey=https://pkg.jenkins.io/redhat/jenkins.io.key
gpgcheck=1
Yes, with the above change i was able to successfully install jenkins and startup the service. Sample output is show in below
Step4: Run the Cookbook in local mode
[root@host-1 cookbooks]# chef-client –local-mode –runlist ‘recipe[jenkins]’
[2017-09-09T04:15:20-07:00] WARN: No config file found or specified on command line, using command line options.
Starting Chef Client, version 12.12.15
resolving cookbooks for run list: [“jenkins”]
Synchronizing Cookbooks:
  – jenkins (0.1.0)
Installing Cookbook Gems:
Compiling Cookbooks…
Converging 1 resources
Recipe: jenkins::default
  * manageJenkins[install] action install
    * yum_package[jenkins] action install
      – install version 2.77-1.1 of package jenkins
    * service[jenkins] action enable (up to date)
    * service[jenkins] action start
      – start service service[jenkins]
As a last step, we need to validate if jenkins is actually installed or not which can be done as in step five.
Step5: Validate the Jenkins installation
[root@host-1 cookbooks]# systemctl status jenkins
● jenkins.service – LSB: Jenkins Automation Server
   Loaded: loaded (/etc/rc.d/init.d/jenkins)
   Active: active (running) since Sat 2017-09-09 04:20:40 PDT; 3min 34s ago
     Docs: man:systemd-sysv-generator(8)
  Process: 9410 ExecStart=/etc/rc.d/init.d/jenkins start (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/jenkins.service
           └─9425 /etc/alternatives/java -Dcom.sun.akuma.Daemon=daemonized -Djava.awt.headless=true -DJENKINS_HOME=/var/lib/jenkins -jar …
Sep 09 04:20:35 host-1 systemd[1]: Starting LSB: Jenkins Automation Server…
Sep 09 04:20:36 host-1 runuser[9411]: pam_unix(runuser:session): session opened for user jenkins by (uid=0)
Sep 09 04:20:39 host-1 runuser[9411]: pam_unix(runuser:session): session closed for user jenkins
Sep 09 04:20:40 host-1 jenkins[9410]: Starting Jenkins [  OK  ]
Sep 09 04:20:40 host-1 systemd[1]: Started LSB: Jenkins Automation Server.
Access Jenkins using below url
http://localhost:8080/
In this article i haven’t touched on securing the jenkins instance, but when you access the above URL, it show as message stating that your jenkins instances configured with administrator password by default for security reasons, so you can login with the default password shown on the page which is also logged in the log file mentioned in the message.
Hope you enjoyed reading this article. Thank you.