How to Run Custom Chef Cookbook Recipes During Deploy

The majority of Engine Yard Cloud customers run one application in an environment and many of them customize their application's environments (production, staging, etc) using custom recipes. We do the same thing internally[1].

One thing we like to do is to run our custom recipes during deployment. That is, instead of having to run ey recipes upload --apply and ey deploy as separate commands, we only have to run ey deploy.

Is this little bit of magic useful to you? If so, then read on!

How do I execute my chef recipes during deployment?

  1. Move your cookbooks into your application repo (see post by [ Mike Barinek](http://www.engineyard.com/blog/2010/managing-your-ey-cloud-recipes/))
  2. Move your cookbooks into `deploy/cookbooks/` (not `cookbooks/`)
  3. Add the following into `deploy/before_migrate.rb` # Runs application cookbooks sudo "/usr/local/ey_resin/ruby/bin/chef-solo -c #{latest_release}/deploy/solo.rb -j /etc/chef/dna.json"
  4. Add the following into `deploy/solo.rb` require "dnapi" base_dir = File.dirname(__FILE__) file_store_path base_dir file_cache_path base_dir cookbook_path "#{base_dir}/cookbooks" node_name DNApi.from(File.read("/etc/chef/dna.json")).id

The todo_with_delayed_job example app shows this in action.

What is an example application?

If you want to jump straight to a working example application, then see this modified todo app which uses delayed_job and includes recipes to setup delayed_job on your environment.

  1. Go to the Engine Yard Cloud dashboard
  2. Click “Add an Application”
  3. Git Repository URI is git://github.com/engineyard/todo_with_delayed_job.git
  4. Application Type is Rails 3
  5. Click “Create Application”
  6. Environment Name is todo (or anything you like)
  7. Click “Create Environment”
  8. Click “Boot This Configuration”
When the environment finishes launching and deploying the Todo application, visit it and check off/complete some tasks. Wait a minute and refresh. Shazzam! New tasks are magically created in the background (by delayed_job).

Quirks of this approach

Running chef on deploy is a new idea, though doesn't fit in nicely yet with some aspects of Engine Yard Cloud. If you are ok with them, or their work arounds, then perhaps this is a great idea for us to productize more thoroughly.

Only solo, app, and util instances

Deploy hooks are not run on database instances. If you need modifications to your db_master or db_slave instances then please use the normal ey recipes upload system.

Adding/removing instances

When you add/remove instances, the deploy hooks are not currently triggered and so your chef recipes will not be run. Press "Deploy" or run ey deploy from your terminal once the instances have finished booting/being removed.

Do not modify core configuration

Due to the timing sequence of when chef runs and deployments are triggered, you should not modify core engineyard managed configuration files (for example, nginx configuration) using this chef-on-deploy approach.

Is there more fun to be had with Engine Yard Cloud?

I'll trade you. Let me know in the comments if this is useful to you or not; then I'll show you some other fun and productive ideas that we've been brewing up lately.

[1] Yes, all the different applications that make up Engine Yard Cloud are hosted on Engine Yard Cloud.