awslabs / aws-solutions-constructs

The AWS Solutions Constructs Library is an open-source extension of the AWS Cloud Development Kit (AWS CDK) that provides multi-service, well-architected patterns for quickly defining solutions
https://docs.aws.amazon.com/solutions/latest/constructs/
Apache License 2.0
1.24k stars 247 forks source link

How to safely deploy stacks using AlbToFargate into the same VPC #918

Open phsiao opened 1 year ago

phsiao commented 1 year ago

This is not necessarily a bug but it is not clear to me what the best practices are.

Because AlbToFargate (and other constructs) attaches service endpoint (e.g., ecr, ddb) into the VPC it uses, if you have multiple stacks all using AlbToFargate and share the same vpc only the first stack would succeed because of the endpoints can't be attached again.

What one would have done is to perform the service endpoint attachment in where the VPC is defined, and when importing the VPC into a stack one also places the interfaceTag marker into the VPC construct so the service endpoints are not attached again. This gets around the problem but it does not seem to be a general solution.

Reproduction Steps

Error Log

Environment

Other


This is :bug: Bug Report

biffgaut commented 1 year ago

Thanks for the note! Have you seen behavior where two identical endpoints are added to the same VPC? When we run the code below only 1 endpoint is created:

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

    const firstConstruct = new LambdaToSqs(this, 'first', {
      deployVpc: true,
      lambdaFunctionProps: {
         code: lambda.Code.fromAsset(`lambda`),
         runtime: lambda.Runtime.NODEJS_14_X,
         handler: '.handler',
      },
    });

    const secondConstruct = new LambdaToSqs(this, 'second', {
      existingVpc: firstConstruct.vpc,
      lambdaFunctionProps: {
         code: lambda.Code.fromAsset(`lambda`),
         runtime: lambda.Runtime.NODEJS_14_X,
         handler: '.handler',
      },
    });
  }
}

If you've got an example that creates two endpoints of the same type, please share it.

biffgaut commented 1 year ago

Ah - is your point that if I obtain a pre-existing VPC from another stack using something like fromVpcAttributes, then a subsequent construct could add a second endpoint? That could be - it could be the CDK that is preventing the redundancy in my example.

phsiao commented 1 year ago

Right. If the two constructs shares the same VPC construct, the invocation of the first construct would place some markers in the VPC construct so the invocation of the second construct would avoid attaching the endpoints again.

But if the second construct does a fromVpcAttributes to import the same VPC, the second construct can't detect the endpoints are already attached and would attempt to attach again and fail.

biffgaut commented 1 year ago

I'm not sure that an answer to this exists in the CDK world. fromVpcAttributes only populates the existing resources defined in VpcAttributes - and the interface has no entry to include endpoints. It would appear that CDK cannot learn about the endpoints of existing VPCs getting pulled into the stack.

.fromLookup might have different behavior, I have never experimented with it.

biffgaut commented 1 year ago

To the best of our knowledge, this cannot be accomplished in the CDK at this time. We'll put it on our backlog on the possibility that this changes in the future.