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.7k stars 3.93k forks source link

aws-elasticloadbalancingv2: fromApplicationLoadBalancerAttributes broken since v2.64.0 #24397

Open ChrisLane opened 1 year ago

ChrisLane commented 1 year ago

Describe the bug

Since v2.64.0, I can no longer import my application load balancer by its attributes from my elastic beanstalk environment. This was working in v2.63.2.

Expected Behavior

The code in Reproduction Steps successfully gets the application load balancer for heimdallApplicationLoadBalancer as it did in v2.63.2.

Current Behavior

The code in Reproduction Steps results in the following error when using aws-cdk v2.64.0 and above:

TypeError: Cannot read properties of undefined (reading 'startsWith')
    at parseArnShape (/home/chris/git/aws-env-setup/node_modules/aws-cdk-lib/core/lib/arn.js:1:5219)
    at Arn.split (/home/chris/git/aws-env-setup/node_modules/aws-cdk-lib/core/lib/arn.js:1:2317)
    at Object.parseLoadBalancerFullName (/home/chris/git/aws-env-setup/node_modules/aws-cdk-lib/aws-elasticloadbalancingv2/lib/shared/util.js:1:2289)
    at new ImportedApplicationLoadBalancer (/home/chris/git/aws-env-setup/node_modules/aws-cdk-lib/aws-elasticloadbalancingv2/lib/alb/application-load-balancer.js:1:20605)
    at ApplicationLoadBalancer.fromApplicationLoadBalancerAttributes (/home/chris/git/aws-env-setup/node_modules/aws-cdk-lib/aws-elasticloadbalancingv2/lib/alb/application-load-balancer.js:1:3060)
    at new StatelessCdkStack (/home/chris/git/aws-env-setup/lib/stack/stateless-cdk-stack.js:554:77)
    at /home/chris/git/aws-env-setup/bin/app.js:62:26
    at Array.forEach (<anonymous>)
    at Object.<anonymous> (/home/chris/git/aws-env-setup/bin/app.js:25:28)
    at Module._compile (node:internal/modules/cjs/loader:1275:14)

Reproduction Steps

I need to get my application load balancer via attributes since it is created by elasticbeanstalk but not available on the CfnEnvironment object. I need to pass the load balancer to create a CloudFront origin. Example code:

const vpc = someEc2Vpc;
const serviceSecurityGroup = someEc2SecurityGroup;
const heimdallEnv = someElasticBeanstalkCfnEnvironment;
const heimdallApplicationLoadBalancer = elbv2.ApplicationLoadBalancer.fromApplicationLoadBalancerAttributes(
    this,
    "heimdall-application-load-balancer",
    {
      vpc,
      securityGroupId: serviceSecurityGroup.securityGroupId,
      loadBalancerDnsName: heimdallEnv.attrEndpointUrl
    });

const heimdallApplicationLoadBalancerOrigin = new origins.LoadBalancerV2Origin(heimdallApplicationLoadBalancer, {
  protocolPolicy: cloudfront.OriginProtocolPolicy.HTTPS_ONLY,
  originSslProtocols: [cloudfront.OriginSslPolicy.TLS_V1_2],
  readTimeout: Duration.seconds(60)
});

Possible Solution

No response

Additional Information/Context

No response

CDK CLI Version

2.64.0 (build fb67c77)

Framework Version

No response

Node.js Version

v19.7.0

OS

Arch Linux 6.2.1-zen1

Language

Typescript

Language Version

JavaScript

Other information

No response

pahud commented 1 year ago

Probably related to https://github.com/aws/aws-cdk/pull/23853 as it introduced the new function parseLoadBalancerFullName() which throws in your error message. To help us better trouble-shooting, can you provide a full working sample that we can simply run the reproduce the error in our account?

ChrisLane commented 1 year ago

Here is a zip containing the project files to reproduce the error on cdk synth

cdk-alb-import-bug-example.zip

pahud commented 1 year ago

Hi @ChrisLane

From what I can see, the fromApplicationLoadBalancerAttributes() method requires loadBalancerArn which is missing in your provided code. I see you have loadBalancerDnsName instead which is optional. I believe you need to specify loadBalancerArn in your sample.

And in 2.63.2 this property was required as well: https://github.com/aws/aws-cdk/blob/e08e34a5dad5bcaf595404d24a11c9d937ce15e2/packages/%40aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-load-balancer.ts#L531

So I doubt you were able to import the ALB without passing loadBalancerArn in 2.63.2.

ChrisLane commented 1 year ago

@pahud the code in the example is taken from my production system and only slightly modified. I have been importing the ALB using just loadBalancerDnsName for a lot of versions now and it has always worked until this new version.

I am unsure how I would get the loadBalancerArn from a elasticbeanstalk.CfnEnvironment to be able to use it in fromApplicationLoadBalancerAttributes().

If you try the example project that I linked and change the version to v2.63.2, you will see that it works.

pahud commented 1 year ago

I noticed your zip bundle are CDK codes in JS. Yes I noticed your CDK in JS with cdk v2.63.2 can synthesize but if you create a new repo with CDK in TypeScript with version v2.63.2 the loadBalancerArn is still mandatory.

Did you write your CDK code in javascript rather than typescript?

image
ChrisLane commented 1 year ago

Yes sorry, my projects are all in JavaScript. The issue template doesn't offer JavaScript as an option.

pahud commented 1 year ago

@ChrisLane

No problem but using TypeScript over JavaScript would allow you to have powerful type check from IDE and boost your coding performance with CDK. Is there any reason you need to us JS rather than TS in your project?

ChrisLane commented 1 year ago

@ChrisLane

No problem but using TypeScript over JavaScript would allow you to have powerful type check from IDE and boost your coding performance with CDK. Is there any reason you need to us JS rather than TS in your project?

Unfortunately that's a limitation for my team in particular since all of our other projects are JavaScript rather than TypeScript, we try to keep everything in the same language.

ChrisLane commented 1 year ago

I'm currently working around this issue by getting the load balancer via the fromLookup function matching against a tag instead.

elbv2.ApplicationLoadBalancer.fromLookup(
          this,
          "heimdall-application-load-balancer",
          {
            loadBalancerTags: {"elasticbeanstalk:environment-name": heimdallEnv.environmentName}
          });