Niblets....Simple. Less.

Capistrano & EC2 Sitting in a Tree, K I S S I N G


I am using EC2 to host my soon-to-launch application. Its great.

I use capistrano to manage these EC2 instances. With these tasks, I have automated many sets of EC2 commands into simple rake tasks.

For instance, to launch an instance, I can type…

rake ec2:run id=ami-61a54008

. ..and a minute or two later I have a new instance running.

Then to install my rails app, I type…

cap initial_install


So in a few minutes, I’ve got my app running on a newly commissioned server! Awesome.

I use to dread bundling my instances (that is, saving my instance with all the changes so I can re-use it again later). I’d have to look up how to do it in the API, paste in my secret keys, and then wait until bundling finished before uploading it, then registering it. It took a while. Now I can bundle, upload, and register with one key command:

rake ec2:complete_bundle

I’ll include the files I use to do this here. There are three files used.

  1. aws.yml – this is where I store all of the data needed by Amazon’s web services for ec2 and s3, such as my access and secret keys. This file goes in your config directory. Since I use this data in multiple places (ec2.rake, deploy.rb, and my s3_cache library), I keep it in this central location. It looks like:aws_access_key: 'XXXXXXXXXXX'
    aws_secret_access_key: 'x+XXXXXXXXXXXXXXXXXX'
    aws_account: '84441XXXXXXX'
    image_bucket: "steveodom_ec2_images"
    ec2_id_rsa: '~/Documents/Projects/ec2/auth/id_rsa-rails-server'
    ec2_keypair_name: "rails-server"
    primary_instance_url: ''
  2. ec2.rake – this file goes in lib/tasks directory of your application. It contains these tasks:
    • images – lists out all public EC2 images and my own images
    • run – runs the image specified. Example: rake ec2:run id=ami-61a54008
    • instances – shows what instances are running. Example: rake ec2:instances
    • bundle_image – bundles my current image
    • upload_image – uploads my current image to s3 (the bucket is specified in aws.yml)
    • register_image – registers my image at amazon.
    • complete_bundle – combines bundle, upload and register
    • terminate – terminates a running instance. Example: rake ec2:terminate id=ami-61a54008
    • login – logs in to my instance. (this I use all the time)
  3. Deploy.rb – this is my capistrano deploy file. This calls tasks from ec2 as well as using tasks from Adam Green’s s3.rake library. So you will need to have Adam’s s3.rake and ec2.rake in your lib/tasks folder.Some of my tasks here are:
    1. patch_server – Anytime you change something on an EC2 instance, unless you re-bundle and register that change at EC2, your changes are not saved next time you run that instance. I put all my changes in this script so the next time I run an instance, I can call this task, and it gets my server the way I want it. If this task starts getting too long, I’ll then re-bundle and register my image.
    2. create_database – If I bundle an image that has databases all ready in the instance, it does not leave me flexibility if I want to use that instance for another web app. So I use this task to write my databases after the instance is already created.
    3. write_database_yaml
    4. backup_db – uses Adam’s S3.rake library.
    5. import_db – uses Adam’s S3.rake library.

    Next I start bundling tasks together. Such as initial_install, which I run right after running my instance, and this task patches it with the latest changes, starts my server, then sets_up my rails application (creates databases, writes the database yaml, does all my migrations, imports the latest version of my database from S3, then restarts).

I’ve found Capistrano with these tasks to be perfect for managing my EC2 instances. I hope that others can find them useful too and add to them.