For AI agents: A markdown version of this page is available at https://docs.datadoghq.com/security/code_security/iac_security/iac_rules/terraform-aws-emr-without-vpc.md. A documentation index is available at /llms.txt.
This product is not supported for your selected Datadog site. ().

Metadata

Id: terraform-aws-emr-without-vpc

Provider: AWS

Platform: Terraform

Severity: Low

Category: Networking and Firewall

Learn More

Description

This check ensures that Amazon Elastic MapReduce (EMR) clusters are deployed within a Virtual Private Cloud (VPC) by specifying a subnet_id in the Terraform resource. Launching EMR clusters without associating them to a VPC, as shown by omitting the subnet_id attribute in the aws_emr_cluster resource, exposes the cluster to public networks and increases the risk of unauthorized access or data compromise. By deploying EMR clusters in a VPC, network access control can be properly enforced through security groups and network ACLs, limiting exposure to only trusted sources. Failure to launch EMR clusters inside a VPC can lead to serious security vulnerabilities, including unauthorized data access, data exfiltration, or service disruption.

Compliant Code Examples

# This configuration's subnet_id is a cross-resource reference to a
# not-yet-created subnet (aws_subnet.main). On the HCL path the parser
# keeps the unresolved "${aws_subnet.main.id}" as a literal string, so
# common_lib.valid_key finds the key present. On the plan-JSON path
# (negative2.json, a genuine create plan for this exact configuration) the
# value itself is unresolved and absent from planned_values, but the rule
# now also checks _dd_tfplan_meta.configuration_expressions to confirm
# subnet_id is configured-but-unresolved rather than missing.
resource "aws_emr_cluster" "negative1" {
  name          = "emr-test-arn"
  release_label = "emr-4.6.0"
  subnet_id = aws_subnet.main.id
}

Non-Compliant Code Examples

resource "aws_emr_cluster" "positive1" {
  name          = "emr-test-arn"
  release_label = "emr-4.6.0"
}
# Guard-rail case: ec2_attributes is populated (instance_profile is set),
# but subnet_id/subnet_ids is genuinely never configured -- not a
# cross-resource reference left unresolved. Must still be flagged: the
# rule's configuration_expressions check only suppresses the finding when
# subnet_id/subnet_ids is actually present as a key the user wrote.
resource "aws_iam_role" "emr_service_role" {
  name = "emr-service-role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Action    = "sts:AssumeRole"
      Effect    = "Allow"
      Principal = { Service = "elasticmapreduce.amazonaws.com" }
    }]
  })
}

resource "aws_emr_cluster" "positive2" {
  name          = "emr-test-no-subnet"
  release_label = "emr-4.6.0"
  service_role  = aws_iam_role.emr_service_role.arn
  ec2_attributes {
    instance_profile = "test-profile"
  }
}