terraform-provider-aws icon indicating copy to clipboard operation
terraform-provider-aws copied to clipboard

Create an AMI by importing virtual machine images from any virtualization environment

Open mchouque opened this issue 6 years ago • 9 comments

Hello,

With EC2 on AWS, you can use AMIs provided by Amazon or you can "bring your own OS".

Namely you can (it's documented here Importing a VM as an Image Using VM Import/Export:)

  • upload a copy of an existing OS disk image you have to a S3 bucket with "aws s3 cp myimage" (can be a vhd, vmdk or ova file)
  • trigger a conversion to an AMI using "aws ec2 import-image"

When it's done, you have an AMI that was created with the disk image you provided: your own OS tailored to your needs.

In a nutshell, with google, the code to do that is as follow (don't mind the crappy variable names and code, I'm just starting using terraform):

resource "google_storage_bucket_object" "linux-image" {
  name   = "${var.file_name}"
  source = "${var.image_path}/${var.file_name}"
  bucket = "${google_storage_bucket.linux-bucket.name}"
}

resource "google_compute_image" "linux-image" {
  name        = "${var.image_name}"
  family      = "${var.image_family}"
  description = "${var.image_description}"

  raw_disk {
    source = "https://storage.googleapis.com/${var.bucket_name}/${google_storage_bucket_object.linux-image.name}"
  }
}

Namely two resources: one to upload a file to a bucket, the other to "transform" it.

With Azure, it's very similar: 2 resources. One to upload the image, and one to convert it.

resource "azurerm_storage_blob" "linux-image" {
  name                   = "${var.image_name}"
  resource_group_name    = "${var.resource_group}"
  storage_account_name   = "${azurerm_storage_account.linux-bucket.name}"
  storage_container_name = "${azurerm_storage_container.linux-container.name}"
  type                   = "page"
  source                 = "${var.image_path}/${var.image_name}"
}

resource "azurerm_image" "linux-image" {
  name                = "${var.image_name_short}"
  resource_group_name = "${var.resource_group}"
  location            = "${var.bucket_location}"

  os_disk {
    os_type  = "Linux"
    blob_uri = "${azurerm_storage_blob.linux-image.url}"
  }
}

With Amazon, we have the first resource, it's "aws_s3_bucket_object".

The only thing missing in terraform for AWS is the equivalent of the second resource, azurerm_image for Azure or google_compute_image for Google.

On EC2, the conversion is triggered by "aws ec2 import-image" and I believe the API call for that is ImportImage.

Let me know if you have any questions.

Regards, Mathieu

mchouque avatar Sep 26 '18 20:09 mchouque

Is there any way of doing this yet with Terraform in AWS?

ghost avatar Jul 01 '20 14:07 ghost

same question here, is it possible now?

zzzuzik avatar Jul 24 '20 17:07 zzzuzik

I would love to see a Terraform resource for this as well!

km274 avatar Nov 17 '21 02:11 km274

This is possible now through a combination of aws_ebs_snapshot_import and aws_ami.

alexeiser avatar Jun 15 '22 15:06 alexeiser

This is possible now through a combination of aws_ebs_snapshot_import and aws_ami.

This is not true for all cases. You need image import, not snapshot import for a number of use cases.

I started https://github.com/hashicorp/terraform-provider-aws/pull/25621 to try and support this.

artificial-aidan avatar Jun 29 '22 21:06 artificial-aidan

This is possible now through a combination of aws_ebs_snapshot_import and aws_ami.

This is not true for all cases. You need image import, not snapshot import for a number of use cases.

I started #25621 to try and support this.

Hopefully they will accept your MR - out of curiosity what use case does the import handle that the snapshot import and custom ami creation step not handle?

alexeiser avatar Jun 29 '22 21:06 alexeiser

When I imported a Windows VM disk, then created an AMI, a Linux AMI was created. aws_ami doesn't allow platform specification.

artificial-aidan avatar Jun 30 '22 01:06 artificial-aidan

Is this enhancement still actively being considered? Is there an ETA on when it could be implemented if so? I need to create an EC2 from an OVA appliance that was sent to us by the vendor and the preferred way of doing that would be with Terraform.

trevor-viljoen avatar Oct 18 '22 22:10 trevor-viljoen

We have this exact use case - importing a number of images from S3 into our image builder pipeline.

liamraeAL avatar Feb 23 '23 09:02 liamraeAL