Migrating a Linux S3 Based AMI to an EBS Based AMI
While we have been booting from EBS a month after it came out using
pivot_root - most of our implementations are based on a couple of AMIs
and many different EBS snapshots and volumes. We were nonetheless happy
to see Amazon's announcement to allow AMIs to boot from AMIs, it makes
some of our scripts much simpler. I put this article together to show
migrating an existing Linux AMI to EBS can be a trivial task.
Once
you have the AMI you want to migrate booted up, ssh into the machine.
Use the following bootstrap script to prep the machine for running the
ami tools and api. The script after the bootstrap will setup a volume snapshot ready to be registered as an AMI.
You will require the following packages, if they are
not already installed on the AMI:
openssh-client openssh-server curl unzip wget rsync parted bc sudo ruby libopenssl-ruby1.8 openjdk-6-jre-headless
This script bootstraps your AWS environment, you can skip this if you already have this done, but you will need to modify the next script to match your environment:
cat > aws_bootstrap.sh << \BOOTEOF #!/bin/bash #EC2 AMI Tools cd /tmp wget http://s3.amazonaws.com/ec2-downloads/ec2-ami-tools.zip -O ec2-ami-tools.zip cd /usr/local unzip /tmp/ec2-ami-tools.zip ln -s `find . -type d -name ec2-ami-tools-*` ec2-ami-tools chmod -R go-rwsx ec2* rm -rf /tmp/ec2*
#EC2 API Tools cd /tmp wget http://s3.amazonaws.com/ec2-downloads/ec2-api-tools.zip cd /usr/local unzip /tmp/ec2-api-tools.zip ln -s `find . -type d -name ec2-api-tools*` ec2-api-tools chmod -R go-rwsx ec2* rm -rf /tmp/ec2*
mkdir ~/.aws cat > ~/.aws/cert.pem <<\EOF -----BEGIN CERTIFICATE----- <snip - insert the text from your certificate> -----END CERTIFICATE----- EOF cat > ~/.aws/pk.pem <<\EOF -----BEGIN PRIVATE KEY----- <snip - insert the text from your private key> -----END PRIVATE KEY----- EOF
cat >~/.aws/aws.sh <<\EOF #!/bin/bash export EC2_PRIVATE_KEY=/mnt/ec2/pk.pem export EC2_CERT=/mnt/ec2/cert.pem export EC2_AMITOOL_HOME=/usr/local/ec2-ami-tools export EC2_APITOOL_HOME=/usr/local/ec2-api-tools export EC2_HOME=/usr/local/ec2-api-tools export JAVA_HOME=/usr export AMAZON_USER_ID=<snip!!!> export AWS_ACCESS_KEY_ID=<snip!!!> export AWS_SECRET_ACCESS_KEY=<snip!!!> PATH=$EC2_AMITOOL_HOME/bin:$PATH EOF chmod -R 600 ~/.aws chmod o+x ~/.aws/aws.sh BOOTEOF
This script does the migration. I could have used rsync instead of ec2-bundle, but this makes sure the resulting image looks like what Amazon is expecting.
cat > migrate2ebs.sh << \MIGEOF # Change these to suit your environment vol_size=20 dev=/dev/sdp desc="My First EBS Migration" rm -rf /usr/local/ec*
# Call the environment setup script . ~/.aws/aws.sh
# Get basic info from instance meta-data instance_id=`curl -s http://169.254.169.254/latest/meta-data/instance-id` avail_zone=`curl -s \ http://169.254.169.254/latest/meta-data/placement/availability-zone`
# Create the Volume vol=`ec2-create-volume -K "$EC2_PRIVATE_KEY" -C "$EC2_CERT" -z "$avail_zone"\ --size $vol_size| cut -f2`
# Attach the volume ec2attvol "$vol" -K "$EC2_PRIVATE_KEY" -C "$EC2_CERT" -i "$instance_id" -d "$dev" while [[ "$vol_status" != "attached" ]]; do vol_status=`ec2-describe-volumes -K "$EC2_PRIVATE_KEY" -C "$EC2_CERT" "$vol"\ | grep ATTACHMENT | cut -f5` echo Status of "$vol" : $vol_status done
# Prepare the volume mkfs.ext3 "$dev" mkdir -p /vol mount "$dev" /vol rm -rf /mnt/image* rm -rf /mnt/img-mnt
# Use bundle to create a clean image (we will not upload) ec2-bundle-vol -c $EC2_CERT -k $EC2_PRIVATE_KEY -u $AMAZON_USER_ID \ -e /vol -d /mnt
# take the clean image and install on the EBS Volume mount -o loop /mnt/image /mnt/img-mnt rsync -av /mnt/img-mnt/ /vol/
# Set the fstab up cat > /vol/etc/fstab << FSTABEOF # <file system> <mount point> <type> <options> <dump> <pass> proc /proc proc defaults 0 0 /dev/sda3 None swap defaults 0 0 /dev/sdb / ext3 defaults 0 0 /dev/sda2 /mnt ext3 defaults 0 0 FSTABEOF
# Snapshot the volume. Note the snapshot id for the registration step umount /vol ec2addsnap -C $EC2_CERT -K $EC2_PRIVATE_KEY -d $desc $vol MIGEOF chmod o+x migrate2ebs.sh
Run the scripts, and note the snapshot id from the last step in the script, you'll need it for the AMI registration
./aws_bootstrap.sh ./migrate2ebs.sh
now all that is left to do is register the snapshot created in the last step
ec2-register -n "MyFirstEBSMigration" -s <snapshotid> -b /dev/sda=ephemeral0 --kernel <kernel> --ramdisk <kernel> --root-device-name /dev/sdb
If everything ran successfully, you should have a brand spanking new EBS based AMI that is a mirror of your old AMI.
This works for us, but your mileage might vary! drop me a line via twitter (@ramarnat) if you have questions.


Comments
Very helpful
Post new comment