-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Conversation
Thanks so much for taking the time to contribute to the AWS CDK ❤️ We will shortly assign someone to review this pull request and help get it
|
1 similar comment
Thanks so much for taking the time to contribute to the AWS CDK ❤️ We will shortly assign someone to review this pull request and help get it
|
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
protocol: containerTarget.protocol | ||
}; | ||
for (const targetGroupProp of containerTarget.targetGroups) { | ||
if (targetGroupProp.listener instanceof elbv2.ApplicationListener) { |
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.
Just for re-usability can we move out the logic for registering based on ApplicationListener and NetworkLister to independent methods, and refer to those methods here?
Pull request has been modified.
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
/** | ||
* Container targets of the container. | ||
*/ | ||
readonly containerTargets: ContainerTargetProps[] |
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.
Not sure I like this name. It feels like introducing a new concept to users that I wonder whether it's worthwhile.
Also: ultimately, we just need a flat list of (container, port, targetGroupName, listener)
, so why introduce all this hierarchy here? Feels like a flat list of tuples would give a much more convenient API.
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.
Yeah I agree, since for each service for most of cases there will only be one or two targets to be registered. Using a flat list should be a better option.
/** | ||
* Setting to create and attach target groups. | ||
*/ | ||
readonly targetGroups: TargetGroupProps [], |
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.
I would expect a property named targetGroups
to take ITargetGroup
objects, not properties to create new target groups.
/** | ||
* Properties for adding new targets to a listener. | ||
*/ | ||
readonly addTargetGroupProps?: elbv2.AddApplicationTargetsProps | elbv2.AddNetworkTargetsProps, |
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.
No type unions please. If you want unions, create union-like classes instead.
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.
Cannot create an interface that extends these and also listeners below because they both have the properties with the same name but different types. Also, can you please explain the reason why type union is not recommended?
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.
Type unions do not translate well across jsii (to all languages that we target).
Union-like classes are abstract base classes that get constructed through some factory function:
abstract class MyGroupUnion {
public static variantOne(): MyGroupUnion {
// Return some subclass of MyGroupUnion
}
public static variantTwo(props: SomeProps) {
// Return some subclass of MyGroupUnion
}
public abstract yieldSomeInterestingProperties(): SomeInterestingProperties;
}
/** | ||
* Listener for the target group to attach to [disable-awslint:ref-via-interface]. | ||
*/ | ||
readonly listener: elbv2.ApplicationListener | elbv2.NetworkListener |
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.
Why are the interfaces not good enough?
Can that be fixed?
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.
So it's because INetworkListener
does not have the method addTargets
, and arn is the only property the interface has.
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.
Sure. Would it be possible to effectively implement addTargets()
in the interfaces?
I guess not, huh?
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.
It is still possible to implement addTargets() but it will be a little bit clumsy and reinvent the wheels. Yeah I think you are right.
649ed01
to
4d5bb12
Compare
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
4d5bb12
to
9807911
Compare
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
9807911
to
0dc3b6b
Compare
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
0dc3b6b
to
fc28e33
Compare
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
/** | ||
* Create a config for adding target group to ALB listener. | ||
*/ | ||
public static applicationListenerConfig(listener: elbv2.ApplicationListener, props?: elbv2.AddApplicationTargetsProps): ListenerConfig { |
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.
I would remove the Config
at the end of the method name here. Shorter is better, and the "config" part is already implied by the class name.
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.
👍
/** | ||
* Properties for defining an ECS target. | ||
*/ | ||
readonly containerTarget: LoadBalancerTargetOptions, |
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.
All other interfaces are declared using a semicolon (;
) at the end of fields, so please match the existing style.
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.
Also, I think I would be in favor of inlining the LoadBalancerTargetOptions
property into the parent struct here. The usability will be a lot better in non-JS languages.
/** | ||
* ID for a target group to be created. | ||
*/ | ||
readonly targetGroupId: string, |
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.
I would prefer you called this newTargetGroupId
to make it abundantly clear you will be creating a new TargetGroup for users, rather than picking an existing Target Group that they've already created.
* }, | ||
* ) | ||
*/ | ||
public registerContainerTargets(...targets: EcsTarget[]) { |
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.
Are you sure that, if you're coming at this cold (and don't have all the state that you have in your head about this change), that the name service.registerContainerTargets
is clear enough that it pertains to load balancing? (And not, for example, service discovery?)
For myself, I would be wondering what I'm registering into?
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.
It is hard to find a name that can be really clear enough to figure out what exactly this method does by seeing the name alone. However, I agree the naming can be improved to make it more explicit.
fc28e33
to
e9aa888
Compare
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
* @example | ||
* | ||
* service.registerLoadBalancerTargets( | ||
* { | ||
* containerTarget: { | ||
* containerName: 'web', | ||
* containerPort: 80, | ||
* }, | ||
* targetGroupId: 'ECS', | ||
* listener: ecs.ListenerConfig.applicationListener(listener, { | ||
* protocol: elbv2.ApplicationProtocol.HTTPS | ||
* }), | ||
* }, | ||
* ) |
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.
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 comment
The 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?
/** | ||
* ID for a target group to be created. | ||
*/ | ||
readonly newTargetGroupId: string; |
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.
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
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.
Very small nits, otherwise LGTM!
* @example | ||
* | ||
* service.registerLoadBalancerTargets( | ||
* { | ||
* containerTarget: { | ||
* containerName: 'web', | ||
* containerPort: 80, | ||
* }, | ||
* targetGroupId: 'ECS', | ||
* listener: ecs.ListenerConfig.applicationListener(listener, { | ||
* protocol: elbv2.ApplicationProtocol.HTTPS | ||
* }), | ||
* }, | ||
* ) |
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.
Do we have a precedent for having examples in jsdoc strings versus in README?
@@ -664,6 +664,321 @@ export = { | |||
|
|||
test.done(); | |||
} | |||
}, | |||
|
|||
'allows add load balancers to a service': { |
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.
Maybe rephrase to "allows registering multiple target groups"
}, | ||
|
||
'allows add load balancers to a service': { | ||
'when application load balancers': { |
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.
Nit: "with" application load balancers
}, | ||
}, | ||
|
||
'when network load balancers': { |
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.
"with"
I included the example in README as well. And for jsdoc strings, I referred to this. I think it can help when users first use this method and when they hover to the method they can see the example to know how to use the method, which makes it more convenient. |
c514e40
to
b0ea719
Compare
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
Examples could/should be in both. |
Remove the label when you are ready to merge. |
Pull request has been modified.
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
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.
Ship it!
Thank you for contributing! Your pull request is now being automatically merged. |
Add a new API for registering ECS targets, which is also the second part for #3922.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license