Skip to main content

Amazon EC2 Paravirtual Virtualization Type Should Not Be Used

Overview

This check identifies EC2 instances using the older paravirtual virtualization type instead of the modern HVM (Hardware Virtual Machine) type. HVM instances provide better performance, security isolation, and access to modern AWS features.

Risk

Paravirtual instances present several security and performance concerns:

  • Weaker isolation - PV instances lack the hardware-level isolation that HVM and Nitro instances provide
  • Missing modern features - Cannot use Enhanced Networking (ENA), NVMe storage, or Nitro security features
  • Increased vulnerability exposure - Legacy hypercalls and drivers increase the attack surface
  • Performance limitations - May experience degraded performance under load

Remediation Steps

Prerequisites

You need permission to view and manage EC2 instances in your AWS account. The migration process requires stopping your existing workload, so plan for a maintenance window.

Required IAM permissions

Your IAM user or role needs these permissions:

  • ec2:DescribeInstances
  • ec2:RunInstances
  • ec2:TerminateInstances
  • ec2:StopInstances
  • ec2:StartInstances

AWS Console Method

  1. Open the EC2 Console
  2. Select the instance you want to check
  3. In the Details tab, look for Virtualization type
    • If it shows paravirtual, proceed with migration
    • If it shows hvm, no action is needed
  4. To migrate to HVM:
    • Back up any data on the instance (create an AMI or snapshot EBS volumes)
    • Launch a new instance using a modern HVM-based AMI (such as Amazon Linux 2023)
    • Reinstall your application and restore data to the new instance
    • Test the new instance thoroughly
    • Once verified, terminate the old paravirtual instance

Important: You cannot convert a paravirtual instance to HVM in place. You must launch a new instance with an HVM AMI and migrate your workload.

AWS CLI (optional)

Find paravirtual instances:

aws ec2 describe-instances \
--region us-east-1 \
--filters "Name=virtualization-type,Values=paravirtual" \
--query "Reservations[*].Instances[*].[InstanceId,InstanceType,VirtualizationType]" \
--output table

Launch a new HVM instance:

# Get the latest Amazon Linux 2023 AMI (HVM)
AMI_ID=$(aws ssm get-parameters \
--region us-east-1 \
--names /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64 \
--query "Parameters[0].Value" \
--output text)

# Launch a new instance with HVM virtualization
aws ec2 run-instances \
--region us-east-1 \
--image-id "$AMI_ID" \
--instance-type t3.micro \
--subnet-id <your-subnet-id> \
--security-group-ids <your-security-group-id> \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=HVM-Instance}]'

Terminate the old paravirtual instance (after migration is complete):

aws ec2 terminate-instances \
--region us-east-1 \
--instance-ids <paravirtual-instance-id>

Warning: Terminating an instance is permanent and irreversible. Ensure you have migrated all data before terminating.

CloudFormation (optional)

This template creates an EC2 instance using HVM virtualization with a modern instance type:

AWSTemplateFormatVersion: '2010-09-09'
Description: EC2 instance using HVM virtualization (modern instance type)

Parameters:
InstanceType:
Type: String
Default: t3.micro
Description: EC2 instance type (must support HVM)
AllowedValues:
- t3.micro
- t3.small
- t3.medium
- m5.large
- m5.xlarge

AmiId:
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64
Description: Amazon Linux 2023 AMI (HVM)

SubnetId:
Type: AWS::EC2::Subnet::Id
Description: Subnet to launch the instance in

SecurityGroupId:
Type: AWS::EC2::SecurityGroup::Id
Description: Security group for the instance

Resources:
EC2Instance:
Type: AWS::EC2::Instance
Properties:
InstanceType: !Ref InstanceType
ImageId: !Ref AmiId
SubnetId: !Ref SubnetId
SecurityGroupIds:
- !Ref SecurityGroupId
Tags:
- Key: Name
Value: HVM-Instance

Outputs:
InstanceId:
Description: Instance ID
Value: !Ref EC2Instance
VirtualizationType:
Description: Virtualization type (should be hvm)
Value: hvm

Deploy the stack:

aws cloudformation create-stack \
--region us-east-1 \
--stack-name hvm-ec2-instance \
--template-body file://template.yaml \
--parameters \
ParameterKey=SubnetId,ParameterValue=<your-subnet-id> \
ParameterKey=SecurityGroupId,ParameterValue=<your-security-group-id>
Terraform (optional)
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}

provider "aws" {
region = "us-east-1"
}

# Data source to get the latest Amazon Linux 2023 AMI (HVM)
data "aws_ami" "amazon_linux_2023" {
most_recent = true
owners = ["amazon"]

filter {
name = "name"
values = ["al2023-ami-*-kernel-*-x86_64"]
}

filter {
name = "virtualization-type"
values = ["hvm"]
}

filter {
name = "architecture"
values = ["x86_64"]
}
}

# EC2 instance using HVM virtualization
resource "aws_instance" "hvm_instance" {
ami = data.aws_ami.amazon_linux_2023.id
instance_type = var.instance_type
subnet_id = var.subnet_id

vpc_security_group_ids = [var.security_group_id]

tags = {
Name = "HVM-Instance"
}
}

variable "instance_type" {
description = "EC2 instance type (must support HVM)"
type = string
default = "t3.micro"
}

variable "subnet_id" {
description = "Subnet ID to launch the instance in"
type = string
}

variable "security_group_id" {
description = "Security group ID for the instance"
type = string
}

output "instance_id" {
description = "ID of the created EC2 instance"
value = aws_instance.hvm_instance.id
}

output "virtualization_type" {
description = "Virtualization type of the AMI (should be hvm)"
value = data.aws_ami.amazon_linux_2023.virtualization_type
}

Deploy:

terraform init
terraform apply -var="subnet_id=<your-subnet-id>" -var="security_group_id=<your-sg-id>"

Verification

After creating your new instance, verify it uses HVM virtualization:

  1. In the EC2 Console, select your new instance
  2. Check the Details tab - Virtualization type should show hvm
CLI verification
aws ec2 describe-instances \
--region us-east-1 \
--instance-ids <your-instance-id> \
--query "Reservations[*].Instances[*].[InstanceId,VirtualizationType]" \
--output table

Expected output:

---------------------------------
| DescribeInstances |
+----------------------+--------+
| i-0123456789abcdef0 | hvm |
+----------------------+--------+

Additional Resources

Notes

  • Migration required: Paravirtual instances cannot be converted to HVM in place. You must launch a new instance and migrate your workload.
  • Instance type selection: All current-generation instance types (t3, m5, c5, r5, etc.) use HVM. Legacy instance types like t1, m1, m2, c1 used paravirtual and are no longer recommended.
  • AMI compatibility: Ensure you select an HVM-compatible AMI. Most modern AMIs (Amazon Linux 2, Amazon Linux 2023, Ubuntu 18.04+, etc.) are HVM-based.
  • Cost consideration: Modern HVM instance types often provide better price-performance than legacy paravirtual instances.