EC2 Continuous Deployment: Wrapping up

Note: This is the fifth (and last!) article in the series on continuous deployment. If you want to start with the overview, go here.

Finally, we’re coming to the end of the road. The only things left in order to finish the continuous deployment cycle are these steps:

  • Run integration tests
  • Shutdown instance
  • Add new nightly job to Hudson that runs the integration tests

Running integration tests

Normally, you would use something like Selenium to do browser-based integration tests, but configuring Selenium RC is outside the scope of these articles (though, you could provision new EC2 instances and run Selenium Grid to test the app from various browsers, even running on Windows. Hmmm, maybe there’s some material here for another article series :-))

To demonstrate the principle, lets create a simple task that performs a crude test to verify that the site is at least running

createTask(‘integrationTest’, dependsOn: ‘testDeploy’) {
try {
client = new org.apache.commons.httpclient.HttpClient()
method = new org.apache.commons.httpclient.methods.GetMethod(“http://$createInstance.dnsName/”)
def s = method.responseBodyAsString
if (s.indexOf(“Welcome to the final helloworld project!”) < 0) { println s throw new RuntimeException("Test failed") } } finally { ec2.terminateInstances([createInstance.instanceId]) } } [/sourcecode] Note, that we shutdown the instance at the end. Now it should be straightforward to add a new Hudson job that runs at night and executes the integrationTest task. This is left as an exercise to the reader!

Where to go from here

This concludes the article series on continuous deployment. The example webapp is very crude, and the target stack rather simple, but this series does describe a complete end-to-end example of how to automate the deployment and testing of a webapp. Expanding on each of the steps in order to match a more realistic scenario should not be insurmountable.

But what I’ve presented here is just the nimble beginning. I know Amazon AWS is not the cheapest hosting you can get, but it does provide you with a lot of flexibility. Here are just some of the possibilities:

  • The single server architecture we’ve used in this example is probably too simplistic in all but the smallest setups. But it is easy to extend even your nightly builds to include a more realistic setup including a load balancer, a few web servers, a few app servers and a database server.
  • If you’re using EBS to store your data, it is very simple to get a replica of your production data by taking a snapshot of your EBS volumes and then mount them in your testing environment. Then you can also test your DB upgrade scripts.
  • Extend integration tests to do browser-based testing using different browsers. This should be possible now that EC2 supports windows instances.
  • Use Chef to deploy a new version of the application without downtime.  You can easily start new app servers with the new code and start routing (perhaps just some?) requests to the new version. When everything looks ok, you can take down the old instances. Of course this would probably require support from the application, since it needs to coexist on the same database with different code bases etc.

Source code

All the code in this example is available on GitHub


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: