Two-men-carrying-woman1947

Converting an OVA to an Amazon AMI

If your job is to migrate applications in or out of public and/or private cloud environments, or maybe you have a VM running locally you might need to move into Amazon’s EC2 service, you’re probably going to have to move a VM in it’s entirety between environments..

Anyway, I had the task of trying to figure out how to move a “VMWare based appliance” into a non-vmware environment, being ec2. It was annoying, but I managed to get it working relatively easily.

Everything below assumes that you have:

  • An AWS account
  • An AWS Access Key
  • An AWS Secret Key
  • Permissions to create EC2 instances, volumes, S3 buckets, s3 objects, User roles, role policies.
  • Some idea what you’re doing.

The first thing you want to do is upload the OVA archive into an s3 bucket of your choosing, preferably one that already exists (i’ll explain why later) and making sure that the bucket is in the region that you want to create the initial AMI in.

Whilst that’s uploading, spin up a small (t2.micro is fine) EC2 instance that uses the Amazon Linux AMI, don’t use ubuntu or your favourite distro – just stick to the Amazon AMI, you’re only going to be using this temporarily to convert the OVA to an AMI, and you don’t need anything resource intensive. You want the Amazon flavour because it comes pre-baked with all of the cli tools, and the right versions. (I first tried it with ubuntu, but ran into some issues with older versions and missing command options).

First thing to do when your VM is spun up, ssh to it and run aws configure and follow the prompts that ask for your credentials. Be sure to pick the region you actually want to deploy the new image in.

$ aws configure 
AWS Access Key ID [None]: 1234 
AWS Secret Access Key [None]: 5678 
Default region name [None]: ap-southeast-2 
Default output format [None]:
You can now now test your credentials by listing the ec2 regions:
$ aws ec2 describe-regions
{
"Regions": [
{
"Endpoint": "ec2.eu-central-1.amazonaws.com",
"RegionName": "eu-central-1"
},
{
"Endpoint": "ec2.sa-east-1.amazonaws.com",
"RegionName": "sa-east-1"
},
}
<snip>

Have the s3 bucket name handy that you uploaded the OVA file to.

Now create two files: trust-policy.json & role-policy.json, in the second file you’ll need to replace “$bucketname” with your bucket name.

trust-policy.json:

{
   "Version":"2012-10-17",
   "Statement":[
      {
         "Sid":"",
         "Effect":"Allow",
         "Principal":{
            "Service":"vmie.amazonaws.com"
         },
         "Action":"sts:AssumeRole",
         "Condition":{
            "StringEquals":{
               "sts:ExternalId":"vmimport"
            }
         }
      }
   ]
}

role-policy.json:

{
   "Version":"2012-10-17",
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "s3:ListBucket",
            "s3:GetBucketLocation"
         ],
         "Resource":[
            "arn:aws:s3:::$bucketname"
         ]
      },
      {
         "Effect":"Allow",
         "Action":[
            "s3:GetObject"
         ],
         "Resource":[
            "arn:aws:s3:::$bucketname/*"
         ]
      },
      {
         "Effect":"Allow",
         "Action":[
            "ec2:ModifySnapshotAttribute",
            "ec2:CopySnapshot",
            "ec2:RegisterImage",
            "ec2:Describe*"
         ],
         "Resource":"*"
      }
   ]
}

Now, use the aws cli tools to apply the policies:

$ aws iam create-role --role-name vmimport --assume-role-policy-document file://trust-policy.json
$ aws iam put-role-policy --role-name vmimport --policy-name vmimport --policy-document file://role-policy.json

Ok, you should be able to now start the import of your OVA, copy what I have below, changing the descriptions, bucket name and the file name of the OVA you uploaded:

$ aws ec2 import-image --cli-input-json "{  \"Description\": \”Description of my OVA\", \"DiskContainers\": [ { \"Description\": \”Disk Description\", \"UserBucket\": { \"S3Bucket\": \”bucketname\", \"S3Key\" : \”OVAFILENAME.ova\" } } ]}"

If you didn’t get any errors, you should now be able to watch your import progress by running aws ec2 describe-import-image-tasks:

$ aws ec2 describe-import-image-tasks
{
 "ImportImageTasks": [
 {
 "Status": "completed",
 "LicenseType": "BYOL",
 "Description": "Description of my OVA",
 "ImageId": "ami-d5abc1234",
 "Platform": "Linux",
 "Architecture": "x86_64",
 "SnapshotDetails": [
 {
 "UserBucket": {
 "S3Bucket": "bucketname",
 "S3Key": "OVAFILENAME.ova"
 },
 "SnapshotId": "snap-abc1234",
 "DiskImageSize": 535459840.0,
 "DeviceName": "/dev/sda1",
 "Format": "VMDK"
 }
 ],
 "ImportTaskId": "import-ami-fg4d51t0"
 }
 ]
}

Once that completes (it can take a while) you should be able to launch an EC2 instance, from your AMI. Login to AWS, Goto EC2 -> AMIs -> select your AMI then Launch!

Cheers!

15 Responses

Add a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.