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

Sharing load balancer listener between stacks #4160

Closed markusl closed 5 years ago

markusl commented 5 years ago

:question: General Issue

Since hitting CloudFormation 200 resource limit, I have been trying to refactor our services to multiple stacks sharing ALB between the stacks.

However, it seems importing ALB or ALB listener between stacks and adding more services to it is challenging.

Stack1 - Create stack and ALB with listener

  const stack = new cdk.Stack(app, `Stack`, props);
  const vpc = ec2.Vpc.fromVpcAttributes(stack, `Vpc`, networkConfiguration.vpcProps);

  const loadBalancerCertificate = cm.Certificate.fromCertificateArn(stack, `Certificate`, networkConfiguration.certificateArn);

  const loadBalancer = new elbv2.ApplicationLoadBalancer(stack, `LoadBalancer`, {
    vpc,
  });

  const listener = loadBalancer
    .addListener(`HttpsListener`, {
      port: 443,
      certificateArns: [loadBalancerCertificate.certificateArn],
    });

...

    fargateServices.map((fg, i) =>
      listener
        .addTargets(`${services[i].name}`, {
          protocol: elbv2.ApplicationProtocol.HTTP,
          targets: [fg],
        }
      ));

Stack 2 - Trying to import existing listener to add new services

  const stack2 = new cdk.Stack(app, `stack2`, props);
  const existingListener = elbv2.ApplicationListener.fromApplicationListenerAttributes(stackInternalServices,
    `Listener`, {
      listenerArn: listener.listenerArn,
      securityGroupId: loadBalancer.loadBalancerSecurityGroups[0]
  });

Result

The result of trying to do that is following: Error: Can only call addTargets() when using a constructed ApplicationListener; construct a new TargetGroup and use addTargetGroup.

Do you have any example or recommendations about how to do this? In general it does not feel right to work around CF limitations in this way..

Environment

rix0rrr commented 5 years ago

What if you don't use fromApplicationListenerAttributes but just use the listener directly in stack 2?

markusl commented 5 years ago

@rix0rrr thanks for the tip. Didn't even think it could be that easy. Here's the problem with that one:


Error: 'ApplicationName-Stack2' depends on 'ApplicationName-Stack1'
(ApplicationName-Stack2/ApplicationName-Stack2-ContainerName/Service ->
    ApplicationName-Stack1/ApplicationName-Stack1LoadBalancer/ApplicationName-Stack1HttpsListener/ApplicationName-Stack2-ContainerNameGroup/Resource.Ref).

Adding this dependency (ApplicationName-Stack1/ApplicationName-Stack1LoadBalancer/SecurityGroup/to SecurityGroup997F5017:8080 -> ApplicationName-Stack2/ApplicationName-Stack2-ContainerName/SecurityGroup/Resource.GroupId) would create a cyclic reference.```
rix0rrr commented 5 years ago

I think you are now getting hit by the issue that was fixed in https://github.com/aws/aws-cdk/pull/4111.

The fix for that will be rolling out later today in the new release. Sorry to keep you waiting.

markusl commented 5 years ago

I can now confirm that this is fixed. Thanks for the help :)

PrettySolution commented 1 year ago

@rix0rrr thanks for the tip. Didn't even think it could be that easy. Here's the problem with that one:


Error: 'ApplicationName-Stack2' depends on 'ApplicationName-Stack1'
(ApplicationName-Stack2/ApplicationName-Stack2-ContainerName/Service ->
    ApplicationName-Stack1/ApplicationName-Stack1LoadBalancer/ApplicationName-Stack1HttpsListener/ApplicationName-Stack2-ContainerNameGroup/Resource.Ref).

Adding this dependency (ApplicationName-Stack1/ApplicationName-Stack1LoadBalancer/SecurityGroup/to SecurityGroup997F5017:8080 -> ApplicationName-Stack2/ApplicationName-Stack2-ContainerName/SecurityGroup/Resource.GroupId) would create a cyclic reference.```

Does it work in CDK v2? Can you please share an example? Can't get it working today

rbrayner commented 1 year ago

I'm facing the same issue in v2 as well. Couldn't find a solution yet.

mixtah commented 1 year ago

I believe I'm also facing the same issue in v2 using the same method originally suggested by @rix0rrr

mixtah commented 1 year ago

Actually I think I found the way around, at least for me, instead of using

loadBalancerListener.addAction('Action', {
    priority,
    conditions: [ListenerCondition.hostHeaders([domainName])],
    action: ListenerAction.forward([this.targetGroup])
});

this seems to work

new ApplicationListenerRule(this, 'ListenerRule', {
    listener: loadBalancerListener,
    priority,
    action: ListenerAction.forward([this.targetGroup]),
    conditions: [ListenerCondition.hostHeaders([domainName])],
});
arijeetsengupta commented 1 year ago

Cyclic dependency issue still exists in CDK v2