CDK が VPC の情報を context に書き込むとき、SubnetType はどう決定されるのか

v2.1029.0
を参照する

Context に書き込むための情報を引いている実処理は以下。
VpcNetworkContextProviderPlugin.readVpcProps()

コメントをコード読めば分かる話ではあるが、AI に説明させてみた。以下は回答
⏺ VPCに関してContextに書き込まれる情報
VpcNetworkContextProviderPlugin が返す情報(packages/@aws-cdk/toolkit-lib/lib/context-providers/vpcs.ts:151-185):
基本的なVPC情報
- vpcId: VPC ID
- vpcCidrBlock: VPCのCIDRブロック
- ownerAccountId: VPCオーナーのAWSアカウントID
- availabilityZones: 利用可能なアベイラビリティゾーンのリスト
サブネット情報(タイプ別)
各サブネットタイプ(Isolated/Private/Public)について以下を記録:
Isolated サブネット
- isolatedSubnetIds: サブネットIDのリスト
- isolatedSubnetNames: サブネット名のリスト
- isolatedSubnetRouteTableIds: ルートテーブルIDのリスト
Private サブネット
- privateSubnetIds: サブネットIDのリスト
- privateSubnetNames: サブネット名のリスト
- privateSubnetRouteTableIds: ルートテーブルIDのリスト
Public サブネット
- publicSubnetIds: サブネットIDのリスト
- publicSubnetNames: サブネット名のリスト
- publicSubnetRouteTableIds: ルートテーブルIDのリスト
オプション情報
- vpnGatewayId: VPNゲートウェイID(存在する場合)
- subnetGroups: 非対称サブネット構成の場合の詳細情報
- 各グループには名前、タイプ、サブネット詳細(ID、CIDR、AZ、ルートテーブルID)を含む
**サブネットタイプの判定ロジック
**
サブネットは以下の順序で判定される(packages/@aws-cdk/toolkit-lib/lib/context-providers/vpcs.ts:69-84):
- aws-cdk:subnet-type タグの値
- MapPublicIpOnLaunch が true → Public
- Internet Gateway へのルートがある → Public
- NAT Gateway へのルートがある → Private
- Transit Gateway へのルートがある → Private
- それ以外 → Isolated
⏺ readVpcProps メソッド内でサブネットの SubnetType を決定するロジックを詳しく説明します。
サブネットタイプ判定ロジック(vpcs.ts:68-84)
サブネットは以下の優先順位で判定されます:
- タグによる明示的な指定(vpcs.ts:69)
let type = getTag('aws-cdk:subnet-type', subnet.Tags);
aws-cdk:subnet-type タグが設定されていれば、その値を使用
- MapPublicIpOnLaunch プロパティ(vpcs.ts:70-72)
if (type === undefined && subnet.MapPublicIpOnLaunch) {
type = SubnetType.Public;
}
パブリックIPの自動割り当てが有効 → Public
- Internet Gateway へのルート(vpcs.ts:73-75)
if (type === undefined && routeTables.hasRouteToIgw(subnet.SubnetId)) {
type = SubnetType.Public;
}
IGWへのルートが存在 → Public
- NAT Gateway へのルート(vpcs.ts:76-78)
if (type === undefined && routeTables.hasRouteToNatGateway(subnet.SubnetId)) {
type = SubnetType.Private;
}
NAT Gatewayへのルート(0.0.0.0/0宛)が存在 → Private
- Transit Gateway へのルート(vpcs.ts:79-81)
if (type === undefined && routeTables.hasRouteToTransitGateway(subnet.SubnetId)) {
type = SubnetType.Private;
}
Transit Gatewayへのルート(0.0.0.0/0宛)が存在 → Private
- デフォルト(vpcs.ts:82-84)
if (type === undefined) {
type = SubnetType.Isolated;
}
上記のいずれにも該当しない → Isolated
ルートテーブルのチェックロジック
IGW判定(vpcs.ts:232-238)
public hasRouteToIgw(subnetId: string | undefined): boolean {
const table = this.tableForSubnet(subnetId) || this.mainRouteTable;
return !!table && !!table.Routes &&
table.Routes.some((route) => !!route.GatewayId && route.GatewayId.startsWith('igw-'));
}
- Gateway IDが igw- で始まるルートの存在を確認
NAT Gateway判定(vpcs.ts:206-214)
public hasRouteToNatGateway(subnetId: string | undefined): boolean {
const table = this.tableForSubnet(subnetId) || this.mainRouteTable;
return !!table && !!table.Routes &&
table.Routes.some((route) => !!route.NatGatewayId && route.DestinationCidrBlock === '0.0.0.0/0');
}
- NAT Gateway IDが存在し、かつ宛先が 0.0.0.0/0 のルートを確認
Transit Gateway判定(vpcs.ts:219-227)
public hasRouteToTransitGateway(subnetId: string | undefined): boolean {
const table = this.tableForSubnet(subnetId) || this.mainRouteTable;
return !!table && !!table.Routes &&
table.Routes.some((route) => !!route.TransitGatewayId && route.DestinationCidrBlock === '0.0.0.0/0');
}
- Transit Gateway IDが存在し、かつ宛先が 0.0.0.0/0 のルートを確認
SubnetType の定義(vpcs.ts:330-334)
enum SubnetType {
Public = 'Public',
Private = 'Private',
Isolated = 'Isolated',
}
判定の特徴
- タグ優先: CDKが付けたタグがあればそれを最優先
- 段階的判定: Public → Private → Isolated の順で判定
- ルートベース: 実際のルーティング設定を参照して判断
- フォールバック: サブネット固有のルートテーブルがなければメインルートテーブルを参照
この判定ロジックにより、VPC内の各サブネットが適切なタイプに分類され、CDKアプリケーションで正しく利用できるようになります。

結論となる回答が出たので、上記から抜粋。
サブネットは以下の順序で判定される(packages/@aws-cdk/toolkit-lib/lib/context-providers/vpcs.ts:69-84):
- aws-cdk:subnet-type タグの値
- MapPublicIpOnLaunch が true → Public
- Internet Gateway へのルートがある → Public
- NAT Gateway へのルートがある → Private
- Transit Gateway へのルートがある → Private
- それ以外 → Isolated
ContextProviderPlugin の拡張である、VpcNetworkContextProviderPlugin
内部の readVpcProps
で上記の判定が行われる。このメソッドは、実際には Provier 共通のインタフェースである getValue
を介して呼び出される。
MapPublicIpOnLaunch
はサブネットの属性で、公式ドキュメントにも言及がある。これは、このサブネットで起動した何か(インスタンス)に対して、パブリックIP の割当を行うかどうかのフラグ。
外に出る必要がないサブネットでこの設定を ON にする意味はないので、実際のルーティング等より優先してこの属性がチェックされているものと思われる。