MIKAEELS

Explore the blog

AWS CDK Subnet Selection: Public, Private, and Isolated

Use vpcSubnets on a CDK construct to choose its subnet placement. Call vpc.selectSubnets() when you also need the selected subnet objects or IDs. In CDK v2, distinguish PRIVATE_WITH_EGRESS from PRIVATE_ISOLATED instead of using the old PRIVATE name.

Choose the right subnet type

TypePurpose in a typical CDK-created VPCWhat selection does not provide
PUBLICSubnet with an internet-gateway routeA public IP or inbound security-group permission
PRIVATE_WITH_EGRESSPrivate workload with outbound connectivity, often through NATA guarantee that your existing network actually has a working egress path
PRIVATE_ISOLATEDWorkload with no internet route in this exampleAutomatic access to AWS service endpoints

Routing and security groups still determine connectivity. An EC2 instance needs a public address for direct IPv4 internet access through an internet gateway. A Lambda function does not gain one merely by selecting public subnets.

Complete EC2 placement example

In a CDK v2 TypeScript app, instantiate this SubnetSelectionStack:

import { CfnOutput, Stack, StackProps } from "aws-cdk-lib"; import * as ec2 from "aws-cdk-lib/aws-ec2"; import { Construct } from "constructs"; export class SubnetSelectionStack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); const vpc = new ec2.Vpc(this, "Network", { maxAzs: 2, natGateways: 0, subnetConfiguration: [ { name: "public", subnetType: ec2.SubnetType.PUBLIC, cidrMask: 24 }, { name: "data", subnetType: ec2.SubnetType.PRIVATE_ISOLATED, cidrMask: 24 }, ], }); const selected = vpc.selectSubnets({ subnetGroupName: "data" }); new ec2.Instance(this, "PrivateClient", { vpc, vpcSubnets: { subnets: selected.subnets }, instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE3, ec2.InstanceSize.MICRO), machineImage: ec2.MachineImage.latestAmazonLinux2023(), }); new CfnOutput(this, "SelectedSubnetIds", { value: selected.subnetIds.join(","), }); } }

This instance has no internet route, SSH ingress rule, or configured management endpoints. It illustrates placement, not a remotely accessible machine. The selected group may contain multiple subnets; one EC2 instance occupies one of them, not all of them.

The example targets CDK 2.272.0 and constructs 10.5.0. Type-check and synthesize before deployment, then inspect the EC2 resource's SubnetId. No AWS deployment was performed for this revision. EC2 incurs charges if you deploy it.

Other selection patterns

Inside the same stack, alternatives include:

const isolated = vpc.selectSubnets({ subnetType: ec2.SubnetType.PRIVATE_ISOLATED, onePerAz: true, }); const firstSubnet = isolated.subnets[0]; if (!firstSubnet) throw new Error("No matching isolated subnet"); const specific = { subnets: [firstSubnet] };

Pass specific as a construct's vpcSubnets when you deliberately need that single subnet. Use availabilityZones or subnetFilters for further constraints. Check the SubnetSelection API rather than assuming every resource accepts a singular subnet property.

Existing VPCs and troubleshooting

If there are no matching subnets, inspect the actual network and filter. A selector does not create a missing group. With an imported VPC, check the lookup context and refresh stale data deliberately. Do not hardcode an array index without checking that the selection exists.

For an application that needs outbound internet access, see Lambda in a VPC with internet access. For a private database reached from EC2, follow the RDS example. To label subnet groups, see subnet tagging.

Review npx aws-cdk diff before deployment and npx aws-cdk destroy only for a disposable exercise stack. Existing workloads can prevent network deletion.

Quick Recap

How do you select private subnets in CDK v2?

Use subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS for private subnets intended to have outbound routing, or PRIVATE_ISOLATED for subnets without an internet route in the example network.

What does selectSubnets return?

It returns SelectedSubnets, including subnets and subnetIds. It does not return a subnet array directly.

How do you place an EC2 instance in selected subnets?

Pass a SubnetSelection to the Instance construct's vpcSubnets property. Do not use a nonexistent subnet property.

Add Mikaeels Blog as a preferred source on Google

Comments

Share your thoughts and questions below