Convert Amazon EC2 AMI to Virtual or Vagrant box

Justin W. picture Justin W. · Feb 20, 2014 · Viewed 29.8k times · Source

I'd like to copy the disk image of a running EC2 instance (grab the AMI) and import it into virtual box or eventually have it run using Vagrant. I saw that packer (http://www.packer.io/) allows you to create AMI's and corresponding Vagrant boxes to work together, however the running instance I currently have has been running for over two years and would be difficult to replicate.

I imagine that this issue is common in the devops community however have not found a solution in my research online. Are there any tools out there that let you accomplish this task?

Answer

BillMan picture BillMan · Jan 6, 2015

I just wanted to note that @Drewness answered this question in the first comment to the original question. I'm just adding this answer to make it more clear because the answer is link to in an anchor tag too. The link points toward the following page: How to convert EC2 AMI to VMDK for Vagrant.

So basically you need to enable root SSH access, e.g.

$ sudo perl -i -pe 's/#PermitRootLogin .*/PermitRootLogin without-password/' /etc/ssh/sshd_config
$ sudo perl -i -pe 's/.*(ssh-rsa .*)/\1/' /root/.ssh/authorized_keys
$ sudo /etc/init.d/sshd reload # optional command<br>

Then copy the running system to a local disk image:

$ ssh -i ~/.ec2/your_key [email protected] 'dd if=/dev/xvda1 bs=1M | gzip' | gunzip | dd of=./ec2-image.raw

After that prepare a filesystem on a new image file:

$ dd if=/dev/zero of=vmdk-image.raw bs=1M count=10240 # create a 10gb image file
$ losetup -fv vmdk-image.raw # mount as loopback device
$ cfdisk /dev/loop0 # create a bootable partition, write, and quit
$ losetup -fv -o 32256 vmdk-image.raw # mount the partition with an offset
$ fdisk -l -u /dev/loop0 # get the size of the partition
$ mkfs.ext4 -b 4096 /dev/loop1 $(((20971519 - 63)*512/4096)) # format using the END number

Now you need to copy everything from the EC2 image to the empty image:

$ losetup -fv ec2-image.raw
$ mkdir -p /mnt/loop/1 /mnt/loop/2 # create mount points
$ mount -t ext4 /dev/loop1 /mnt/loop/1 # mount vmdk-image
$ mount -t ext4 /dev/loop2 /mnt/loop/2 # mount ami-image
$ cp -a /mnt/loop/2/* /mnt/loop/1/

and install Grub:

$ cp /usr/lib/grub/x86_64-pc/stage* /mnt/loop/1/boot/grub/

and unmount the device (umount /dev/loop1) and convert the raw disk image to a vmdk image:

$ qemu-img convert -f raw -O vmdk vmdk-image.raw final.vmdk

Now just create a VirtualBox VM with the vmdk image mounted as the primary boot device.

Unfortunately at this point I could not get the Amazon Linux kernel to boot inside VirtualBox.