home about

Create Your Own EC2 Image

March 10th, 2008

We have been working day and night preparing for our beta launch in April, which is just one of the many excuses I have for not posting in so long. Part of preparing for that launch is setting up the platform that we are going to deploy to. For numerous reasons, we’ve chosen Amazon’s EC2 for our production system. EC2 is a great service, and getting up and running with it isn’t hard at all. However, when it comes to creating your own image, I ran into some barriers, I thought I’d share how we overcame them. I hope you find it useful.

(Side note: Deepak Singh over at business|byte|genes|molecules blogged about an interview with Jeff Barr, an Amazon Web Services Evangelist which I found interesting).

Assumptions

For the purpose of this post, I am assuming your have a working EC2 account, your rsa key is installed properly, and have the basic tools working, ie:

    ec2din
    ec2dim
  
Here is a good tutorial on how to get up and running.

Starting with EC2 on Rails

In my search for a deployment platform, I came across the EC2 on Rails project. It has a bunch of nice things built in, but for various reasons, their standard image wouldn’t work for us. Nevertheless, we decided to use their image as our starting point. You can get their current AMI’s by running the following command (assuming you have the ec2onrails gem installed):

    cap ec2onrails:ami_ids
  
Currently, the 32-bit AMI is ami-e620c58f. Next we start an instance and login:
    ec2run ami-e620c58f --instance-type m1.small -k gsg-keypair
    ec2din
    ssh -i ~/.ssh/id_rsa-gsg-keypair admin@ec2-XXX-XXX-XXX-XXX.compute-1.amazonaws.com
  
In order to rebundle the image, you will need your pk and cert on the server. I store mine in the /mnt/aws-config directory, so lets create that directory. From the server run:
    sudo mkdir /mnt/aws-config
    sudo chown admin.admin /mnt/aws-config
  
Next, upload the files from your local computer
    scp -i ~/.ssh/id_rsa-gsg-keypair ~/.ec2/*.pem admin@ec2-XXX-XXX-XXX-XXX.compute-1.amazonaws.com:/mnt/aws-config
  
To make things easier in the coming steps, I add the pk and cert filenames to my environment. On the server, edit your .profile to include the following lines (I add them before ./usr/local/ec2onrails/config, but I’m not sure it matters):
    KEY_FILE_NAME=pk-[your pk filename].pem
    CERT_FILE_NAME=cert-[your cert filename].pem
    AWS_ACCOUNT_ID=[your account id]
  
Next we have to prepare to rebundle. The EC2 on Rails image comes with a rebundle script. However, I was never able to make it work, so I broke out the necessary steps here:
    curl http://s3.amazonaws.com/ec2-downloads/ec2-api-tools.zip > /tmp/ec2-api-tools.zip
    sudo unzip /tmp/ec2-api-tools.zip -d /usr/local
    sudo chmod -R go-w /usr/local/ec2-api-tools*
    sudo ln -sf /usr/local/ec2-api-tools-* /usr/local/ec2-api-tools
    sudo aptitude install -y sun-java6-jre
  

Insert your configuration here

At this point, you are ready to configure the sever however you see fit. For us it was installing some support software, etc. Although you may want to complete the tutorial first and make sure you can rebundle properly before investing too much time!

The /mnt directory

So at this point you have your perfect server, all you need to do is store the image so you can preserve it forever. There is one last item to deal with, the mnt directory. Whenever you ec2kill an instance and start a new one from the image, the /mnt directory get cleared, which makes sense. You need some place to store all the transient data (like logfiles and deployment versions) that don’t belong in the image. However, somethings in there (like directories for log files) need to exists for the image to start properly. So what’s a person to do? Well I decided on a scheme where I tar up a skeleton on the mnt directory, and wrote an install script for it. That way when I start a new instance, I log in, run ./install.sh and I’m up and running.

Create your mnt directory skeleton

Next I copy the /mnt directory to my home directory and get it just the way I like it (at least get rid of the openssh_id.pub and lost+found).

    sudo cp -R /mnt ~
    cd ~/mnt
    sudo rm lost+found
    sudo rm openssh_id.pub
  
Now tar up your directory:
    sudo tar cvfz ~/mnt.tgz ~/mnt
  
Next we need to write the install script. Mine looks something like (don’t forget to make it executable):
    #!/bin/sh

    sudo tar xvfz mnt.tgz
    cd mnt
    sudo chown app.app -R app
    sudo chown mysql.mysql -R mysql_data
    cd log
    sudo chown syslog.adm *
    sudo chown www-data.www-data -R apache2
    sudo chown mysql.mysql -R mysql
    sudo chown root.root -R fsck
    cd ..
    sudo mv * /mnt

    sudo /etc/init.d/mysql start
    sudo /etc/init.d/apache2 start
  

That’s it, your instance is now configured and ready, now for the good stuff.

Finally, its time to bundle

First we create the image:

    sudo ec2-bundle-vol -u $AWS_ACCOUNT_ID -c /mnt/aws-config/$CERT_FILE_NAME -k /mnt/aws-config/$KEY_FILE_NAME
  
Next, we need to upload the image to S3, (you must create an S3 bucket prior to this step):
  
    ec2-upload-bundle -b [your-bucket] -m /tmp/image.manifest.xml -a [your access key] -s [your secret access key]
  
The final step is to register your image with Amazon and get your AMI:
  
    ec2-register -K /mnt/aws-config/$KEY_FILE_NAME -C /mnt/aws-config/$CERT_FILE_NAME [your-bucket]/image.manifest.xml
  

Putting it all together (AKA, the test)

So you’ve now created your bundle. The true test is, can you start it, login, run your install script, and have a fully functional server. From your local machine:

    ec2dim # You should see your new AMI
    ec2run [AMI from previous command] --instance-type m1.small -k gsg-keypair
    ec2din
    ssh -i ~/.ssh/id_rsa-gsg-keypair admin@ec2-XXX-XXX-XXX-XXX.compute-1.amazonaws.com
  
Now run the install script from the remote machine:
    ./install.sh
  
You should now have a fully functional server.

Bonus

I created two aliases on my local machine that i found very helpful, maybe you will too:

    alias ec2ssh="ssh -i ~/.ssh/id_rsa-gsg-keypair" 
    alias ec2scp="scp -i ~/.ssh/id_rsa-gsg-keypair" 
  

Coming Attractions

Like I said earlier, we are launching our beta in April, so expect to see a lot of changes to the site shortly. One of those changes will include moving from WordPress to Mephisto. if your feed reader resets, I apologize in advance.

2 Responses to “Create Your Own EC2 Image”

  1. Allen Taylor Says:
    Nice writing. You are on my RSS reader now so I can read more from you down the road. Allen Taylor
  2. A biotech company that’s on the programmable web : business|bytes|genes|molecules Says:
    [...] not only mentions their upcoming beta launch in April, but goes through an entire process about how to set up an EC2 image. At the time of my original post, I had felt that the company seemed to get the programmable web. [...]

Leave a Reply