For some time I’ve strived at taking the next step after Continuous
Integration in my projects: Continuous Delivery. This implies not only
automated testing, but also automated deployment. I’ve succeeded in achieving
this on bare-metal servers for some time now, but struggled to get this
working with Grails in the cloud. The good news is that this is finally
possible now!
I recently discovered CloudBees, a Platform as a Service (PaaS) solution for
Java applications. What sets them apart from their competition is that they
aren’t merely offering a cloud hosting solution, but a hosted CI environment
too (read hosted Jenkins!). This is all achieved by leveraging off the stable
infrastructure offered by Amazon EC2.
So with a hosted CI server in the cloud, a deployment destination and a Grails
runtime available to us, we (almost) have all the components necessary to do
end-to-end automated releases. One final puzzle-piece was missing: the
CloudBees SDK required to perform deployment from within our Grails project on
the Jenkins server. After trying out several things, I opted for writing a
Grails Plugin that encapsulates the SDK.
The CloudBees Grails plugin can be installed into any typical Grails project,
and adds numerous command scripts for interaction with CloudBees through the
SDK. It is possible to deploy, delete, stop, start, restart, list and get app
info. You can even tail log files! It is also possible to create, read, update
and delete new databases (MySQL databases hosted on Amazon RDS) using the
plugin.
Commands
Here is a list of all the available commands that the plugin provides:
bees-app-checksums
bees-app-delete
bees-app-deploy
bees-app-info
bees-app-list
bees-app-restart
bees-app-start
bees-app-stop
bees-app-tail
bees-test-app
bees-db-create
bees-db-drop
bees-db-info
bees-db-list
Without further ado, let’s jump into using the plugin. We’ll use a small
example application which you can pull down from GitHub. We will install the
plugin, run some commands on the cloud, and finally set up a Jenkins build
that runs tests and deploys the app.
This article assumes that you have an existing CloudBees account and the
latest Grails installed on your machine. Also, ensure that your have your
CloudBees API key and secret handy.
Getting the Application
The application that we will be using is one that was used to demonstrate
Named Queries with Projections in Grails from an earlier post found
here. Fork the code found here on
GitHub.
Next pull down the source as follows:
$ git clone git@github.com:githubusername/battle-star-galactica.git
replacing githubusername with your own.
Install and Configure the Plugin
Next, step into the project folder, install and configure the plugin:
$ cd battle-star-galactica
$ grails install-plugin cloud-bees
Ensure that your have a .grails folder in your home folder and then create a
settings.groovy file in this folder. Now fire up your editor of choice (I’ll
be using vim) and edit this file:
$ vi ~/.grails/settings.groovy
Add the following few lines, replacing the key and secret with your own:
cloudbees.account='CLOUD_BEES_ACCOUNT'
cloudbees.api.key='CLOUD_BEES_API_KEY'
cloudbees.api.secret='CLOUD_BEES_API_SECRET'
Add the same config to the BuildConfig.groovy to be used later from within
the Jenkins job:
$ vi grails-app/conf/BuildConfig.groovy
Run Some Commands
Let’s test our app, then deploy it straight to the cloud.
$ grails clean
$ grails bees-test-app
$ grails prod war
$ grails bees-app-deploy
Give the command some time to complete and start up the application, then
navigate to the url that is dumped to the console. Remember, give it some time
to deploy!
My account name is hashcode, so in my case it was:
http://bsg.hashcode.cloudbees.net
Next, let’s start configuring the CI environment…
Setting up Jenkins
I won’t go into the detail of how Jenkins works, or even how to configure it
in fine detail. Instead I’ll show only the bits that matter.
Firstly we need to install the Grails plugin for Jenkins. After logging into
CloudBees, click on the ‘>>Take me to Jenkins’ button. Click: Manage Jenkins >
Manage Plugins. Under the Available tab, select the Grails Plugin and hit the
Install button at the bottom of the page. Once installed, you will need to
restart the Jenkins instance.
Next, we go to New Job and create a ‘free-style software project’ with the
name of your choosing. In the following screen, we get to set up all the
specifics of our new Job. Enter all your SCM details, triggers and anything
else that you would normally configure for a new Job.
The bit that we’re interested in is the Build Section. Here is what mine looks
like:

Update (20/05/11)
From version 0.1.1 of the plugin, a new script has been added. The bees-test-
app script should be used in the place of test-app. It cloaks the test-
app script but overrides the system property grails.env to be test. This
script works like you would expect the standard test-app script to work.
The interesting bit in the screen-grab is the Targets field. It has a list of
targets that need to be executed, of which the last is the most interesting.
This calls on the bees-app-deploy script in the cloud-bees Grails plugin to
deploy the war file to RUN@cloud.
$ bees-app-deploy bsg 0.1.${env['BUILD_NUMBER']}
This will deploy target/battle-star-galactica-0.1.war to hashcode/bsg,
with a version number of 0.1.x.
This follows the same format as we used earlier, although you should remember
to enclose the entire command in quotes in order to tell Jenkins that this is
a single command. Also noteworthy is the build number that we insert. This
will substitute everything between ${} with the current dynamic build
number. You can use any of the implicit environment variables that Jenkins
provides in the this way.
One final caveat to look out for is the Properties field. Providing the
grails.env=DEV will result in ALL THE TARGETS running in the DEV
environment. This will include the test-app target, which is not ideal. I’ll
be looking at a solution for this soon and will update this post with news. I
will possibly look into getting the Jenkins Grails plugin patched to ignore
environment on the test-app target, or else writing a Grails plugin that will
cloak test-app.
Continuous Delivery
After all is configured, you should be able to push changes to your SCM
(provided that you have set your job up to poll your repository), and see the
Jenkins build coming to life. Once all the appropriate targets have been
invoked, the war file will be deployed to RUN@cloud. It’s handy to watch your
Console Output while you’re testing this, since it also provides you with the
URL that your application will be deployed to. As before, once deployed, the
application needs to be given some time to deploy.
Getting Continuous Deployment working takes some effort to get right. Some
tweaking might be necessary to get the process streamlined. Despite this
initial investment in time, it results in a process that will save you many
hours in the future. You will never need to run another deploy script or scp
another WAR to your server environment. Simply push your changes to Git and
watch it deployed in the cloud within minutes!