Archive for April, 2012

Too grown up for Heroku?


Cheat sheet for my Too Grown up for Heroku? tutorial at Roots

Pre-requisites for Ubuntu 10.04

Skip this section unless you are starting with a blank Ubuntu Image

  1. sudo apt-get install git-core
  2. install rbenv (
  3. install ruby-build as an rbenv plugin
  4. sudo apt-get install curl
  5. add to .bashrc not .bash_profile
  6. sudo apt-get install zlib1g-dev
  7. sudo apt-get install libssl-dev
  8. rbenv install 1.9.2-p290
  9. rbenv rehash
  10. gem install bundler

Setup Chef

This will get chef setup and installed

  1. Go to
  2. Click on “Free Trial”
  3. Fill in your details
  4. Verify email
  5. git clone git:// chef-repo-demo
  6. cd chef-repo-demo/
  1. list organizations
  2. select your organization
  3. generate knife config
  4. mkdir .chef
  5. nano .chef/knife.rb
  6. paste in generated knife config
  7. on opscode: change password -> get private key -> get new private key
  8. regenerate validation key (will download it) move validation key and private key to match what knife.rb specifies i.e. (.chef/).
  9. gem install chef
  10. (rbenv rehash)
  11. run “knife node list” or some other command to verify your setup is working

Set up a WebServer

This will set up a Webserver on AWS and deploy our example app to it


Create a security group

  1. EC2 -> Security Groups -> Create ->
  2. Add HTTP and SSH inbound (to
  3. Apply rule changs

Launch an instance

  1. -> choose your region -> Ubuntu 10.04 LTS EBS BOOT
  2. Choose type (bigger will install faster, I recommend medium for this tutorial)
  3. Give it a name
  4. Create new key pair
  5. Download the .pem key and add it to ~/.ssh/amazon/your_key.pem
  6. sudo chmod 0400 ~/.ssh/amazon/your_key.pem
  7. ssh-add ~/.ssh/amazon/your_key.pem
  8. Verify with ssh-add -l
  9. Choose the security group you made earlier
  10. Watch it launching

Make sure Chef installs the correct version of Ruby

  1. Copy the Gist into .chef/install_ruby_193-p125.erb
  2. knife bootstrap --distro ubuntu10.04-gems --template-file .chef/bootstrap/install_ruby_193-p125.erb --node-name demoprep-web1 -x ubuntu -i ~/.ssh/amazon/demoprep.pem --sudo
  3. Wait for it to install all packages etc. you should see a long trace in your terminal
  4. Verify with ‘knife node list’ (you can also ssh ubuntu@public.dns if you want to log into the machine)

Run the chef-client once

  1. knife ssh name:demoprep-web1 -a ec2.public_hostname -x ubuntu -i ~/.ssh/amazon/demoprep.pem "sudo chef-client"

Install nginx and unicorn

  1. knife cookbook site install nginx
  2. knife cookbook site install unicorn
  3. knife cookbook site install apt
  4. knife cookbook site install git
  5. knife cookbook site install ssh_known_hosts
  6. knife cookbook site install chef-client
  7. create roles/webserver.rb as
  8. knife role from file roles/webserver.rb
  9. comment out default-site.erb section
  10. knife node run_list add demoprep-web1 'role[webserver]'
  11. knife cookbook upload runit apt bluepill ohai build-essential yum chef-client git nginx ssh_known_hosts unicorn
  12. run the chef client again (see above)
  13. check NGINX is running by going to the public dns in your browser

Checkout example app

  2. add group :development do “capistrano” end to the Gemfile
  3. bundle
  4. capify .
  5. cheat and do git checkout origin/chef
  7. edit deploy.rb

.ssh-keys and git

  1. if you don’t have .ssh/id_rsa: ‘ssh-keygen -t rsa -C “” ‘
  2. ‘ssh -T’

Some more tweaks

  1. knife cookbook create permissions
  2. chown -r ubuntu:ubuntu /var/www
  3. knife upload permissions
  4. knife role from file roles/webserver.rb
  5. create data_bags/ssh_known_hosts/github.json as
  6. replace the value of rsa with the rsa key you get when you do cat ~/.ssh/known_hosts | grep git
  7. knife data bag create ssh_known_hosts
  8. knife data bag from file ssh_known_hosts data_bags/ssh_known_hosts/github.json
  9. knife cookbook create bundler
  10. add ‘gem_package “bundler”‘ to default.rb
  11. knife cookbook upload bundler
  12. add bundler to roles/webserver.rb
  13. knife role from file roles/webserver.rb
  14. run chef-client


  1. cap deploy:setup
  2. cap deploy
  3. cap unicorn:start
  4. cap nginx:restart
  5. check the public url in your browser


  1. knife cookbook site install monit
  2. add “recipe[monit]”, to roles/webserver.rb
  3. add nginx-monit.conf.erb to cookbooks/nginx/templates/default from gist:
  4. add monitc(nginx-monit) to nginx default.rb see gist:
  5. knife cookbook upload nginx monit
  6. knife role from file roles/webserver.rb
  7. run chef-client


Add a Munin server and make it monitor our web server

  1. knife cookbook site install munin
  2. create an environment: environments/productions.rb from
  3. knife environment from file environment/production.rb
  4. knife node edit demoprep-web1 – change environment from _default to production
  5. create a new role roles/muninserver.rb – as
  6. knife role from file roles/muninserver.rb
  7. in AWS Console add 4949 access to the appropriate security group (could be same as above)
  8. launch a new instance on AWS (same security group, keypair etc.)
  9. knife bootstrap --distro ubuntu10.04-gems --template-file .chef/bootstrap/install_ruby_193-p125.erb --node-name demoprep-web1 -x ubuntu -i ~/.ssh/amazon/demoprep.pem --sudo
  10. tweak cookbooks/munin/attributes/default.rb as of
  11. change from fqdn to ipaddress in cookbooks/munin/templates/default/munin.conf.erb
  12. knife cookbook upload apache2 munin
  13. create data_bags/users/munin.json from gist:
  14. knife data bag create users
  15. knife data bag from file users data_bags/users/munin.json
  16. knife node run_list add demoprep-muninserver ‘role[muninserver]’
  17. knife node edit demoprep-muninserver
  18. change environment from _default to production
  19. knife ssh name:demoprep-muninserver -a ec2.public_hostname -x ubuntu -i ~/.ssh/amazon/demoprep.pem "sudo chef-client"
  20. verify you can log in to the muninserver with munin/test
  21. wait for a few minutes for the index to be generated
  22. add “recipe[munin::client]”, to the webserver role
  23. knife role from file roles/webserver.rb
  24. knife ssh name:demoprep-web1 -a ec2.public_hostname -x ubuntu -i ~/.ssh/amazon/demoprep.pem "sudo chef-client"
  25. wait for a few minutes, check the munin graphs


Make chef-client run as a daemon:

knife ssh name:NODE_NAME -a ec2.public_hostname -x ubuntu -i ~/.ssh/amazon/demoprep.pem "sudo chef-client -d -P /var/run/chef/ -L /var/log/chef-client.log -c /etc/chef/client.rb -i 300 -s 20"