Skip to content

Commit

Permalink
fix(vpc): detect subnet with TGW route as PRIVATE_WITH_EGRESS (#25958)
Browse files Browse the repository at this point in the history
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*
  • Loading branch information
bruecktech authored Jun 15, 2023
1 parent b705956 commit 49643d6
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 1 deletion.
10 changes: 10 additions & 0 deletions packages/aws-cdk/lib/context-providers/vpcs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export class VpcNetworkContextProviderPlugin implements ContextProviderPlugin {
if (type === undefined && subnet.MapPublicIpOnLaunch) { type = SubnetType.Public; }
if (type === undefined && routeTables.hasRouteToIgw(subnet.SubnetId)) { type = SubnetType.Public; }
if (type === undefined && routeTables.hasRouteToNatGateway(subnet.SubnetId)) { type = SubnetType.Private; }
if (type === undefined && routeTables.hasRouteToTransitGateway(subnet.SubnetId)) { type = SubnetType.Private; }
if (type === undefined) { type = SubnetType.Isolated; }

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

/**
* Whether the given subnet has a route to a Transit Gateway
*/
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');
}

/**
* Whether the given subnet has a route to an IGW
*/
Expand Down
66 changes: 65 additions & 1 deletion packages/aws-cdk/test/context-providers/vpcs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ test('Recognize public subnet by route table', async () => {
});
});

test('Recognize private subnet by route table', async () => {
test('Recognize private subnet by route table with NAT Gateway', async () => {
// GIVEN
const filter = { foo: 'bar' };
const provider = new VpcNetworkContextProviderPlugin(mockSDK);
Expand Down Expand Up @@ -475,6 +475,70 @@ test('Recognize private subnet by route table', async () => {
});
});

test('Recognize private subnet by route table with Transit Gateway', async () => {
// GIVEN
const filter = { foo: 'bar' };
const provider = new VpcNetworkContextProviderPlugin(mockSDK);

mockVpcLookup({
subnets: [
{ SubnetId: 'sub-123456', AvailabilityZone: 'bermuda-triangle-1337', MapPublicIpOnLaunch: false },
],
routeTables: [
{
Associations: [{ SubnetId: 'sub-123456' }],
RouteTableId: 'rtb-123456',
Routes: [
{
DestinationCidrBlock: '10.0.2.0/26',
Origin: 'CreateRoute',
State: 'active',
VpcPeeringConnectionId: 'pcx-xxxxxx',
},
{
DestinationCidrBlock: '10.0.1.0/24',
GatewayId: 'local',
Origin: 'CreateRouteTable',
State: 'active',
},
{
DestinationCidrBlock: '0.0.0.0/0',
TransitGatewayId: 'tgw-xxxxxx',
Origin: 'CreateRoute',
State: 'active',
},
],
},
],
});

// WHEN
const result = await provider.getValue({
account: '1234',
region: 'us-east-1',
filter,
});

// THEN
expect(result).toEqual({
vpcId: 'vpc-1234567',
vpcCidrBlock: '1.1.1.1/16',
ownerAccountId: '123456789012',
availabilityZones: ['bermuda-triangle-1337'],
isolatedSubnetIds: undefined,
isolatedSubnetNames: undefined,
isolatedSubnetRouteTableIds: undefined,
privateSubnetIds: ['sub-123456'],
privateSubnetNames: ['Private'],
privateSubnetRouteTableIds: ['rtb-123456'],
publicSubnetIds: undefined,
publicSubnetNames: undefined,
publicSubnetRouteTableIds: undefined,
vpnGatewayId: undefined,
subnetGroups: undefined,
});
});

test('Recognize isolated subnet by route table', async () => {
// GIVEN
const filter = { foo: 'bar' };
Expand Down

0 comments on commit 49643d6

Please sign in to comment.