aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.52k stars 3.86k forks source link

vpc: PRIVATE_WITH_EGRESS not getting applied with route to TransitGateway #25626

Closed bruecktech closed 1 year ago

bruecktech commented 1 year ago

Describe the bug

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 that introduced it talks about TransitGateway too but it doesn't seem to get applied.

Expected Behavior

Detect subnet with a default route to a TransitGateway as PRIVATE_WITH_EGRESS

Current Behavior

Subnets with a default route to a TransitGateway are detected as PRIVATE_ISOLATED

Reproduction Steps

Use Vpc.fromLookup in a VPC that has subnets with a default route to a TransitGateway

Possible Solution

No response

Additional Information/Context

No response

CDK CLI Version

2.66

Framework Version

No response

Node.js Version

16.16

OS

MacOS

Language

Typescript

Language Version

No response

Other information

No response

peterwoodworth commented 1 year ago

You're right, I'm finding the same behavior.

When we set the type of imported subnets, we are first checking that the subnet has the type explicitly declared with a tag. If it doesn't, then we will cross reference with the describeRouteTable response to check if the subnet is associated with a route table.

https://github.com/aws/aws-cdk/blob/b60876f7bd973f88e965c7e6204ced11c55c55a3/packages/aws-cdk/lib/context-providers/vpcs.ts#L72-L77

This doesn't account for transit gateway route tables, which are separate. And unfortunately, it doesn't appear we can fetch subnet information from this call. Maybe there's another way we could detect this?

bruecktech commented 1 year ago

From what I understand we don't actually need to look at TransitGateway route tables, but just incorporate routes to TransitGatewayIds in the regular route tables.

This is how the route looks like in the describe-route-table CLI command

{
    "DestinationCidrBlock": "0.0.0.0/0",
    "TransitGatewayId": "tgw-02261c6cd4750fc3c",
    "Origin": "CreateRoute",
    "State": "active"
},

So I think what's missing is something like this before line 77

if (type === undefined && routeTables.hasRouteToTransitGateway(subnet.SubnetId)) { type = SubnetType.Private; }

whereas hasRouteToTransitGateway could be implemented as

  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');
  }
github-actions[bot] commented 1 year ago

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.