Skip to main content
MEDIUMEC2Security

EC2 Subnet Auto-Assigns Public IPs

ec2-subnet-auto-public-ip

What this rule checks

Detects AWS::EC2::Subnet resources with MapPublicIpOnLaunch=true. Instances launched into the subnet inherit a public IP by default, which makes them internet-reachable without an explicit opt-in at the ENI level.

How to fix it

  1. 1Set MapPublicIpOnLaunch to false unless this is intentionally a public subnet
  2. 2Have instances opt into a public IP via the ENI configuration when needed
  3. 3Use VPC endpoints / NAT for outbound access from private subnets
FlaggedMapPublicIpOnLaunch=true makes any instance launched into this subnet internet-reachable by default, with no explicit opt-in at the ENI level. The check flags subnets that set this flag to true.
import { App, Stack } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';

const vpc = new ec2.CfnVPC(this, 'Vpc', { cidrBlock: '10.0.0.0/16' });

// FLAGGED: every instance launched here inherits a public IP.
new ec2.CfnSubnet(this, 'Subnet', {
  vpcId: vpc.ref,
  cidrBlock: '10.0.1.0/24',
  mapPublicIpOnLaunch: true,
});
FixedSetting MapPublicIpOnLaunch=false (the AWS default) clears the finding. Instances that genuinely need a public IP should opt in explicitly at the ENI level rather than inheriting one from the subnet.
import { App, Stack } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';

const vpc = new ec2.CfnVPC(this, 'Vpc', { cidrBlock: '10.0.0.0/16' });

// FIXED: subnet keeps the safe default (no auto-assigned public IPs).
new ec2.CfnSubnet(this, 'Subnet', {
  vpcId: vpc.ref,
  cidrBlock: '10.0.1.0/24',
  mapPublicIpOnLaunch: false,
});

CDK Insights pinpoints the exact file and line in your CDK source for every finding, so you can jump straight to the fix.

Affected resource types

AWS::EC2::Subnet

Compliance frameworks

SOC2HIPAAPCI-DSSNIST

AWS documentation

Read the AWS guidance

Intentional? Suppress this finding

Sometimes a flag is deliberate — a genuinely public endpoint, say. You can dismiss ec2-subnet-auto-public-ip and the reason is kept in the report, not silently hidden.

In .cdk-insights.json:

{
  "ignoreRules": [
    { "id": "ec2-subnet-auto-public-ip", "reason": "Why this is intentional" }
  ]
}

Or inline in your CDK code:

Validations.of(scope).acknowledge({
  id: 'cdk-insights::ec2-subnet-auto-public-ip',
  reason: 'Why this is intentional',
});

Use the rule ID ec2-subnet-auto-public-ip shown above — not the CDK-* ID from SARIF / GitHub code scanning. To dismiss every finding on one construct instead, use ignorePaths. Suppression docs →

Catch this in your stack

$ npx cdk-insights scan

CDK Insights runs this and 118+ other rules locally against your synthesised CDK app — free, no account, your code never leaves your machine.

More EC2 rules