Converting Paravirtual (PV) AMI to Hardware Virtual Machine (HVM) AMI on AWS: A Step-by-Step Guide


2 views

When working with legacy AWS infrastructure, you might encounter paravirtual (PV) AMIs that need conversion to hardware virtual machine (HVM) format. While AWS has largely moved to HVM as the default virtualization type, certain older systems still rely on PV AMIs. The conversion isn't straightforward because:

  • ec2-create-image doesn't expose virtualization type parameters
  • Direct modification of existing AMIs isn't supported
  • Kernel and bootloader requirements differ between PV and HVM

Here's the most reliable approach I've found through extensive testing:

# Launch your source PV instance
aws ec2 run-instances \
    --image-id ami-pv123456 \
    --instance-type t2.small \
    --key-name my-key-pair

# Stop the instance before creating image
aws ec2 stop-instances --instance-ids i-0123456789abcdef

After instance preparation:

# Create new AMI (will inherit PV type)
aws ec2 create-image \
    --instance-id i-0123456789abcdef \
    --name "Converted_HVM_Base" \
    --description "PV-to-HVM conversion base"

Use the AWS CLI to update the virtualization type:

aws ec2 modify-image-attribute \
    --image-id ami-987654321 \
    --virtualization-type hvm

Important caveats:

  • This only works for AMIs you own
  • The source instance must be properly prepared (clean shutdown, no pending operations)
  • Some AWS regions may enforce additional restrictions

Always validate your converted AMI:

# Check virtualization type
aws ec2 describe-images \
    --image-ids ami-987654321 \
    --query 'Images[].VirtualizationType'

# Test launch
aws ec2 run-instances \
    --image-id ami-987654321 \
    --instance-type t3.medium \
    --key-name my-key-pair

For more complex scenarios, consider using HashiCorp Packer:

{
  "builders": [{
    "type": "amazon-ebs",
    "source_ami": "ami-pv123456",
    "instance_type": "t2.medium",
    "ssh_username": "ec2-user",
    "ami_name": "converted-hvm-{{timestamp}}",
    "virtualization_type": "hvm",
    "ami_regions": ["us-east-1"]
  }]
}

When working with legacy AWS environments, you might encounter paravirtual (PV) AMIs that need conversion to hardware virtual machine (HVM) format. While AWS has been phasing out PV in favor of HVM (since 2017 for newer instance types), migration remains necessary for certain workloads.

The ec2-create-image command doesn't support virtualization type specification because:

  • Virtualization type is fundamentally tied to the AMI's kernel and boot process
  • PV AMIs use special drivers (Xen-specific) while HVM uses hardware-assisted virtualization
  • The disk partitioning scheme differs (PV uses / partition, HVM commonly uses GPT)

Here's the proper workflow to convert PV to HVM:


# Launch the source PV instance
aws ec2 run-instances \
  --image-id ami-pv123456 \
  --instance-type m1.small \
  --key-name my-keypair
  
# Connect and prepare the volume
sudo su
mkdir /mnt/source /mnt/target
# For RedHat/CentOS:
yum install -y grub2
# For Debian/Ubuntu:
apt-get install -y grub-pc

After instance preparation:

  1. Create new EBS volume with HVM requirements
  2. Copy filesystem while preserving permissions
  3. Install GRUB bootloader for HVM

# Create snapshot of the prepared volume
aws ec2 create-snapshot \
  --volume-id vol-12345678 \
  --description "HVM-converted from PV AMI"
  
# Register the new HVM AMI
aws ec2 register-image \
  --name "Converted-HVM-AMI" \
  --architecture x86_64 \
  --root-device-name "/dev/xvda" \
  --block-device-mappings "[
    {\"DeviceName\": \"/dev/xvda\", 
     \"Ebs\": {\"SnapshotId\": \"snap-12345678\"}}
  ]" \
  --virtualization-type hvm

Boot failures often occur due to:

  • Missing HVM-compatible kernel (install latest kernel package)
  • Incorrect grub configuration (check /boot/grub/menu.lst)
  • Partition alignment issues (use fdisk with 1M alignment)

For quick testing, you can attempt direct conversion using:


aws ec2 describe-images --image-ids ami-pv123456 \
  --query 'Images[0].BlockDeviceMappings' > mapping.json
# Edit mapping.json to update virtualization type
aws ec2 register-image --cli-input-json file://mapping.json

Note this method has limitations and may not work for all AMI configurations.