Back to Checks
aws

EC2 instance does not have a public IP address

ec2_instance_public_ip
Service: ec2Severity: medium
OfficialBuilt-inVerified
Categories:internet-exposed
Resource Type:AwsEc2Instance

EC2 instances are assessed for the presence of a public IPv4 address and public DNS. A public IP indicates the instance is directly reachable from the Internet; no public IP implies access only through private networking paths such as load balancers, gateways, or proxies.

Risk

Publicly addressed instances are Internet-scannable, enabling direct probing and brute-force of exposed services and management ports. This increases risks of unauthorized access, remote code execution, and data exfiltration (confidentiality, integrity), and allows direct DDoS targeting, degrading availability.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks ec2_instance_public_ip

Recommendation

Avoid assigning public IPs unless strictly required. Place workloads in private subnets and expose only via load balancers with WAF; use bastions or Session Manager for administration. Enforce least privilege security groups, prefer private endpoints, and route egress via NAT for defense in depth.

Remediation

Terraform

# Terraform: Launch EC2 without a public IP
resource "aws_instance" "example" {
  ami           = "<ami_id>"
  instance_type = "<instance_type>"
  subnet_id     = "<example_subnet_id>"

  associate_public_ip_address = false  # CRITICAL: ensures no public IPv4 is assigned
}

NativeIaC

# CloudFormation: Launch EC2 without a public IP
Resources:
  ExampleInstance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: <ami_id>
      InstanceType: <instance_type>
      NetworkInterfaces:
        - DeviceIndex: 0
          SubnetId: <example_subnet_id>
          AssociatePublicIpAddress: false  # CRITICAL: ensures the instance has no public IPv4 address

Other

1In the AWS Console, go to EC2 > Instances and select the instance with a public IPv4 address
2Check the Networking tab to see if an Elastic IP is attached
3If an Elastic IP is attached:
4- Go to EC2 > Elastic IPs, select the address, choose Actions > Disassociate Elastic IP
5If the public IPv4 is auto-assigned (no Elastic IP shown):
6- Create a new instance (or an AMI from the current one) and, during launch, in Network settings, set Auto-assign public IP to Disable
7- Verify the new instance has no public IPv4, then migrate and terminate the old instance

Check Code

from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.ec2.ec2_client import ec2_client


class ec2_instance_public_ip(Check):
    def execute(self):
        findings = []
        for instance in ec2_client.instances:
            if instance.state != "terminated":
                report = Check_Report_AWS(metadata=self.metadata(), resource=instance)
                report.status = "PASS"
                report.status_extended = (
                    f"EC2 Instance {instance.id} does not have a Public IP."
                )
                if instance.public_ip:
                    report.status = "FAIL"
                    report.status_extended = f"EC2 Instance {instance.id} has a Public IP: {instance.public_ip} ({instance.public_dns})."

                findings.append(report)

        return findings