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]:
$ 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!
Thank you for writing this up! Your instructions were easy to follow, and worked like charm! Although the AWS docs are good, I wanted a bit more than the theory they lay out. Real life command line intructions, and the two JSON documents. Thank you again!
No problems, Thanks for the feedback.
Thank for ur document and its really helpful but i came across one issue and want to check if u can help in this regard as i m trying to import csr1000v cisco image and here is what where need ur help.
[[email protected] ~]$ aws ec2 describe-import-image-tasks
{
“ImportImageTasks”: [
{
“Status”: “deleted”,
“SnapshotDetails”: [
{
“UserBucket”: {
“S3Bucket”: “image-ovf”,
“S3Key”: “csr1000v-universalk9.03.16.02.S.155-3.S2-ext.ova”
},
“DiskImageSize”: 73216.0,
“Format”: “VMDK”
}
],
“Description”: “Description of my CISCO-OVA”,
“StatusMessage”: “ClientError: No valid partitions. Not a valid volume.”,
“ImportTaskId”: “import-ami-fg3q52d4”
}
]
}
[[email protected] ~]$
+We can clearly see in ClientError in “StatusMessage” above.
On further checking on Google might be the only supported OVA for Owned AMI are windows which i need to verified but based on this link /error getting thats the case is this correct or we can use any ova and it should work ?
https://forums.aws.amazon.com/message.jspa?messageID=285858
Hey mate,
Sorry, i’ve been busy and sick, haven’t had any time to take another look at this until now.
I found a version of that ova online and tried it, But I think maybe that ova has a partition layout that’s preventing it from working. Did you end up getting it working?
Thanks for the amazing writeup. I followed the article to a tee and I get the following error:
A client error (InvalidParameter) occurred when calling the ImportImage operation: The service role does not exist or does not have sufficient permissions for the service to continue
I then modified your permissions according to this document: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/VMImportPrerequisites.html#vmimport-iam-permissions
I checked in the console and the role exists after running your commands from the cli.
Any assistance is helpful. Thanks
I’m trying to import an OVA for a pfSense instance (FreeBSD) and seeing the same which further supports the theory that only Windows OVA are supported.
Thank you very much for this guide.
Great to get things done without going through all the Amazon doc.
Thank you for writing this page
what version AWSCLI you because in recent version 1.10.x I’m getting this error can you look into this
Traceback (most recent call last):
File “/usr/local/bin/aws”, line 27, in
sys.exit(main())
File “/usr/local/bin/aws”, line 23, in main
return awscli.clidriver.main()
File “/usr/local/aws/local/lib/python2.7/site-packages/awscli/clidriver.py”, line 50, in main
return driver.main()
File “/usr/local/aws/local/lib/python2.7/site-packages/awscli/clidriver.py”, line 212, in main
sys.stderr.write(“%s\n” % e)
Thank you very much for this tutorial. I was trying for some time to create an AMI of my company’s OS and with the Amazon Documentation I couldn’t make it, and with this it went well in the first time !
Hi, Im having issues with this command.
$ aws ec2 import-image –cli-input-json “{ \”Description\”: \”Description of my OVA\”, \”DiskContainers\”: [ { \”Description\”: \”Disk Description\”, \”UserBucket\”: { \”S3Bucket\”: \”bucketname\”, \”S3Key\” : \”OVAFILENAME.ova\” } } ]}”
i got this error:
Error parsing parameter ‘cli-input-json’: Invalid JSON: No JSON object could be decoded
JSON received: { “Description”: \”ubuntu vmware”, “DiskContainers”: [ { “Description”: \”ubuntu from vmware”, “UserBucket”: { “S3Bucket”: \”ovavalueline”, “S3Key” : \”ubuntuxaws.ova” } } ]}
I changed the descriptions and bucket name and filename, but i got the errors
aws ec2 import-image –cli-input-json “{ \”Description\”: \”ubuntu vmware\”, \”DiskContainers\”: [ { \”Description\”: \”ubuntu from vmware\”, \”UserBucket\”: { \”S3Bucket\”: \”ovavalueline\”, \”S3Key\” : \”ubuntuxaws.ova\” } } ]}”
I don’t think it’s got to do with your inputs, but specifically the json that’s wrapping your inputs. What might be happening is that the wordpress theme is replacing the ” characters because of the theme.
Try this: https://pastebin.com/gLSYHKqJ
Jake it’s the quotes which gives the errror.
I have a question which i’m stuck since two hours. Everything worked when i was converting my OVA into Amazon AMI. When it’s in a pending state of conversion it automatically stops and terminates.
The issue which is coming – > Disk validation failed [OVF file parsing error: Content is not allowed in prolog.]”
This sounds like bad data in the json, maybe a bad character?
Maybe try without copy-pasting from this site, I know the fonts can sometimes replace some characters for others.
Hello Jake,
I have done this before and it was work at that time the same you documented but I have one customer OS that I want to migrate on AWS and I faced below error.
{
“ImportImageTasks”: [
{
“Description”: “onpremisesvm”,
“ImportTaskId”: “import-ami-069263dc99c678fde”,
“SnapshotDetails”: [
{
“Description”: “onpremisesvm”,
“DiskImageSize”: 7487321600.0,
“Format”: “VMDK”,
“Status”: “completed”,
“UserBucket”: {
“S3Bucket”: “myonpremisesvm”,
“S3Key”: “Nodegrid_4.2.7-disk1.vmdk”
}
}
],
“Status”: “deleted”,
“StatusMessage”: “ClientError: Multiple different grub/menu.lst files found.”,
“Tags”: []
}
]
}
don’t know what is wrong with that just to let you know I am using vmdk.
You’ll need to look inside the VM – it’s complaining that there’s multiple grub/menu.lst files so the conversion is getting confused.