How do I migrate Amazon EC2 Windows AMI (or instances) from one region to another?

Solution 1:

Hmmm, no responses, so I went ahead and tried a variant of solution 4. The original solution as-is failed because of

  1. incorrect usage of netcat
  2. changes to the newer linux kernels in how they refer to Windows volumes

So I'll document what worked for me.

Setting it up

We're going to use Linux to copy the Windows volume, byte-for-byte across the network. It's actually very simple, I've just given detailed instructions to assist newbies.

1. Backup your Windows EBS volume at the source region

  1. Shutdown your Windows EC2 instance.
  2. Detach Volume. volumes section -> the Windows volume(Right click) -> Detach Volume.
  3. Create snapshot. Right click it again -> create snapshot.
  4. Note the 'zone' of the volume (eg. 'us-east-1b') somewhere. You need it shortly

2. Create a Linux instance in your source region, in same zone I used Ubuntu, (search for "ubuntu/images" AMIs). Alternatively go to http://alestic.com/ and you'll find links to the latest official Ubuntu AMIs on the top. I used AMI ami-20f97410 as reference.

  1. Pick instance type, t1.micro worked for me. My ubuntu 11.10 32bit instance was at 40% CPU throughout the disk read operation.
  2. Set instance in the SAME zone as your windows volume (eg. 'us-east-1b').
  3. Attach the windows volume to your Linux instance (right click-> attach -> pick linux instance) to something like /dev/sdf (Web UI may change to /dev/xvdf in future). If you don't see your linux instance, the Windows volume and Linux instance are likely in different 'zones' (eg 'us-east-1a' vs 'us-east-1b').
  4. Ensure that port 9999 is open in the security groups
  5. Boot up the Linux instance
  6. do NOT mount the Windows volume (we only want the windows 'hard drive' attached to the 'machine', NOT the Linux OS to mount the filesystem present inside the 'hard drive' device)
  7. install cpipe via sudo apt-get install cpipe

3. Create a blank EBS volume at your destination region

  1. Destination region (top left) -> Volumes -> Create Volume.
  2. I used the same size (30GB) but this is a chance to grow the volume.
  3. Note down the zone (eg. us-west-2a). Ensure it's in the same region that you'd like your Windows EC2 instance to be.

4. Create a Linux instance in your destination region, in same zone Read the above section (#2) about the Linux instance. Again make sure the Linux and Windows volume zones are the same within the destination zone. My Ubuntu 11.10 32bit 'server' t1.micro instance was hitting 80% CPU during this disk write operation.

  1. Boot the instance.
  2. do *NOT** mount the windows volume
  3. Attach the blank, destination windows volume to this Linux instance.

Start the copy process

1. Destination Log into the Linux EC2 instance and enter

sudo sh -c 'netcat -p 9999 -l > /dev/xvdf'

2. Source Log into the Linux EC2 instance and enter

sudo sh -c 'cpipe -vt -b 1024 < /dev/xvdf | netcat -q 1 dest-aws-ip-dns-address.com 9999'

note : More new/current kernels will use /dev/xvdf for the Windows volume. Older kernels refer to it as /dev/sdf

note2 netcat is sometimes aliased to nc, in case you're using another Linux distro. cpipe just gives your feedback about progress and tranfer rates. netcat runs over TCP/IP, so it's robust against dropped/corrupt packets. You'd still want to perform a windows disk check on the destination once the transfer completes.

3. Wait I was getting an exact 3.00MB/sec (Mbytes, not Mbits) throughout this operation from the east to west coast. My 30GB image took 2hours, 50 minutes.

4. Create new Windows EC2 instance We have a volume but a EC2 instance/machine is needed to actually boot anything. If go use the AWS console GUI to go volume->snapshot->AMI, AWS incorrectly creates a Linux (?!?) VM that doesn't boot because the EC2 configuration is now garbage. We work around that by

  1. Create a new Windows EC2 instance in the SAME zone as your volume. You will choose stock Windows AMI's but pick one closest to your actual Windows volume. My source image was Windows 2003 R2, 32bits, EBS backed, so I fired off a (generic) Windows 2003 R2, 32bit, EBS backed AMI too.
  2. Boot this instance completely. Verify by logging in via RDP.
  3. Shutdown this instance
  4. Detach the EBS volume created in #1 just before
  5. Attach the EBS volume you copied over as /dev/sda1 (NOT the default /dev/xvdf in the Web UI dialog)
  6. Reboot.
  7. Safety measure: Check the resulting system's drive (chkdsk).
  8. Enjoy!

5. Cleanup Remember that you've ONLY done the following

  1. Migrated the volume
  2. Recreated the EC2 instance

If you terminate the above, it's gone forever, no AMI to relaunch it. So, I would highly recommend

  1. Build an AMI out of the currently working instance (right click instance -> create image AMI). This is now your new "day 0" reference point.
  2. Make a snapshot of the volume too. Yeah, I know the AMI backup above helps, but I keep weekly backups, so I'd have a "day 7" reference next week anyway. Plus since snapshots are differential, I did this right away.

Conclusion It's a LONG writeup, but I left no details for newbies. The above worked 100% for me migrating from US-East (Virginia) to US-West (Oregon). I'm in CA and did this to bring the VM closer to me without hitting northern CA's higher charges.