Using Capistrano to Bundle Amazon EC2 Images
I've found the following bit of Capistrano script to be useful when tinkering with EC2 images. I can make a change and then bundle the image with just one command:
cap admin:bundle
The most difficult part of this script was finding out how to upload files to the remote instance using scp
. The rest is fairly straightforward. I am only posting this script because I haven't seen this functionality posted anywhere else.
# capfile for Amazon EC2 Bundling. Normally, a yaml file would be # hold configuration parameters. I am using environment # variables because they are also used by the EC2 # programs - why have the information in two places? # This script assumes that you are only bundling one # instance at a time. # EC2 Instance Hostname to be bundled. ec2_hostname = ENV['BUNDLE_EC2_HOSTNAME'] # S3 Bucket Name (where the bundle is uploaded) s3_bucket_name = ENV['BUNDLE_S3_BUCKET_NAME'] # If you are using ElasticFox (and if not, why not?) that # you created in the KeyPairs tab. Specify the full # path to the file. ssh_keypair_file = ENV['BUNDLE_SSH_PRIVATE_KEY_FILESPEC'] # Amazon Web Services Info amazon_account_id = ENV['AMAZON_ACCOUNT_ID'] amazon_access_key_id = ENV['AMAZON_ACCESS_KEY_ID'] amazon_secret_access_key = ENV['AMAZON_SECRET_ACCESS_KEY'] # Amazon EC2 Info cert_filespec = ENV['EC2_CERT'] private_key_filespec = ENV['EC2_PRIVATE_KEY'] # We are only dealing with one EC2 instance. role :libs, "#{ec2_hostname}" # I like working with ElasticFox which seems to only # support using the root user. set :user, "root" ssh_options[:keys] = ssh_keypair_file namespace :admin do task :bundle do # Copy the certificate and private key to the remote computer. upload("#{private_key_filespec}", "/mnt", :via => :scp) upload("#{cert_filespec}", "/mnt", :via => :scp) # Extract just the filename from the filespec. private_key_filename_start = private_key_filespec.rindex('/') + 1 private_key_filename_end = private_key_filespec.length private_key_filename = private_key_filespec[private_key_filename_start, private_key_filename_end] # Extract just the filename from the filespec. cert_filename_start = cert_filespec.rindex('/') + 1 cert_filename_end = cert_filespec.length cert_filename = cert_filespec[cert_filename_start, cert_filename_end] # Remove any old image. run "rm --force /mnt/image /mnt/image.*" # Create the EC2 Bundle #run "ec2-bundle-vol -d /mnt -c /mnt/#{cert_filename} -k /mnt/#{private_key_filename} -u #{amazon_account_id} -r i386" # Upload the EC2 Bundle to S3 run "ec2-upload-bundle -b #{s3_bucket_name} -m /mnt/image.manifest.xml -a #{amazon_access_key_id} -s #{amazon_secret_access_key}" exec "ec2-register #{s3_bucket_name}/image.manifest.xml" end task :update do run "apt-get update" run "apt-get upgrade -y" end end