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

[ecs-patterns]: allow use of existing load balancer in ApplicationMultipleTargetGroupsEc2Service #11347

Open ggallotti opened 3 years ago

ggallotti commented 3 years ago

This is a :rocket: Feature Request

Description

Would like to be able to use an existing load balancer with ApplicationMultipleTargetGroupsEc2Service.

Load balancer pricing includes a fee per hour of load balancer running, which currently means about $18 per month. Running many services, each with its own balancer, can quickly add up.

Additionally, creating a separate load balancer for each service means we can't run multiple services under the same DNS name. So it's not possible to call different microservices depending on the path, for example (probably a common pattern?). Or group multiple subdomains on the same load balancer.

Use Case

const service1 = new ApplicationMultipleTargetGroupsEc2Service(this, "Service1",{
    ...
    targetGroups: [
             {
                containerPort: 80,
                listener: "listener",
                **pathPattern: "service1",**
                priority: 1,
                protocol: Protocol.TCP,
              },
});
const service2 = new ApplicationMultipleTargetGroupsEc2Service(this, "Service2",{ 
    targetGroups: [
              {
                containerPort: 80,
                listener: "listener",
                **pathPattern: "service2",**
                priority: 2,
                protocol: Protocol.TCP,
              },
});

I would like that that two gets deployed to (Use the same LoadBalancer, instead of creating one for Each Service):

Proposed Solution

Not have a workaround. Would need to skip ECS Patterns for this.


piradeepk commented 3 years ago

@ggallotti for each of those services, should they be accessible by many listener ports, or do you only have 1 port to 1 service mapping?

piradeepk commented 3 years ago

If you're only looking to have 1 port mapped to each service, you could create the load balancer outside of the pattern construct, and pass it in to the ApplicationLoadBalancedEc2Service as an input prop. Let me know if this doesn't solve your issue.

ggallotti commented 3 years ago

@piradeepk, only 1 port to 1 service.

However I think I discarded ApplicationLoadBalancedEc2Service because it's seems to not support "pathPattern" rule for target Group.

Thanks for your response.

pmaoui commented 3 years ago

@ggallotti If you use 1 port to 1 service, ApplicationMultipleTargetGroupsEc2Service doesn't look like the way to go as you would need only one target group per service. From what I learned, ECS Patterns are suitable for fairly generic needs and doesn't support usage of existing resources like load balancers.
To use an existing ALB, I would recommend to import its listener and use the Ec2Service class . You can create many services with many target groups and linked them to one listener.

Here an example to attach one service to one target group to an existing listener:

const yourALBListener = ApplicationListener.fromLookup(this, 'appListener', {
    listenerArn: 'the:arn:of-your-elb-listener-here',
})

const service1 = new Ec2Service(this, 'Service1', {
    ...
})

const service1Target = service1.loadBalancerTarget({
    containerName: 'your-container-name-from-service1',
    containerPort: 80,
    protocol: Protocol.TCP,
})

const group1 = new ApplicationTargetGroup(this, 'DashboardTargetGroup', {
    vpc: YourVpc,
    port: 80,
    targetType: TargetType.IP,
})

const group1Rule = new ApplicationListenerRule(this, 'group1rule', {
    pathPattern: 'service1',
    listener: yourALBListener,
    priority: 10,
})

service1Target.attachToApplicationTargetGroup(group1)
group1Rule.addTargetGroup(group1)

Of course, I would be interested if someone is aware of a more concise approach.

ggallotti commented 3 years ago

Thanks for the code @poupougnac. Seems very simple and clean. Yes, I think that for now I would need to Skip ECS Patterns for this.

Puskin2911 commented 1 year ago

If you're only looking to have 1 port mapped to each service, you could create the load balancer outside of the pattern construct, and pass it in to the ApplicationLoadBalancedEc2Service as an input prop. Let me know if this doesn't solve your issue.

How about this issue? I'm facing thing issue and my case is one service has multiple ports. I saw that this issue is still open and added feature/pattern label. Can anyone give a status or any work around right now before the cdk lib is already (even work arround is cloudformation is waited from me right now). Thank guys !!!