Back to Checks
EC2 instance uses a non-deprecated Amazon AMI
ec2_instance_with_outdated_ami
Service: ec2Severity: medium
OfficialBuilt-inVerified
Categories:vulnerabilities
Resource Type:AwsEc2Instance
EC2 instances launched from Amazon-owned AMIs are evaluated for the AMI's DeprecationTime; instances tied to images with a deprecation date in the past are reported as using deprecated AMIs.
Risk
Running on a deprecated AMI undermines security and availability:
- Missing patches enable exploitation of known CVEs (confidentiality/integrity)
- Unsupported components hinder hardening and forensics
- AMI removal from catalogs complicates scale-out and recovery (availability)
Run this check with Prowler
Run in Prowler CloudRun
prowler aws --checks ec2_instance_with_outdated_amiRecommendation
Adopt non-deprecated, maintained AMIs and perform rolling replacements of affected instances. Standardize on hardened golden images with regular AMI rotation and DeprecationTime monitoring. Update launch templates/ASGs to reference current images. Automate patching via an image pipeline and apply defense in depth.
Remediation
Terraform
# EC2 instance using a non-deprecated Amazon AMI
resource "aws_instance" "<example_resource_name>" {
ami = "<non_deprecated_amazon_ami_id>" # Critical: Amazon-owned AMI with no DeprecationTime
instance_type = "t3.micro"
}NativeIaC
# Use a non-deprecated Amazon AMI for instances launched via this template
Resources:
<example_resource_name>:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateData:
ImageId: "<non_deprecated_amazon_ami_id>" # Critical: Amazon-owned AMI with no DeprecationTimeOther
1In the EC2 console, go to AMIs
2Set Owner to "Amazon" and ensure deprecated AMIs are not included; copy the AMI ID
3If using an Auto Scaling Group:
4- Launch templates > select the one in use > Create new version with Image ID set to the copied AMI and set it as default
5- Auto Scaling Groups > select the group > Start instance refresh
6If it is a standalone instance:
7- Launch a new instance using the copied Amazon AMI
8- Move workloads and terminate the old instance
Check Code
from datetime import datetime, timezone
from typing import List
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.ec2.ec2_client import ec2_client
class ec2_instance_with_outdated_ami(Check):
"""Check if EC2 instances are using outdated AMIs.
This check verifies whether EC2 instances are running on outdated AMIs that have
reached their deprecation date. If an instance is using an AMI that is deprecated,
the check fails.
Attributes:
metadata: Metadata associated with the check (inherited from Check).
"""
def execute(self) -> List[Check_Report_AWS]:
"""Execute the outdated AMI check for EC2 instances.
Iterates over all EC2 instances and checks if their AMIs have been deprecated.
If an instance is using an outdated AMI, the check fails.
Returns:
List[Check_Report_AWS]: A list containing the results of the check for each instance.
"""
findings = []
images_by_id = getattr(ec2_client, "images_by_id", None)
if images_by_id is None:
images_by_id = {image.id: image for image in ec2_client.images}
for instance in ec2_client.instances:
ami = images_by_id.get(instance.image_id)
if ami and ami.owner == "amazon":
report = Check_Report_AWS(metadata=self.metadata(), resource=instance)
report.status = "PASS"
report.status_extended = (
f"EC2 Instance {instance.id} is not using an outdated AMI."
)
if ami.deprecation_time:
deprecation_datetime = datetime.strptime(
ami.deprecation_time, "%Y-%m-%dT%H:%M:%S.%fZ"
).replace(tzinfo=timezone.utc)
if deprecation_datetime < datetime.now(timezone.utc):
report.status = "FAIL"
report.status_extended = f"EC2 Instance {instance.id} is using outdated AMI {ami.id}."
findings.append(report)
return findings