Some Jenkins Magic

The last days I worked on an automated Jenkins installation for a customer with Ansible. The plain installation was pretty easy. I followed the Ansible Role (jenkins-role) provided by Jeff Geerling. Jeff Geerling is also the author of the great book Ansible for DevOps

In addition to this plain installation I had some other requirements for the automatic installation.

  • Enable security so that no actions are permitted without login
  • Create two kinds of security credentials. One username password credential for authentication against a subversion repository and an ssh keybased credential for Ansible connection on the target hosts.
  • Create a seed job which creates all our deployment jobs.

Enable Security

First of all I permit all actions without login. Jenkins runs all groovy scripts found in {{ jenkins_home }}/init.groovy.d/

The following script creates a new user and activates matrix-based project security. For matrix-based security you need the Matrix Authorization Strategy Plugin:

#!groovy
import hudson.*
import hudson.security.*
import jenkins.model.*

def instance = Jenkins.getInstance()

println "--> Checking if security has been set already"

if (!instance.isUseSecurity()) {
    println "--> creating local user 'admin'"

    // with new HudsonPrivateSecurityRealm(true) self registration for new Users is enabled
    def hudsonRealm = new HudsonPrivateSecurityRealm(false)
    hudsonRealm.createAccount('{{ jenkins_admin_username }}', '{{ jenkins_admin_password }}')
    instance.setSecurityRealm(hudsonRealm)

    def strategy = new ProjectMatrixAuthorizationStrategy()
    strategy.add(instance.ADMINISTER, "{{ jenkins_admin_username }}")
    // enables global read to anonymous
    strategy.add(Permission.READ, instance.ANONYMOUS.getName())
    // activates read permission to complete Jenkins instance to authenticated users
    strategy.add(instance.READ, "authenticated")
    instance.setAuthorizationStrategy(strategy)
    instance.save()
}

Creating Credentials

For creating the credentials I used the Jenkins Rest-Interface. To create a ssh key-based credential the following request can be used:

curl -X POST 'http://{{ jenkins_admin_username }}:{{ jenkins_admin_password }}@{{ jenkins_hostname }}:{{ jenkins_http_port }}/credentials/store/system/domain/_/createCredentials' \
--data-urlencode 'json={
  "": "0",
  "credentials": {
    "scope": "GLOBAL",
    "id": "ssh-credentials",
    "username": "key-user",
    "password": "",
    "description": "",
    "privateKeySource": {
      "stapler-class": "com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey$FileOnMasterPrivateKeySource",
      "privateKeyFile": "/home/{{ jenkins_user }}/id_rsa"
    },
    "$class": "com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey"
  }
}

If folders are used and the credential is for a specific folder the url must be changed into something like this:

http://{{ jenkins_admin_username }}:{{ jenkins_admin_password }}@{{ jenkins_hostname }}:{{ jenkins_http_port }}/job/{{ folder }}/job/{{ subfolder }}/credentials/store/folder/domain/_/</pre>

The creation of a username password credentials is very similar:

curl -X POST 'http://{{ jenkins_admin_username }}:{{ jenkins_admin_password }}@{{ jenkins_hostname }}:{{ jenkins_http_port }}/credentials/store/system/domain/_/createCredentials' \
    --data-urlencode 'json={
      "": "0",
      "credentials": {
        "scope": "GLOBAL",
        "id": "svn-credentials",
        "username": "user",
        "password": "",
        "$class": "com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl"
      }
    }

Create Seed Job

For creating the seed job I created the job on another Jenkins instance and extracted the job.xml. This can be done by using the cli.

java -jar jenkins-cli.jar -s http://{{ jenkins_hostname }}:{{ jenkins_http_port }}/ get-job JOB

Or copying the job.xml from the filesystem.

This job.xml can now be used to create the Job on the new Jenkins installation with the cli.

cat seed-job.xml | java -jar {{ jenkins_jar_location }} -s http://{{ jenkins_hostname }}:{{ jenkins_http_port }}/
create-job seed-job
--username {{ jenkins_admin_username }}
--password {{ jenkins_admin_password }}

Conclusion

Based on the initial Jenkins Role provides by Jeff Geerling it was realy time consuming to find out how these three Tasks can be achieved. It feel like magic when it works on the end of the day. I hope this would help some people saving time when it comes to automatic Jenkins installations.

Dieser Beitrag wurde unter Cloud & Infrastructure, Software Engineering abgelegt und mit verschlagwortet. Setze ein Lesezeichen auf den Permalink.

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s