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
| Type | Purpose in a typical CDK-created VPC | What selection does not provide |
|---|---|---|
| PUBLIC | Subnet with an internet-gateway route | A public IP or inbound security-group permission |
| PRIVATE_WITH_EGRESS | Private workload with outbound connectivity, often through NAT | A guarantee that your existing network actually has a working egress path |
| PRIVATE_ISOLATED | Workload with no internet route in this example | Automatic 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.
Comments
Share your thoughts and questions below