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
- Open the EC2 Console
- Select the instance using the outdated AMI
- Note the instance's current configuration (instance type, security groups, IAM role, key pair, etc.)
- In the left navigation, click AMIs under Images
- Filter by Owner: Amazon to find official AWS AMIs
- Search for a current, non-deprecated AMI that matches your requirements (e.g., Amazon Linux 2023, Ubuntu 24.04)
- Select the AMI and click Launch instance from AMI
- Configure the new instance to match your original instance settings
- Launch the instance and verify your application works correctly
- Migrate any data or workloads from the old instance to the new one
- 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
- Open the EC2 Console
- In the left navigation, click AMIs under Images
- Filter by Owner: Amazon and find a current, non-deprecated AMI
- Note the AMI ID (e.g.,
ami-0abcdef1234567890) - Navigate to Launch Templates in the left navigation
- Select the launch template used by your Auto Scaling Group
- Click Actions > Modify template (Create new version)
- Under Application and OS Images, enter the new AMI ID
- Click Create template version
- Set the new version as the default: Actions > Set default version
- Navigate to Auto Scaling Groups (under Auto Scaling in the left navigation)
- Select your Auto Scaling Group
- Click the Instance refresh tab
- Click Start instance refresh
- 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:
- Open the EC2 Console
- Select your instance and note the AMI ID in the Details tab
- Navigate to AMIs and search for that AMI ID
- 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
- AWS Documentation: Deprecate an AMI
- AWS Documentation: Find a Linux AMI
- AWS Documentation: Instance refresh for Auto Scaling
- AWS SSM Parameter Store AMI paths
- Prowler Check Documentation
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.