Blog News about what we are doing

Fernando Dobladez

Cloud Provisioning for CI: Jenkins + Cloudstack

Written by José Rozanec

At one of our clients, we are using Cloudstack to develop an internal “cloud” infrastructure, and Jenkins as the continuous integration server. In this post I describe how to leverage Cloudstack at Jenkins using the JClouds plugin. This setup allow us to create slaves on demand, get them down automatically when load decreases, and create single-use slaves if needed.

Sample project

In order to explain how this integration works, we’ll use Twitter’s twitter-text-java project. I chose this project because it is publicly available, displays tests status on its Github page, and does not require any special configuration, making easier to focus on cloud settings.

Configure a Cloudstack image

Before we start with Jenkins configuration, we need to have a Cloudstack template to be used as base image. We created a Cloudstack template with a freshly installed CentOS 6.2.

Jenkins’ requirements

Since we are cloning a git repository, Jenkins must have the Git Plugin installed and configured. To build the project we need to have Git, a JDK and Maven installed. For this tutorial, we chose to install these tools through Jenkins configuration (when instances are created) instead of installing them on the base image.

Configure Jenkins’ Cloud options

In the following steps we will configure a cloud provider and an instance template, so that Jenkins will know how to launch new instances. We will also enumerate the characteristics these instances should have.

  1. Go to Jenkins’ configuration page (e.g. http://your-jenkins-servers/configure)
  2. Scroll down to the Cloud section.
  3. Set a Cloud profile name, select Cloudstack provider and specify the endpoint URL (e.g. http://your-cloud-manager:8080/client/api). Identity and credential fields should be completed with Cloudstack’s user API Key and Secret Key respectively.

Setup cloud profile 1

When providing RSA Private Key and Public Key values, you can just select the “Generate Key Pair” option to generate them automatically. Take into consideration that there is no need for having these keys setup inside the base image use by Jenkins. The JClouds plugin will run a bootstrap script when creating instances to configure a jenkins user with the provided ssh-keys.

Setup cloud profile 2

Use the “Test Connection” button to check endpoint url is correct and Jenkins is able to connect to the cloud provider.

In the Cloud Instance Templates section you can configure different instance profiles:

Setup instance template 1

To configure the first one:

  1. Set a name (avoid whitespaces!) and description
  2. You may want to specify a label to force jobs to run on Cloudstack slaves and to avoid running on Jenkins master.
  3. Choose a hardwareId (Cloudstack’s compute offering uuid) and imageId (Cloudstack’s template uuid), and check if these are valid ids. The jClouds plugin will validate that the Cloudstack endpoint URL is correct and that the identity and credential values specified have enough permissions to access the Cloudstack configuration.

At the end of the Image/OS Options there is an “Advanced” button where additional configuration options may be specified.

Setup instance template 2

Click on it and configure the following options:

Jenkins user = jenkins
Allow sudo = yes
Remote FS Root = /jenkins
Admin username = root-username
Admin password = root-password

Save your changes.

To leverage cloud configuration we still need to create/edit a Jenkins’ job. For our twitter-java-text project, we created a Maven job.

If you want this job to be run just on certain nodes (i.e. just on the ones created by the cloud provider), check the “Restrict where this project can be run” option and specify an instance type label.

Configure job 1

At the bottom, complete the “Build Environment” options checking the “JClouds Instance Creation” and selecting a cloud name, template and number of instances.

Configure job 2

Other configuration options correspond to standard job settings.

To complete the setup of the project, be sure to specify the git repository, mvn clean install goals, add a shell script to be executed as pre-build step with git submodule init && git submodule update command as specified in the project README.

Conclusion

jClouds plugin enables Jenkins to create build slaves on demand leveraging the cloud provider of your choice. The benefits are:

  • better hardware usage
  • no more large job queues: if the queue grows, new slaves get created resulting in a higher job throughput
  • slaves keep a consistent configuration, since they are all created from same image and renewed periodically

The plugin allows you to create single-use slaves, which could be useful to ensure the slave is correctly setup. Currently we reuse them with a low retention time, avoiding boot times when under heavy load, and get slaves renewed when the load decreases. To speed up boot time we also use a base image with git, JDK, Maven and other tools needed for the build.

You may also condider creating a base image with a Jenkins master install, so that each team can deploy its own Jenkins master with pre-configured plugins and cloud settings. For this approach make sure teams have good reasons to create another Jenkins and ensure that builds from a Jenkins instance do not depend on builds from another.

Sounds interesting? Go and give it a try!

Share