Skip to content
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

Merged

Conversation

MrArnoldPalmer
Copy link
Contributor

@MrArnoldPalmer MrArnoldPalmer commented Sep 17, 2019

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 #3757


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

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)
@mergify
Copy link
Contributor

mergify bot commented Sep 17, 2019

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
merged. In the meantime, please take a minute to make sure you follow this
checklist
:

  • PR title type(scope): text
    • type: fix, feat, refactor go into CHANGELOG, chore is hidden
    • scope: name of module without aws- or cdk- prefix or postfix (e.g. s3 instead of aws-s3-deployment)
    • text: use all lower-case, do not end with a period, do not include issue refs
  • PR Description
    • Rationale: describe rationale of change and approach taken
    • Issues: indicate issues fixed via: fixes #xxx or closes #xxx
    • Breaking?: last paragraph: BREAKING CHANGE: <describe what changed + link for details>
  • Testing
    • Unit test added. Prefer to add a new test rather than modify existing tests
    • CLI or init templates change? Re-run/add CLI integration tests
  • Documentation
    • README: update module README to describe new features
    • API docs: public APIs must be documented. Copy from official AWS docs when possible
    • Design: for significant features, follow design process

@MrArnoldPalmer MrArnoldPalmer force-pushed the bugfix/3757_alb-multiple-certificates branch from ec2381c to 8fd47e5 Compare September 17, 2019 18:17
@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@MrArnoldPalmer
Copy link
Contributor Author

This potentially creates multiple ListenerCertificate constructs where technically only one would be necessary.

const listener = lb.addListener(this, "x", {
  certificateArns: ["cert0"]
});
listener.addCertificateArns("ListenerCert1", ["cert1", "cert2"]);
listener.addCertificateArns("ListenerCert2", ["cert3", "cert4"]);

Attaches cert0 to the listener resource, and creates two separate ListenerCertificate resources, one with certs 1 and 2, the second with certs 3 and 4. If we built the list of cert arns and created the resources within prepare we could limit the number of these constructs needed.

This was done to avoid the usage of the prepare method. I was warned that prepare can cause breakage in automatic dependency resolution.

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.

@MrArnoldPalmer MrArnoldPalmer marked this pull request as ready for review September 17, 2019 19:30
@rix0rrr rix0rrr self-assigned this Sep 18, 2019
this.certificateArns.push(...(props.certificateArns || []));

// Attach certificates
if (props.certificateArns) {
Copy link
Contributor

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.

Copy link
Contributor Author

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;
Copy link
Contributor

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;
Copy link
Contributor

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") {
Copy link
Contributor

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.

Copy link
Contributor Author

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
});
}
Copy link
Contributor

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];
Copy link
Contributor Author

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.

Copy link
Contributor

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 :)

Copy link
Contributor

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

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@rix0rrr rix0rrr changed the title fix(elasticloadbalancingv2): Allow Multiple Certificates on ALB Listener fix(elbv2): allow multiple certificates on ALB listener Sep 19, 2019
@mergify
Copy link
Contributor

mergify bot commented Sep 19, 2019

Thank you for contributing! Your pull request is now being automatically merged.

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@mergify mergify bot merged commit d1f8e5c into aws:master Sep 19, 2019
eladb pushed a commit that referenced this pull request Sep 23, 2019
* 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
@MrArnoldPalmer MrArnoldPalmer deleted the bugfix/3757_alb-multiple-certificates branch April 26, 2023 21:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants