Back to Checks
aws

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 Cloud
Run
prowler aws --checks ec2_instance_with_outdated_ami

Recommendation

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 DeprecationTime

Other

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