One of the tasks that I perform as a rails application developer is repeatedly setting up the following rails stack on an EC2 instance running a variant of Ubuntu:
- Ruby Enterprise Edition (or Ruby 1.9.2 via RVM)
- Apache (or Nginx) with Phusion Passenger
In the past few years, often time I find myself doing the similar setup for testing, staging, and production environments. One thing to note here is that, I was utilizing Amazon Web Service (AWS). This means after an instance has been setup, I can take a snap shot of that instance and save the AMI to S3. Later on, I can use that image to launch new EC2 instance when needed. This avoids the hassle of rebuilding an image from scratch. But, I want to have control of what gets installed on each instances. For example, If I wanted to launch an instance just for a database server, then it does not make sense to install Postfix or Nginx on it. So, I set out to find tools that I can use to setup a Rails stack on a production environment easy as walk in the park. After doing some googling, I came across two tools: Chef and Puppet. Both are tools for automated infrastructure management. I am not going to discuss the differences between the two in this post. After reading this post (http://bitfieldconsulting.com/puppet-vs-chef), I decided to go with Puppet.
First thing I needed was a VM on my development machine. This way, I can change the puppet code and test it on my local machine without ever touching production or test environment. VirtualBox (open source virtualization software) is a great tool for setting up a VM on my development machine. I installed an Ubuntu Maverick (10.1) on my VM.
Puppet is usually setup as a server-client architecture. You store your puppet code in the server and the clients will download the puppet code from it and run them locally. You can also run the puppet code in server-less mode by manually invoking the code from the terminal. Simply put, when the code is run, puppet checks the system architecture with what the puppet code describes. If what is described by puppet is not setup properly, then it will make the necessary changes on the client to synch with what the puppet code describes.
I created bunch of puppet modules (collection of resources, classes, files, definitions and templates) for the different components of the Rails stack. See http://docs.puppetlabs.com/guides/modules.html for more information on puppet modules. I created modules for setting up a deploy user, setting up mysql, setting up nginx, etc. These modules basically tell puppet what packages to install and what configuration files to setup. You can create default configuration files (i.e. nginx.conf, mysql.cnf ) and have puppet install that to the proper locations. With these modules in hand, I played around on my VM.
My initial impression with puppet is that, there is a steep learning curve. There is so much to learn about Puppet but you are not alone on this. PuppetLabs (http://www.puppetlabs.com/) provides tones of resources for you to get going. Once you start getting the hang of writing puppet code, its a great tool that can help to automate the setup of rails (or any IT) environments.