Over the past couple of months I have been playing around with Amazon Web Services, I have to admit they are an interesting and powerful solution to many of the IT as a Service models that have hung around in the past. While the technology is definitely still low level I thought I would spend a rainy Saturday in Manila playing around with the Ruby EC2 library and see what I could.
In order to get things started I simply set-up the new Amazon EC2 gem.
# ONE TIME ONLY
# Execute this on each machine where you install gems to add github as a gem source
gem sources -a http://gems.github.com/
# ONE TIME ONLY
# Only if you had a previous version of the gem installed from RubyForge before we moved to GitHub
# Say 'Y' to remove all previous versions and all binaries when prompted.
sudo gem uninstall amazon-ec2
# Finally install the gem
sudo gem install grempe-amazon-ec2
Once installed we need to add a couple of environment variables to our .bash_profile, this is useful to have around if you want to use the EC2 CLI anyway. Here’s what I put in my .bash_profile (on Leopard):
export RUBYOPT="rubygems"
# For amazon-ec2 and amazon s3 ruby gems
export AMAZON_ACCESS_KEY_ID="YOUR_ACCESS_KEY_ID"
export AMAZON_SECRET_ACCESS_KEY="YOUR_SECRET_ACCESS_KEY_ID"
Before going too far we will need to create a key pair that we can use, this is easy enough – lets start up the ec2sh and create a new keypair. We store this in a local file.
>> File.open("pdodds-keypair","w") { |file| file.write(@ec2.create_keypair(:key_name=>"pdodds-keypair").keyMaterial); file.close }
>> File.chmod 0700,"pdodds-keypair"
First up I thought I would take a look around the images that are available so that I can pick up something that I could use, since I’m bedding slowly into the Ruby world I thought I would use ec2sh and get back some information on what is available.
>> @ec2.describe_images(:owner=>'amazon').imagesSet.item.each { |image| puts "#{image.imageId} #{image.imageLocation}" } == true
Beside the scruffy ==true on the end basically this prints out the ID’s and locations of the Amazon owned images. For those new to EC2 these are the images of operating systems that we can use to boot our instance. EC2 machines currently only support persistent filesystems for those lucky enough to get on the beta (anyone going to invite me?). These means that when you boot up a machine the image is all you have, and when you power down anything you have written to disk is lost. In a while we’ll touch upon bundles – this is a way to allow you to build AMIs (Amazon Machine Image) and store them away.
The output of our command should give us a nice list, we can do a little to filter down the results (since their is a fair few to choose from).
>> @ec2.describe_images(:owner=>'amazon').imagesSet.item.each { |image| puts "#{image.imageId} #{image.imageLocation}" if image.imageLocation =~ /rails/} == true
This gave me a few to choose from
ami-0cf61365 ec2-on-rails-0.9.2/ec2-on-rails.manifest.xml
ami-540aef3d ec2onrails/ec2onrails-v0_9_7-x86_64.manifest.xml
ami-5c0aef35 ec2onrails/ec2onrails-v0_9_7-i386.manifest.xml
ami-6bcd2802 rails1-51193934437/rails1-51193934437.img.manifest.xml
ami-86c025ef ec2onrails/ec2onrails-v0_9_5-i386.manifest.xml
ami-99c025f0 ec2onrails/ec2onrails-v0_9_5-x86_64.manifest.xml
ami-99f712f0 ec2-on-rails-0.9.1/ec2-on-rails.manifest.xml
ami-a38b6eca amis.winelibrary.com/rails_svn.manifest.xml
ami-a3f91cca ec2onrails/ec2onrails-v0_9_3.manifest.xml
ami-a93adfc0 webficient/ec2_images/fc8-rails2-nginx-mysql/image.manifest.xml
ami-e620c58f ec2onrails/ec2onrails-v0_9_6-i386.manifest.xml
ami-ecc12485 ec2onrails/ec2onrails-v0_9_4-i386.manifest.xml
ami-efc12486 ec2onrails/ec2onrails-v0_9_4-x86_64.manifest.xml
ami-f920c590 ec2onrails/ec2onrails-v0_9_6-x86_64.manifest.xml
So lets get down to business – time to provision one of those servers for our use, I have to admit this was the bit that I always thought was cool, we can just use a simple command from ec2sh to create an instance of a server. Back to ec2sh.
>> @ec2.run_instances :image_id=>"ami-a93adfc0", :key_name=>"pdodds-keypair"
This will dump out a bunch of XML, basically the response from the web service. You could probably have done something to pretty up the response, however for now we can look up our instances to see if it is running
>> @ec2.describe_instances.reservationSet.item.each{ |reservation| puts "Reservation: #{reservation.reservationId}"; reservation.instancesSet.item.each {|item| puts "Instance: #{item.instanceId} #{item.instanceType} #{item.launchTime} #{item.dnsName}" }} == true
This will output the happy information, as long as the server has had a few minutes to provision and start.
i-9e5a97f7 m1.small 2008-05-03T09:19:12.000Z ec2-75-101-212-159.compute-1.amazonaws.com
Next we need to authorize the access to the server
>> @ec2.authorize_security_group_ingress :group_name=>"default",:from_port=>22,:ip_protocol=>"tcp", :to_port=>22, :cidr_ip=>"0.0.0.0/24"
Finally now from terminal we can SSH into the server, note that we do need to include the key that we created.
ssh -i pdodds-keypair root@ec2-75-101-212-159.compute-1.amazonaws.com
There we go – we have an instance of that Unix box, up and running, we can play around with the instance and when it’s time to say goodbye its a simple as going back to our ec2sh session and running:
>> @ec2.terminate_instances :instance_id=>"i-9e5a97f7"
I’ll follow up this blog post with how you can modify and then store images, later however I hope this shows how you can use the Ruby EC2 API to play around and create servers :) happy provisioning in the cloud….

