Subnet and networking management in AWS CDK EC2 provides comprehensive control over subnet creation, routing, and network configuration within VPCs.
The CDK provides several subnet classes for different networking scenarios:
abstract class Subnet extends Resource implements ISubnet {
readonly subnetId: string;
readonly availabilityZone: string;
readonly ipv4CidrBlock: string;
readonly routeTable: IRouteTable;
readonly internetConnectivityEstablished: IDependable;
static fromSubnetAttributes(scope: Construct, id: string, attrs: SubnetAttributes): ISubnet;
static fromSubnetId(scope: Construct, id: string, subnetId: string): ISubnet;
associateNetworkAcl(id: string, acl: INetworkAcl): void;
addRoute(id: string, options: AddRouteOptions): void;
}
class PublicSubnet extends Subnet implements IPublicSubnet {
constructor(scope: Construct, id: string, props: PublicSubnetProps);
addDefaultInternetRoute(gatewayId: string, gateway: IDependable): void;
}
class PrivateSubnet extends Subnet implements IPrivateSubnet {
constructor(scope: Construct, id: string, props: PrivateSubnetProps);
addDefaultNatRoute(natGatewayId: string): void;
}Interfaces define the contracts for different subnet types:
interface ISubnet extends IResource {
readonly subnetId: string;
readonly availabilityZone: string;
readonly ipv4CidrBlock: string;
readonly routeTable: IRouteTable;
readonly internetConnectivityEstablished: IDependable;
associateNetworkAcl(id: string, acl: INetworkAcl): void;
}
interface IPublicSubnet extends ISubnet {
// Public subnet-specific methods
}
interface IPrivateSubnet extends ISubnet {
// Private subnet-specific methods
}Configuration interfaces for subnet creation:
interface SubnetProps {
readonly availabilityZone: string;
readonly cidrBlock: string;
readonly vpcId: string;
readonly mapPublicIpOnLaunch?: boolean;
}
interface PublicSubnetProps extends SubnetProps {
// Additional public subnet properties
}
interface PrivateSubnetProps extends SubnetProps {
// Additional private subnet properties
}
interface SubnetAttributes {
readonly subnetId: string;
readonly availabilityZone?: string;
readonly ipv4CidrBlock?: string;
readonly routeTableId?: string;
}Enumeration of available subnet types:
enum SubnetType {
PRIVATE_ISOLATED = 'Isolated',
PRIVATE_WITH_NAT = 'Private',
PUBLIC = 'Public'
}
interface SubnetConfiguration {
readonly cidrMask: number;
readonly name: string;
readonly subnetType: SubnetType;
readonly reserved?: boolean;
readonly mapPublicIpOnLaunch?: boolean;
}Interfaces for selecting subsets of subnets:
interface SubnetSelection {
readonly availabilityZones?: string[];
readonly onePerAz?: boolean;
readonly subnetType?: SubnetType;
readonly subnets?: ISubnet[];
readonly subnetFilters?: SubnetFilter[];
readonly subnetGroupName?: string;
}
interface SelectedSubnets {
readonly subnetIds: string[];
readonly availabilityZones: string[];
readonly routeTableIds: string[];
readonly subnets: ISubnet[];
readonly internetConnectivityEstablished: IDependable;
readonly hasPublic: boolean;
}Classes for advanced subnet filtering:
abstract class SubnetFilter {
static byIds(subnetIds: string[]): SubnetFilter;
static availabilityZones(availabilityZones: string[]): SubnetFilter;
static onePerAz(): SubnetFilter;
static containsIpAddresses(ipv4addrs: string[]): SubnetFilter;
static byCidrMask(mask: number): SubnetFilter;
abstract selectSubnets(subnets: ISubnet[]): ISubnet[];
}Route table management interfaces:
interface IRouteTable {
readonly routeTableId: string;
}
interface AddRouteOptions {
readonly routerType: RouterType;
readonly routerId?: string;
readonly destinationCidrBlock?: string;
readonly destinationIpv6CidrBlock?: string;
readonly enablesInternetConnectivity?: boolean;
}
enum RouterType {
VPC_ENDPOINT = 'VpcEndpoint',
EGRESS_ONLY_INTERNET_GATEWAY = 'EgressOnlyInternetGateway',
INTERNET_GATEWAY = 'InternetGateway',
INSTANCE = 'Instance',
NAT_GATEWAY = 'NatGateway',
NAT_INSTANCE = 'NatInstance',
NETWORK_INTERFACE = 'NetworkInterface',
VPC_PEERING_CONNECTION = 'VpcPeeringConnection',
VPN_GATEWAY = 'VpnGateway',
CARRIER_GATEWAY = 'CarrierGateway'
}import * as ec2 from "@aws-cdk/aws-ec2";
import * as cdk from "@aws-cdk/core";
const vpc = new ec2.Vpc(this, "MyVpc", {
cidr: "10.0.0.0/16"
});
// Create a custom public subnet
const publicSubnet = new ec2.PublicSubnet(this, "CustomPublicSubnet", {
availabilityZone: "us-east-1a",
cidrBlock: "10.0.1.0/24",
vpcId: vpc.vpcId,
mapPublicIpOnLaunch: true
});
// Create a custom private subnet
const privateSubnet = new ec2.PrivateSubnet(this, "CustomPrivateSubnet", {
availabilityZone: "us-east-1a",
cidrBlock: "10.0.2.0/24",
vpcId: vpc.vpcId
});const vpc = new ec2.Vpc(this, "CustomVpc", {
cidr: "10.0.0.0/16",
maxAzs: 3,
subnetConfiguration: [
{
cidrMask: 24,
name: "PublicSubnet",
subnetType: ec2.SubnetType.PUBLIC,
mapPublicIpOnLaunch: true
},
{
cidrMask: 24,
name: "PrivateSubnet",
subnetType: ec2.SubnetType.PRIVATE_WITH_NAT
},
{
cidrMask: 28,
name: "IsolatedSubnet",
subnetType: ec2.SubnetType.PRIVATE_ISOLATED
},
{
cidrMask: 26,
name: "DatabaseSubnet",
subnetType: ec2.SubnetType.PRIVATE_ISOLATED
}
]
});// Select all public subnets
const publicSubnets = vpc.selectSubnets({
subnetType: ec2.SubnetType.PUBLIC
});
// Select one subnet per AZ from private subnets
const distributedPrivate = vpc.selectSubnets({
subnetType: ec2.SubnetType.PRIVATE_WITH_NAT,
onePerAz: true
});
// Select subnets in specific AZs
const specificAzSubnets = vpc.selectSubnets({
availabilityZones: ["us-east-1a", "us-east-1b"],
subnetType: ec2.SubnetType.PRIVATE_WITH_NAT
});
// Select subnets by name
const databaseSubnets = vpc.selectSubnets({
subnetGroupName: "DatabaseSubnet"
});
// Select specific subnets by ID
const specificSubnets = vpc.selectSubnets({
subnetFilters: [
ec2.SubnetFilter.byIds(["subnet-12345", "subnet-67890"])
]
});// Filter by CIDR mask
const smallSubnets = vpc.selectSubnets({
subnetFilters: [
ec2.SubnetFilter.byCidrMask(28)
]
});
// Filter by IP addresses
const subnetsContainingIps = vpc.selectSubnets({
subnetFilters: [
ec2.SubnetFilter.containsIpAddresses(["10.0.1.100", "10.0.2.200"])
]
});
// Combine multiple filters
const filteredSubnets = vpc.selectSubnets({
subnetFilters: [
ec2.SubnetFilter.availabilityZones(["us-east-1a", "us-east-1b"]),
ec2.SubnetFilter.onePerAz()
]
});// Import subnet by ID
const existingSubnet = ec2.Subnet.fromSubnetId(
this,
"ExistingSubnet",
"subnet-12345678"
);
// Import subnet with attributes
const subnetWithAttributes = ec2.Subnet.fromSubnetAttributes(this, "ImportedSubnet", {
subnetId: "subnet-87654321",
availabilityZone: "us-east-1a",
ipv4CidrBlock: "10.0.1.0/24",
routeTableId: "rtb-12345678"
});const privateSubnet = new ec2.PrivateSubnet(this, "PrivateSubnet", {
availabilityZone: "us-east-1a",
cidrBlock: "10.0.1.0/24",
vpcId: vpc.vpcId
});
// Add custom route
privateSubnet.addRoute("CustomRoute", {
routerType: ec2.RouterType.NAT_GATEWAY,
routerId: "nat-12345678",
destinationCidrBlock: "0.0.0.0/0",
enablesInternetConnectivity: true
});
// Add route to VPC endpoint
privateSubnet.addRoute("S3Route", {
routerType: ec2.RouterType.VPC_ENDPOINT,
routerId: "vpce-12345678",
destinationCidrBlock: "0.0.0.0/0"
});const multiAzVpc = new ec2.Vpc(this, "MultiAzVpc", {
cidr: "10.0.0.0/16",
maxAzs: 3,
subnetConfiguration: [
{
cidrMask: 24,
name: "Public",
subnetType: ec2.SubnetType.PUBLIC
},
{
cidrMask: 24,
name: "Private",
subnetType: ec2.SubnetType.PRIVATE_WITH_NAT
}
]
});
// Deploy instances across multiple AZs
multiAzVpc.publicSubnets.forEach((subnet, index) => {
new ec2.Instance(this, `PublicInstance${index}`, {
vpc: multiAzVpc,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO),
machineImage: ec2.MachineImage.latestAmazonLinux(),
vpcSubnets: {
subnets: [subnet]
}
});
});const webSubnets = vpc.selectSubnets({
subnetType: ec2.SubnetType.PUBLIC
});
const appSubnets = vpc.selectSubnets({
subnetGroupName: "Private"
});
const dbSubnets = vpc.selectSubnets({
subnetGroupName: "Database"
});
// Create security groups for each tier
const webSg = new ec2.SecurityGroup(this, "WebSG", {
vpc,
description: "Web tier security group"
});
const appSg = new ec2.SecurityGroup(this, "AppSG", {
vpc,
description: "Application tier security group"
});
const dbSg = new ec2.SecurityGroup(this, "DatabaseSG", {
vpc,
description: "Database tier security group"
});
// Configure tier-to-tier access
webSg.addEgressRule(appSg, ec2.Port.tcp(8080), "Web to App");
appSg.addIngressRule(webSg, ec2.Port.tcp(8080), "Web to App");
appSg.addEgressRule(dbSg, ec2.Port.tcp(3306), "App to DB");
dbSg.addIngressRule(appSg, ec2.Port.tcp(3306), "App to DB");import * as elbv2 from "@aws-cdk/aws-elasticloadbalancingv2";
const vpc = new ec2.Vpc(this, "LoadBalancerVpc", {
subnetConfiguration: [
{
cidrMask: 24,
name: "PublicSubnet",
subnetType: ec2.SubnetType.PUBLIC
},
{
cidrMask: 24,
name: "PrivateSubnet",
subnetType: ec2.SubnetType.PRIVATE_WITH_NAT
}
]
});
// Application Load Balancer in public subnets
const alb = new elbv2.ApplicationLoadBalancer(this, "ALB", {
vpc,
internetFacing: true,
vpcSubnets: {
subnetType: ec2.SubnetType.PUBLIC
}
});
// EC2 instances in private subnets
const targetGroup = new elbv2.ApplicationTargetGroup(this, "TargetGroup", {
vpc,
port: 80,
targets: [
// EC2 instances would be added here
]
});const vpc = new ec2.Vpc(this, "CrossAzVpc");
// Get subnets in different AZs
const az1Subnets = vpc.selectSubnets({
availabilityZones: [vpc.availabilityZones[0]]
});
const az2Subnets = vpc.selectSubnets({
availabilityZones: [vpc.availabilityZones[1]]
});
// Instance in AZ1
const instanceAz1 = new ec2.Instance(this, "InstanceAZ1", {
vpc,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO),
machineImage: ec2.MachineImage.latestAmazonLinux(),
vpcSubnets: {
subnets: az1Subnets.subnets
}
});
// Instance in AZ2
const instanceAz2 = new ec2.Instance(this, "InstanceAZ2", {
vpc,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO),
machineImage: ec2.MachineImage.latestAmazonLinux(),
vpcSubnets: {
subnets: az2Subnets.subnets
}
});
// Allow communication between AZs
instanceAz1.connections.allowTo(instanceAz2, ec2.Port.tcp(8080));const organizedVpc = new ec2.Vpc(this, "OrganizedVpc", {
subnetConfiguration: [
{
cidrMask: 24,
name: "WebTier",
subnetType: ec2.SubnetType.PUBLIC
},
{
cidrMask: 24,
name: "AppTier",
subnetType: ec2.SubnetType.PRIVATE_WITH_NAT
},
{
cidrMask: 28,
name: "DataTier",
subnetType: ec2.SubnetType.PRIVATE_ISOLATED
}
]
});
// Add tags to subnet groups
cdk.Tags.of(organizedVpc.selectSubnets({ subnetGroupName: "WebTier" }))
.add("Tier", "Web")
.add("Environment", "Production");
cdk.Tags.of(organizedVpc.selectSubnets({ subnetGroupName: "AppTier" }))
.add("Tier", "Application")
.add("Environment", "Production");
cdk.Tags.of(organizedVpc.selectSubnets({ subnetGroupName: "DataTier" }))
.add("Tier", "Database")
.add("Environment", "Production");