You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用AWS CDK配置VPC:双公有子网单路由表异常排查

问题排查:CDK创建VPC时自动关联默认路由表的异常情况

尝试创建两个公有子网并关联至同一个路由表,特意将subnetConfiguration设为空数组以避免自动创建子网和路由表,但当前CDK代码仍生成了两个关联默认路由表的公有子网。代码如下:

import * as cdk from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import { Construct } from 'constructs';

export class DevVpcStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Create the VPC
    const vpc = new ec2.Vpc(this, 'DevVPC', {
      cidr: '10.0.0.0/16',
      subnetConfiguration: [], // Do not create any subnets automatically
      enableDnsHostnames: true,
      enableDnsSupport: true,
    });

    // Create public subnets
    const publicSubnet1 = new ec2.CfnSubnet(this, 'PublicSubnet1', {
      vpcId: vpc.vpcId,
      cidrBlock: '10.0.1.0/24',
      availabilityZone: cdk.Stack.of(this).availabilityZones[0],
      mapPublicIpOnLaunch: true,
    });

    const publicSubnet2 = new ec2.CfnSubnet(this, 'PublicSubnet2', {
      vpcId: vpc.vpcId,
      cidrBlock: '10.0.2.0/24',
      availabilityZone: cdk.Stack.of(this).availabilityZones[1],
      mapPublicIpOnLaunch: true,
    });

    // Create a single route table
    const routeTable = new ec2.CfnRouteTable(this, 'PublicRouteTable', {
      vpcId: vpc.vpcId,
    });

    // Associate the subnets with the route table
    new ec2.CfnSubnetRouteTableAssociation(this, 'PublicSubnet1RouteTableAssociation', {
      subnetId: publicSubnet1.ref,
      routeTableId: routeTable.ref,
    });

    new ec2.CfnSubnetRouteTableAssociation(this, 'PublicSubnet2RouteTableAssociation', {
      subnetId: publicSubnet2.ref,
      routeTableId: routeTable.ref,
    });
  }
}

问题原因

  • 所有AWS VPC默认都会生成一个默认路由表,当通过CfnSubnet手动创建子网时,AWS会自动将子网关联到这个默认路由表,而非你手动创建的自定义路由表。你看到的“独立路由表”其实是VPC的默认路由表,并非CDK额外生成。
  • 代码中缺少互联网网关及路由配置,即使子网关联了自定义路由表,也无法正常访问公网。

解决方案

方案1:使用CDK高层抽象(推荐)

改用CDK封装的高层API,简化操作并避免底层资源的默认行为冲突:

import * as cdk from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import { Construct } from 'constructs';

export class DevVpcStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // 创建VPC,禁用自动子网创建
    const vpc = new ec2.Vpc(this, 'DevVPC', {
      cidr: '10.0.0.0/16',
      subnetConfiguration: [],
      enableDnsHostnames: true,
      enableDnsSupport: true,
      natGateways: 0, // 公有子网无需NAT网关
      maxAzs: 2, // 匹配子网使用的可用区数量
    });

    // 创建公有子网
    const publicSubnet1 = new ec2.Subnet(this, 'PublicSubnet1', {
      vpcId: vpc.vpcId,
      cidrBlock: '10.0.1.0/24',
      availabilityZone: this.availabilityZones[0],
      mapPublicIpOnLaunch: true,
    });

    const publicSubnet2 = new ec2.Subnet(this, 'PublicSubnet2', {
      vpcId: vpc.vpcId,
      cidrBlock: '10.0.2.0/24',
      availabilityZone: this.availabilityZones[1],
      mapPublicIpOnLaunch: true,
    });

    // 创建公有路由表并添加互联网路由
    const publicRouteTable = new ec2.RouteTable(this, 'PublicRouteTable', {
      vpc,
    });

    // 添加互联网网关及路由
    const igw = vpc.addInternetGateway('InternetGateway');
    new ec2.Route(this, 'PublicInternetRoute', {
      routeTable: publicRouteTable,
      destinationCidrBlock: '0.0.0.0/0',
      gateway: igw,
    });

    // 关联子网到公有路由表
    publicSubnet1.addRouteTableAssociation('Subnet1RouteTableAssoc', publicRouteTable);
    publicSubnet2.addRouteTableAssociation('Subnet2RouteTableAssoc', publicRouteTable);
  }
}

方案2:保留底层Cfn资源调整

如果坚持使用Cfn资源,需补充互联网网关配置,确保子网正确关联自定义路由表:

import * as cdk from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import { Construct } from 'constructs';

export class DevVpcStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Create the VPC
    const vpc = new ec2.Vpc(this, 'DevVPC', {
      cidr: '10.0.0.0/16',
      subnetConfiguration: [],
      enableDnsHostnames: true,
      enableDnsSupport: true,
    });

    // Create public subnets
    const publicSubnet1 = new ec2.CfnSubnet(this, 'PublicSubnet1', {
      vpcId: vpc.vpcId,
      cidrBlock: '10.0.1.0/24',
      availabilityZone: cdk.Stack.of(this).availabilityZones[0],
      mapPublicIpOnLaunch: true,
    });

    const publicSubnet2 = new ec2.CfnSubnet(this, 'PublicSubnet2', {
      vpcId: vpc.vpcId,
      cidrBlock: '10.0.2.0/24',
      availabilityZone: cdk.Stack.of(this).availabilityZones[1],
      mapPublicIpOnLaunch: true,
    });

    // 创建互联网网关并关联到VPC
    const internetGateway = new ec2.CfnInternetGateway(this, 'InternetGateway');
    new ec2.CfnVPCGatewayAttachment(this, 'VpcIgwAttachment', {
      vpcId: vpc.vpcId,
      internetGatewayId: internetGateway.ref,
    });

    // Create a single route table
    const routeTable = new ec2.CfnRouteTable(this, 'PublicRouteTable', {
      vpcId: vpc.vpcId,
    });

    // 添加互联网路由到自定义路由表
    new ec2.CfnRoute(this, 'PublicInternetRoute', {
      routeTableId: routeTable.ref,
      destinationCidrBlock: '0.0.0.0/0',
      gatewayId: internetGateway.ref,
    });

    // Associate the subnets with the route table
    new ec2.CfnSubnetRouteTableAssociation(this, 'PublicSubnet1RouteTableAssociation', {
      subnetId: publicSubnet1.ref,
      routeTableId: routeTable.ref,
    });

    new ec2.CfnSubnetRouteTableAssociation(this, 'PublicSubnet2RouteTableAssociation', {
      subnetId: publicSubnet2.ref,
      routeTableId: routeTable.ref,
    });
  }
}

注:AWS会自动将新子网关联到默认路由表,但手动创建的CfnSubnetRouteTableAssociation会覆盖这个默认关联,最终子网会绑定到自定义路由表。

内容的提问来源于stack exchange,提问作者jkhan_prog

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 21:35:06