Back to Checks
aws

EMR Cluster without Public IP.

emr_cluster_master_nodes_no_public_ip
Service: emrSeverity: medium
OfficialBuilt-inVerified
Categories:internet-exposed
Resource Type:Other

Amazon EMR clusters in non-terminated states are assessed for public IP assignment on cluster nodes (primary and workers). The finding identifies clusters whose instances are reachable via public IPs rather than private VPC addresses.

Risk

Publicly reachable EMR nodes expose admin UIs and SSH to the Internet, enabling brute force and service exploits. A compromised primary node can alter jobs and exfiltrate data from S3/HDFS, degrading confidentiality and integrity, and disrupt workloads, impacting availability.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks emr_cluster_master_nodes_no_public_ip

Recommendation

Run EMR in private subnets without public IPs. Use VPC endpoints for AWS services and NAT only when needed. Enforce least privilege security groups, avoid 0.0.0.0/0, and prefer SSM or a bastion for admin access. Keep EMR block public access enabled and favor private connectivity for external dependencies.

Remediation

Terraform

# Terraform: Launch EMR in a private subnet (no public IPs)
resource "aws_emr_cluster" "<example_resource_name>" {
  name                = "<example_resource_name>"
  release_label       = "emr-6.10.0"
  master_instance_type = "m5.xlarge"
  core_instance_type   = "m5.xlarge"

  service_role = "EMR_DefaultRole"
  ec2_attributes {
    instance_profile = "EMR_EC2_DefaultRole"
    subnet_id        = "<example_resource_id>"  # CRITICAL: private subnet ensures no public IPs
  }
}

NativeIaC

# CloudFormation: Launch EMR in a private subnet (no public IPs)
Resources:
  <example_resource_name>:
    Type: AWS::EMR::Cluster
    Properties:
      Name: <example_resource_name>
      ReleaseLabel: emr-6.10.0
      ServiceRole: EMR_DefaultRole
      JobFlowRole: EMR_EC2_DefaultRole
      Instances:
        Ec2SubnetId: <example_resource_id>  # CRITICAL: use a PRIVATE subnet to prevent public IPs
        InstanceGroups:
          - InstanceRole: MASTER
            InstanceType: m5.xlarge
            InstanceCount: 1
          - InstanceRole: CORE
            InstanceType: m5.xlarge
            InstanceCount: 1

Other

1In the AWS Console, go to EMR > Clusters, select the non-compliant cluster (with Public IP) and choose Terminate.
2Click Create cluster.
3Under Networking, select your VPC and choose a private Subnet (no auto-assign public IPv4).
4Create the cluster. Its instances will launch without public IPs.

Check Code

from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.emr.emr_client import emr_client
from prowler.providers.aws.services.emr.emr_service import ClusterStatus


class emr_cluster_master_nodes_no_public_ip(Check):
    def execute(self):
        findings = []
        for cluster in emr_client.clusters.values():
            if cluster.status not in (
                ClusterStatus.TERMINATED,
                ClusterStatus.TERMINATED_WITH_ERRORS,
            ):
                report = Check_Report_AWS(metadata=self.metadata(), resource=cluster)
                if cluster.public:
                    report.status = "FAIL"
                    report.status_extended = (
                        f"EMR Cluster {cluster.id} has a Public IP."
                    )
                else:
                    report.status = "PASS"
                    report.status_extended = (
                        f"EMR Cluster {cluster.id} does not have a Public IP."
                    )

                findings.append(report)

        return findings