Skip to content

Commit 49643d6

Browse files
authored
fix(vpc): detect subnet with TGW route as PRIVATE_WITH_EGRESS (#25958)
When I do Vpc.fromLookup in a VPC that has subnets with a default route to a TransitGateway the subnet is detected as `PRIVATE_ISOLATED` instead of `PRIVATE_WITH_EGRESS` This PR adds the detection of subnets with TGW routes as `PRIVATE_WITH_EGRESS` instead of `PRIVATE_ISOLATED`. This is potentially a breaking change depending on what is the expected behaviour. To me it seemed rather missed accidentally given that this [previous PR](#21699) mentions that `PRIVATE_WITH_EGRESS` was introduced also for Transit Gateways. Closes #25626 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent b705956 commit 49643d6

File tree

2 files changed

+75
-1
lines changed

2 files changed

+75
-1
lines changed

packages/aws-cdk/lib/context-providers/vpcs.ts

+10
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ export class VpcNetworkContextProviderPlugin implements ContextProviderPlugin {
7474
if (type === undefined && subnet.MapPublicIpOnLaunch) { type = SubnetType.Public; }
7575
if (type === undefined && routeTables.hasRouteToIgw(subnet.SubnetId)) { type = SubnetType.Public; }
7676
if (type === undefined && routeTables.hasRouteToNatGateway(subnet.SubnetId)) { type = SubnetType.Private; }
77+
if (type === undefined && routeTables.hasRouteToTransitGateway(subnet.SubnetId)) { type = SubnetType.Private; }
7778
if (type === undefined) { type = SubnetType.Isolated; }
7879

7980
if (!isValidSubnetType(type)) {
@@ -176,6 +177,15 @@ class RouteTables {
176177
return !!table && !!table.Routes && table.Routes.some(route => !!route.NatGatewayId && route.DestinationCidrBlock === '0.0.0.0/0');
177178
}
178179

180+
/**
181+
* Whether the given subnet has a route to a Transit Gateway
182+
*/
183+
public hasRouteToTransitGateway(subnetId: string | undefined): boolean {
184+
const table = this.tableForSubnet(subnetId) || this.mainRouteTable;
185+
186+
return !!table && !!table.Routes && table.Routes.some(route => !!route.TransitGatewayId && route.DestinationCidrBlock === '0.0.0.0/0');
187+
}
188+
179189
/**
180190
* Whether the given subnet has a route to an IGW
181191
*/

packages/aws-cdk/test/context-providers/vpcs.test.ts

+65-1
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ test('Recognize public subnet by route table', async () => {
411411
});
412412
});
413413

414-
test('Recognize private subnet by route table', async () => {
414+
test('Recognize private subnet by route table with NAT Gateway', async () => {
415415
// GIVEN
416416
const filter = { foo: 'bar' };
417417
const provider = new VpcNetworkContextProviderPlugin(mockSDK);
@@ -475,6 +475,70 @@ test('Recognize private subnet by route table', async () => {
475475
});
476476
});
477477

478+
test('Recognize private subnet by route table with Transit Gateway', async () => {
479+
// GIVEN
480+
const filter = { foo: 'bar' };
481+
const provider = new VpcNetworkContextProviderPlugin(mockSDK);
482+
483+
mockVpcLookup({
484+
subnets: [
485+
{ SubnetId: 'sub-123456', AvailabilityZone: 'bermuda-triangle-1337', MapPublicIpOnLaunch: false },
486+
],
487+
routeTables: [
488+
{
489+
Associations: [{ SubnetId: 'sub-123456' }],
490+
RouteTableId: 'rtb-123456',
491+
Routes: [
492+
{
493+
DestinationCidrBlock: '10.0.2.0/26',
494+
Origin: 'CreateRoute',
495+
State: 'active',
496+
VpcPeeringConnectionId: 'pcx-xxxxxx',
497+
},
498+
{
499+
DestinationCidrBlock: '10.0.1.0/24',
500+
GatewayId: 'local',
501+
Origin: 'CreateRouteTable',
502+
State: 'active',
503+
},
504+
{
505+
DestinationCidrBlock: '0.0.0.0/0',
506+
TransitGatewayId: 'tgw-xxxxxx',
507+
Origin: 'CreateRoute',
508+
State: 'active',
509+
},
510+
],
511+
},
512+
],
513+
});
514+
515+
// WHEN
516+
const result = await provider.getValue({
517+
account: '1234',
518+
region: 'us-east-1',
519+
filter,
520+
});
521+
522+
// THEN
523+
expect(result).toEqual({
524+
vpcId: 'vpc-1234567',
525+
vpcCidrBlock: '1.1.1.1/16',
526+
ownerAccountId: '123456789012',
527+
availabilityZones: ['bermuda-triangle-1337'],
528+
isolatedSubnetIds: undefined,
529+
isolatedSubnetNames: undefined,
530+
isolatedSubnetRouteTableIds: undefined,
531+
privateSubnetIds: ['sub-123456'],
532+
privateSubnetNames: ['Private'],
533+
privateSubnetRouteTableIds: ['rtb-123456'],
534+
publicSubnetIds: undefined,
535+
publicSubnetNames: undefined,
536+
publicSubnetRouteTableIds: undefined,
537+
vpnGatewayId: undefined,
538+
subnetGroups: undefined,
539+
});
540+
});
541+
478542
test('Recognize isolated subnet by route table', async () => {
479543
// GIVEN
480544
const filter = { foo: 'bar' };

0 commit comments

Comments
 (0)