or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

cloudformation-init.mdec2-instances.mdflow-logs.mdindex.mdlaunch-templates.mdmachine-images.mdnetwork-acl.mdsecurity-groups.mdstorage-volumes.mdsubnets-networking.mduser-data.mdvpc-endpoints.mdvpc-management.mdvpn-connectivity.md
tile.json

subnets-networking.mddocs/

Subnets & Networking

Subnet and networking management in AWS CDK EC2 provides comprehensive control over subnet creation, routing, and network configuration within VPCs.

Subnet Classes

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;
}

Subnet Interfaces

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
}

Subnet Configuration

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;
}

Subnet Types

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;
}

Subnet Selection

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;
}

Subnet Filtering

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 Tables

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'
}

Usage Examples

Basic Subnet Creation

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
});

Custom Subnet Configuration in VPC

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
    }
  ]
});

Subnet Selection Patterns

// 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"])
  ]
});

Advanced Subnet Filtering

// 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()
  ]
});

Importing Existing Subnets

// 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"
});

Route Management

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"
});

Multi-AZ Subnet Deployment

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]
    }
  });
});

Subnet-Specific Security

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");

Subnet Networking with Load Balancers

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
  ]
});

Cross-AZ Connectivity

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));

Subnet Tagging and Organization

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");

Best Practices

  1. Subnet Planning: Plan CIDR blocks carefully to avoid overlap and allow for growth
  2. Multi-AZ Deployment: Always deploy across multiple Availability Zones for high availability
  3. Tiered Architecture: Use different subnet types for different application tiers
  4. Security Isolation: Use private and isolated subnets to protect sensitive resources
  5. Route Table Management: Keep route tables simple and well-documented
  6. Subnet Sizing: Size subnets appropriately based on expected resource needs
  7. Naming Conventions: Use consistent naming conventions for subnets and subnet groups
  8. Network ACLs: Consider Network ACLs for additional subnet-level security
  9. Monitoring: Monitor subnet utilization and network traffic
  10. Documentation: Document subnet allocation and usage patterns