Skip to main content

Check for EC2 Instances Using Outdated AMIs

Overview

This check identifies EC2 instances running on deprecated or outdated Amazon Machine Images (AMIs). AWS marks AMIs as deprecated when they are no longer receiving updates, security patches, or official support. Running instances on deprecated AMIs leaves your workloads exposed to known vulnerabilities.

Risk

Using outdated AMIs creates several security and operational concerns:

  • Security vulnerabilities: Deprecated AMIs no longer receive security patches, leaving instances exposed to known CVEs and exploits
  • Operational limitations: Unsupported components make it harder to harden your environment and complicate incident response
  • Availability risk: When deprecated AMIs are eventually removed from AWS catalogs, you may face complications during scaling events or disaster recovery

Remediation Steps

Prerequisites

You need:

  • Access to the AWS Console with permissions to view and manage EC2 instances
  • If using Auto Scaling Groups: permission to modify launch templates and trigger instance refreshes
Required IAM permissions

To remediate this finding, your IAM user or role needs these permissions:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances",
"ec2:DescribeImages",
"ec2:RunInstances",
"ec2:TerminateInstances",
"ec2:CreateLaunchTemplateVersion",
"ec2:ModifyLaunchTemplate",
"autoscaling:StartInstanceRefresh",
"autoscaling:DescribeAutoScalingGroups"
],
"Resource": "*"
}
]
}

AWS Console Method

The remediation approach differs depending on whether your instance is standalone or part of an Auto Scaling Group.

For Standalone EC2 Instances

  1. Open the EC2 Console
  2. Select the instance using the outdated AMI
  3. Note the instance's current configuration (instance type, security groups, IAM role, key pair, etc.)
  4. In the left navigation, click AMIs under Images
  5. Filter by Owner: Amazon to find official AWS AMIs
  6. Search for a current, non-deprecated AMI that matches your requirements (e.g., Amazon Linux 2023, Ubuntu 24.04)
  7. Select the AMI and click Launch instance from AMI
  8. Configure the new instance to match your original instance settings
  9. Launch the instance and verify your application works correctly
  10. Migrate any data or workloads from the old instance to the new one
  11. Once verified, terminate the old instance

Important: Plan for downtime or use a blue-green deployment strategy if your workload requires high availability.

For Auto Scaling Groups

  1. Open the EC2 Console
  2. In the left navigation, click AMIs under Images
  3. Filter by Owner: Amazon and find a current, non-deprecated AMI
  4. Note the AMI ID (e.g., ami-0abcdef1234567890)
  5. Navigate to Launch Templates in the left navigation
  6. Select the launch template used by your Auto Scaling Group
  7. Click Actions > Modify template (Create new version)
  8. Under Application and OS Images, enter the new AMI ID
  9. Click Create template version
  10. Set the new version as the default: Actions > Set default version
  11. Navigate to Auto Scaling Groups (under Auto Scaling in the left navigation)
  12. Select your Auto Scaling Group
  13. Click the Instance refresh tab
  14. Click Start instance refresh
  15. Configure refresh settings (minimum healthy percentage, warmup time) and click Start

The instance refresh will gradually replace old instances with new ones running the updated AMI.

AWS CLI

Identify Instances Using Deprecated AMIs

First, list all your instances and their AMI IDs:

aws ec2 describe-instances \
--region us-east-1 \
--query 'Reservations[*].Instances[*].[InstanceId,ImageId,State.Name]' \
--output table

Check if a specific AMI is deprecated:

aws ec2 describe-images \
--region us-east-1 \
--image-ids ami-0abcdef1234567890 \
--include-deprecated \
--query 'Images[*].[ImageId,Name,DeprecationTime,State]' \
--output table

Find a Replacement AMI

Search for current Amazon Linux 2023 AMIs:

aws ec2 describe-images \
--region us-east-1 \
--owners amazon \
--filters "Name=name,Values=al2023-ami-2023*-x86_64" \
"Name=state,Values=available" \
--query 'sort_by(Images, &CreationDate)[-1].[ImageId,Name,CreationDate]' \
--output table

For Standalone Instances

Launch a replacement instance with the new AMI:

aws ec2 run-instances \
--region us-east-1 \
--image-id ami-0new-ami-id-here \
--instance-type t3.micro \
--key-name <your-key-pair> \
--security-group-ids sg-0123456789abcdef0 \
--subnet-id subnet-0123456789abcdef0 \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=MyNewInstance}]'

After migrating your workload and verifying the new instance, terminate the old one:

aws ec2 terminate-instances \
--region us-east-1 \
--instance-ids i-0old-instance-id

For Auto Scaling Groups

Create a new launch template version with the updated AMI:

aws ec2 create-launch-template-version \
--region us-east-1 \
--launch-template-name <your-launch-template-name> \
--source-version '$Latest' \
--launch-template-data '{"ImageId":"ami-0new-ami-id-here"}' \
--version-description "Updated to non-deprecated AMI"

Set the new version as the default:

aws ec2 modify-launch-template \
--region us-east-1 \
--launch-template-name <your-launch-template-name> \
--default-version '$Latest'

Start an instance refresh to roll out the new AMI:

aws autoscaling start-instance-refresh \
--region us-east-1 \
--auto-scaling-group-name <your-asg-name> \
--preferences '{"MinHealthyPercentage":90,"InstanceWarmup":300}'

Monitor the refresh progress:

aws autoscaling describe-instance-refreshes \
--region us-east-1 \
--auto-scaling-group-name <your-asg-name> \
--query 'InstanceRefreshes[0].[Status,PercentageComplete,StatusReason]' \
--output table
CloudFormation

If you manage your infrastructure with CloudFormation, update the ImageId property in your launch template or EC2 instance resource.

Launch Template Example

AWSTemplateFormatVersion: '2010-09-09'
Description: Launch template with current AMI

Parameters:
LatestAmiId:
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64
Description: SSM parameter for latest Amazon Linux 2023 AMI

Resources:
MyLaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateName: my-updated-launch-template
LaunchTemplateData:
ImageId: !Ref LatestAmiId
InstanceType: t3.micro
SecurityGroupIds:
- sg-0123456789abcdef0
TagSpecifications:
- ResourceType: instance
Tags:
- Key: Name
Value: MyInstance

MyAutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
AutoScalingGroupName: my-asg
LaunchTemplate:
LaunchTemplateId: !Ref MyLaunchTemplate
Version: !GetAtt MyLaunchTemplate.LatestVersionNumber
MinSize: 1
MaxSize: 3
DesiredCapacity: 2
VPCZoneIdentifier:
- subnet-0123456789abcdef0
- subnet-0123456789abcdef1

Tip: Using AWS::SSM::Parameter::Value with the /aws/service/ami-amazon-linux-latest/ path automatically retrieves the latest AMI ID, so your stack always uses a current image.

Standalone EC2 Instance Example

AWSTemplateFormatVersion: '2010-09-09'
Description: EC2 instance with current AMI

Parameters:
LatestAmiId:
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64

Resources:
MyInstance:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref LatestAmiId
InstanceType: t3.micro
SecurityGroupIds:
- sg-0123456789abcdef0
SubnetId: subnet-0123456789abcdef0
Tags:
- Key: Name
Value: MyCurrentInstance

Deploy or update the stack:

aws cloudformation deploy \
--region us-east-1 \
--template-file template.yaml \
--stack-name my-ec2-stack \
--capabilities CAPABILITY_IAM
Terraform

Using AWS SSM Parameter for Latest AMI

# Automatically fetch the latest Amazon Linux 2023 AMI
data "aws_ssm_parameter" "al2023_ami" {
name = "/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64"
}

resource "aws_launch_template" "main" {
name_prefix = "my-launch-template-"
image_id = data.aws_ssm_parameter.al2023_ami.value
instance_type = "t3.micro"

vpc_security_group_ids = [aws_security_group.main.id]

tag_specifications {
resource_type = "instance"
tags = {
Name = "MyInstance"
}
}

lifecycle {
create_before_destroy = true
}
}

resource "aws_autoscaling_group" "main" {
name = "my-asg"
vpc_zone_identifier = [aws_subnet.main.id]
min_size = 1
max_size = 3
desired_capacity = 2

launch_template {
id = aws_launch_template.main.id
version = "$Latest"
}

instance_refresh {
strategy = "Rolling"
preferences {
min_healthy_percentage = 90
instance_warmup = 300
}
}

tag {
key = "Name"
value = "my-asg-instance"
propagate_at_launch = true
}
}

Standalone EC2 Instance

data "aws_ssm_parameter" "al2023_ami" {
name = "/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64"
}

resource "aws_instance" "main" {
ami = data.aws_ssm_parameter.al2023_ami.value
instance_type = "t3.micro"
subnet_id = aws_subnet.main.id

vpc_security_group_ids = [aws_security_group.main.id]

tags = {
Name = "MyCurrentInstance"
}
}

Apply the configuration:

terraform init
terraform plan
terraform apply

Note: When you update the AMI in Terraform, standalone instances will be replaced (destroyed and recreated). Use lifecycle { create_before_destroy = true } or consider using an Auto Scaling Group with instance refresh for zero-downtime updates.

Verification

After remediation, verify that your instances are using current AMIs:

  1. Open the EC2 Console
  2. Select your instance and note the AMI ID in the Details tab
  3. Navigate to AMIs and search for that AMI ID
  4. Confirm that the Deprecation time field is empty or shows a future date
CLI verification

Check if the AMI is deprecated:

aws ec2 describe-images \
--region us-east-1 \
--image-ids ami-your-new-ami-id \
--include-deprecated \
--query 'Images[*].[ImageId,Name,DeprecationTime]' \
--output table

A DeprecationTime of None or a future date indicates a current AMI.

Re-run the Prowler check to confirm remediation:

prowler aws --check ec2_instance_with_outdated_ami --region us-east-1

Additional Resources

Notes

  • Plan for downtime: Replacing standalone instances typically requires downtime. Use migration strategies like blue-green deployments for production workloads.
  • Test before production: Always test new AMIs in a non-production environment before rolling them out to production.
  • Automate AMI updates: Consider using AWS Systems Manager Automation or EC2 Image Builder to create and deploy updated AMIs automatically.
  • Golden images: For consistent deployments, create your own "golden" AMIs based on current AWS AMIs with your organization's standard configurations pre-applied.
  • Monitor deprecation: Set up monitoring to alert you when AMIs used in your environment are approaching deprecation.