-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
fix(elbv2): allow multiple certificates on ALB listener #4116
fix(elbv2): allow multiple certificates on ALB listener #4116
Conversation
Fixes a cloudformation error when attaching multiple certificates to an alb listener. Cloudformation allows only a single certificate attached to the `LoadBalancer` resource. If multiple certificates are passed to the construct on initialization or through the `.addCertificateArns` method, separate `ListenerCertificate` resources are created for all after the first. Closes [issue aws#3757](aws#3757)
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
|
ec2381c
to
8fd47e5
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 |
This potentially creates multiple
Attaches This was done to avoid the usage of the We may want to add a section on attaching certificates to load balancers to the documentation to detail what resources get created under different conditions. If that is something that the team believes should be included with this fix, let me know. |
this.certificateArns.push(...(props.certificateArns || [])); | ||
|
||
// Attach certificates | ||
if (props.certificateArns) { |
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.
This does not preclude it from being an empty list, just means it's not undefined
.
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.
Added a check for an empty list as well.
public addCertificateArns(_id: string, arns: string[]): void { | ||
this.certificateArns.push(...arns); | ||
public addCertificateArns(id: string, arns: string[]): void { | ||
const [first, ...rest] = arns; |
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.
Neat!
this.certificateArns.push(...arns); | ||
public addCertificateArns(id: string, arns: string[]): void { | ||
const [first, ...rest] = arns; | ||
const additionalCertArns = this.certificateArns.length ? arns : rest; |
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'd rather you explicitly test length > 0
than rely on truthiness of 0.
const [first, ...rest] = arns; | ||
const additionalCertArns = this.certificateArns.length ? arns : rest; | ||
|
||
if (!this.certificateArns.length && typeof first === "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.
Is this to deal with the case where an empty list was passed? I'd rather you test for that explicitly than rely on the (to me somewhat obscure) behavior that:
const [x, ...xs] = [];
// x === undefined
I would have expected that to throw. Obviously not, because JavaScript :), but the typeof
check confused me before I tried this out in the REPL.
I'd much rather see a
if (arns.length === 0) { return; }
At the top.
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.
This was to defend against an empty array being passed, I agree that explicitly testing that condition is better.
listener: this, | ||
certificateArns: additionalCertArns | ||
}); | ||
} |
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 agree that the whole logic here is a little hairy to handle different cases. What if we embraced mutability, and do something like this:
addCertificateArns(id, arns: string[]) {
if (arns.length > 0 && this.certificateArns.length === 0) {
// Pop off the first certificate and put it on the main resource
const first = arns.splice(0, 1)[0];
this.certificateArns.push(first);
}
if (arns.length > 0) {
new ApplicationListenerCertificate(this, id, { ... });
}
}
If you feel bad about mutating the input argument (reasonable! :) then we can always copy it into a local variable.
const additionalCertArns = [...arns]; | ||
|
||
if (this.certificateArns.length === 0 && additionalCertArns.length > 0) { | ||
const first = additionalCertArns.splice(0, 1)[0]; |
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.
using .shift
feels better but because of the type definition, requires a non-null assertion operator like so:
const first = additionalCertArns.shift()!;
Otherwise typescript sees the type of first
being string | undefined
even though its guarded against by checking that additionalCertArns.length
is gt 0.
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.
Oh yeah, shift
is totally better, I forgot that existed :)
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.
But I'm happy to accept the PR as-is
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.
Thanks!
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
Thank you for contributing! Your pull request is now being automatically merged. |
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 |
* fix(elasticloadbalancingv2): Allow Multiple Certificates on ALB Listener Fixes a cloudformation error when attaching multiple certificates to an alb listener. Cloudformation allows only a single certificate attached to the `LoadBalancer` resource. If multiple certificates are passed to the construct on initialization or through the `.addCertificateArns` method, separate `ListenerCertificate` resources are created for all after the first. Closes [issue #3757](#3757) * PR Revisions
Fixes a cloudformation error when attaching multiple certificates to an alb listener. Cloudformation allows only a single certificate attached to the
LoadBalancer
resource. If multiple certificates are passed to the construct on initialization or through the.addCertificateArns
method, separateListenerCertificate
resources are created for all after the first.Closes #3757
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license