-
Notifications
You must be signed in to change notification settings - Fork 3.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(ecs): add a new API for registering ECS targets #4212
Changes from all commits
f569711
10884f2
b77386b
e62f9dc
e384bf6
55b665a
f3ff670
b0ea719
1192730
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ import cloudmap = require('@aws-cdk/aws-servicediscovery'); | |
import { Construct, Duration, IResolvable, IResource, Lazy, Resource, Stack } from '@aws-cdk/core'; | ||
import { LoadBalancerTargetOptions, NetworkMode, TaskDefinition } from '../base/task-definition'; | ||
import { ICluster } from '../cluster'; | ||
import { Protocol } from '../container-definition'; | ||
import { CfnService } from '../ecs.generated'; | ||
import { ScalableTaskCount } from './scalable-task-count'; | ||
|
||
|
@@ -23,6 +24,37 @@ export interface IService extends IResource { | |
readonly serviceArn: string; | ||
} | ||
|
||
export interface EcsTarget { | ||
/** | ||
* The name of the container. | ||
*/ | ||
readonly containerName: string; | ||
|
||
/** | ||
* The port number of the container. Only applicable when using application/network load balancers. | ||
* | ||
* @default - Container port of the first added port mapping. | ||
*/ | ||
readonly containerPort?: number; | ||
|
||
/** | ||
* The protocol used for the port mapping. Only applicable when using application load balancers. | ||
* | ||
* @default Protocol.TCP | ||
*/ | ||
readonly protocol?: Protocol; | ||
|
||
/** | ||
* ID for a target group to be created. | ||
*/ | ||
readonly newTargetGroupId: string; | ||
|
||
/** | ||
* Listener and properties for adding target group to the listener. | ||
*/ | ||
readonly listener: ListenerConfig; | ||
} | ||
|
||
/** | ||
* Interface for ECS load balancer target. | ||
*/ | ||
|
@@ -116,6 +148,83 @@ export interface BaseServiceProps extends BaseServiceOptions { | |
readonly launchType: LaunchType; | ||
} | ||
|
||
/** | ||
* Base class for configuring listener when registering targets. | ||
*/ | ||
export abstract class ListenerConfig { | ||
/** | ||
* Create a config for adding target group to ALB listener. | ||
*/ | ||
public static applicationListener(listener: elbv2.ApplicationListener, props?: elbv2.AddApplicationTargetsProps): ListenerConfig { | ||
return new ApplicationListenerConfig(listener, props); | ||
} | ||
|
||
/** | ||
* Create a config for adding target group to NLB listener. | ||
*/ | ||
public static networkListener(listener: elbv2.NetworkListener, props?: elbv2.AddNetworkTargetsProps): ListenerConfig { | ||
return new NetworkListenerConfig(listener, props); | ||
} | ||
|
||
/** | ||
* Create and attach a target group to listener. | ||
*/ | ||
public abstract addTargets(id: string, target: LoadBalancerTargetOptions, service: BaseService): void; | ||
} | ||
|
||
/** | ||
* Class for configuring application load balancer listener when registering targets. | ||
*/ | ||
class ApplicationListenerConfig extends ListenerConfig { | ||
SoManyHs marked this conversation as resolved.
Show resolved
Hide resolved
|
||
constructor(private readonly listener: elbv2.ApplicationListener, private readonly props?: elbv2.AddApplicationTargetsProps) { | ||
super(); | ||
} | ||
|
||
/** | ||
* Create and attach a target group to listener. | ||
*/ | ||
public addTargets(id: string, target: LoadBalancerTargetOptions, service: BaseService) { | ||
const props = this.props || {}; | ||
const protocol = props.protocol; | ||
const port = props.port !== undefined ? props.port : (protocol === undefined ? 80 : | ||
(protocol === elbv2.ApplicationProtocol.HTTPS ? 443 : 80)); | ||
this.listener.addTargets(id, { | ||
... props, | ||
targets: [ | ||
service.loadBalancerTarget({ | ||
...target | ||
}) | ||
], | ||
port | ||
}); | ||
} | ||
} | ||
|
||
/** | ||
* Class for configuring network load balancer listener when registering targets. | ||
*/ | ||
class NetworkListenerConfig extends ListenerConfig { | ||
SoManyHs marked this conversation as resolved.
Show resolved
Hide resolved
|
||
constructor(private readonly listener: elbv2.NetworkListener, private readonly props?: elbv2.AddNetworkTargetsProps) { | ||
super(); | ||
} | ||
|
||
/** | ||
* Create and attach a target group to listener. | ||
*/ | ||
public addTargets(id: string, target: LoadBalancerTargetOptions, service: BaseService) { | ||
const port = this.props !== undefined ? this.props.port : 80; | ||
this.listener.addTargets(id, { | ||
... this.props, | ||
targets: [ | ||
service.loadBalancerTarget({ | ||
...target | ||
}) | ||
], | ||
port | ||
}); | ||
} | ||
} | ||
|
||
/** | ||
* The base class for Ec2Service and FargateService services. | ||
*/ | ||
|
@@ -283,6 +392,35 @@ export abstract class BaseService extends Resource | |
}; | ||
} | ||
|
||
/** | ||
* Use this function to create all load balancer targets to be registered in this service, add them to | ||
* target groups, and attach target groups to listeners accordingly. | ||
* | ||
* @example | ||
* | ||
* service.registerLoadBalancerTargets( | ||
* { | ||
* containerTarget: { | ||
* containerName: 'web', | ||
* containerPort: 80, | ||
* }, | ||
* targetGroupId: 'ECS', | ||
* listener: ecs.ListenerConfig.applicationListener(listener, { | ||
* protocol: elbv2.ApplicationProtocol.HTTPS | ||
* }), | ||
* }, | ||
* ) | ||
Comment on lines
+399
to
+412
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should add this to the README, not sure if it makes sense to add it here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we have a precedent for having examples in jsdoc strings versus in README? |
||
*/ | ||
public registerLoadBalancerTargets(...targets: EcsTarget[]) { | ||
for (const target of targets) { | ||
target.listener.addTargets(target.newTargetGroupId, { | ||
containerName: target.containerName, | ||
containerPort: target.containerPort, | ||
protocol: target.protocol | ||
}, this); | ||
} | ||
} | ||
|
||
/** | ||
* This method is called to attach this service to a Network Load Balancer. | ||
* | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we rename this to targetGroupId (new is relative)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ha, I just made him change it from
targetGroupId
->newTargetGroupId
.The thing is, I'm not sure that
targetGroupId
conveys accurately enough that it will be created, rather than one that already exists that happens to have that ID.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough, just find newTargetGroup to be ambiguous.