There are two options for migration - one is to create the image from within the running VMware machine, the other is to convert the VMDK file into a RAW image.

I plan to create some base 'clean' images from which I can then create specific appliances - for example a base Centos i386 and x64 install which I will then layer additional software on to create specific appliance images.

My preferred method is to create the AMI from within the running VMware machine - the resulting AMI is much smaller in size (as I think that during conversion of a VMDK the resulting RAW image is the size of the volume rather than the data - although you can probably override this with options). I've given instructions for both methods so you can make your own mind up.

Converting VMDK files for use on EC2

Create your machine in VMware as usual and when ready shut it down. Then, grab yourself a copy of QEMU as we need to use it to convert the VMDK files.

Basic usage is:

qemu-img convert -O raw input.vmdk output.raw

The VMDK file will then be converted into a RAW file - we've specified the output format with the -O tag and qemu-img is intelligent enough to figure out the input format.

Your image may span several VMDKs in which case you'll need to run a simple shell loop, for example:

for file in `ls *[0-9].vmdk`; do
  qemu-img convert -O raw $file $file.raw
done
cat *.raw >> output.raw

Depending on the number of files you have for your VMware image you might need to modify the ls - my example is purely by way of demonstration.

Either way, you should now have your VMware disk image in RAW format in the file output.raw. Given this is a RAW image it should also be bootable by a local Xen, QEMU or KVM installation.

The next step is to bundle this into an AMI using ec2-bundle-image:

ec2-bundle-image -i output.raw -r x86_64 -c ~/.amazon/cert.pem -k ~/.amazon/pk.pem --user <user id>

The exact values for the -c, -k and --user parameters will depend on the location of your certificate, private key and Amazon AWS account number respectively.

You might also want to look closely at the documentation for the --block-device-mapping parameter to ensure you get a bootable machine with a valid fstab.

After the image has finished bundling it will (by default) be in your /tmp directory, so the next step is to upload it to an S3 bucket:

ec2-upload-bundle -b <bucket name> -m /tmp/image.manifest.xml -a <access id> -s <secret access id>

With the bundled image in S3 (it will take a while depending on your connection) then you can register the image:

ec2-register <bucket name>/image.manifest.xml

The AMI should then appear when you request a list of your images:

ec2-describe-images

The only remaining thing then is to start up an instance and give it a try!

Creating the EC2 AMI from within VMware

As mentioned, creating the AMI in this way seems to result in a smaller file - I prefer it as it's also quicker to complete as you don't need to convert and create bundle - you can just create the bundle.

You'll need to boot your VMware machine and make sure you have the pre-requisites installed to run the EC2 and AMI tools - i.e. ruby, java > 1.5, etc.

For CentOS I needed to disable the MAC address being specified for my Ethernet device by commenting out the HWADDRESS line of the network script.

Check the amount of disk space you're using - for me it was 1.2Gb for my basic Centos 5.2 install.

You're then ready to bundle your volume, making sure you specify a size big enough to fit your volumes into along with any software you might want to install in future:

ec2-bundle-vol -c ~/.amazon/cert.pem -k ~/.amazon/pk.pem --user <user id> -d /image -e /image -r x86_64 -s 4096 --no-inherit

Depending on your install you may also need to specify an alternative fstab to use via the --fstab option. The -s parameter specifies the size - 4Gb in this example - you can set this up to 10Gb which is the current limit imposed by EC2. The --no-inherit parameter is required because we're not bundling from within an EC2 instance.

After the image has finished bundling it will be in your /image directory (because we specified this in our command) - so the next step is to upload it to an S3 bucket:

ec2-upload-bundle -b <bucket name> -m /image/image.manifest.xml -a <access id> -s <secret access id>

With the bundled image in S3 (it will take a while depending on your connection) then you can register the image:

ec2-register <bucket name>/image.manifest.xml

The AMI should then appear when you request a list of your images:

ec2-describe-images

You can then launch an instance using your new AMI (the AMI id will have been provided on completion of the registration, or from the output of the describe command).