EC2 instance does not have a public IP address
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 Cloudprowler aws --checks ec2_instance_public_ipRecommendation
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 addressOther
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