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

[cloudfront] [lambda] Cross-region Lambda construct for Lambda@Edge #9862

Closed
njlynch opened this issue Aug 20, 2020 · 5 comments · Fixed by #10500
Closed

[cloudfront] [lambda] Cross-region Lambda construct for Lambda@Edge #9862

njlynch opened this issue Aug 20, 2020 · 5 comments · Fixed by #10500
Assignees
Labels
@aws-cdk/aws-cloudfront Related to Amazon CloudFront @aws-cdk/aws-lambda Related to AWS Lambda effort/large Large work item – several weeks of effort feature-request A feature should be added or improved. in-progress This issue is being actively worked on. p1

Comments

@njlynch
Copy link
Contributor

njlynch commented Aug 20, 2020

Create a construct (e.g., EdgeLambda) which facilitates defining Lambda functions cross-region.

Use Case

CloudFront is a "global" service, but requires that both certificates and Lambda@Edge functions be defined in us-east-1 (N Virginia) to use them with a distribution. This creates a lot of overhead for users who have stacks that include CloudFront in different regions.

Customers must have separate stacks to host the Lambda function, then use SSM (or another alternative) to communicate the ARN between stacks. See #1575 (comment) for a detailed explanation of the process as it exists today.

Proposed Solution

The other CloudFront-constrained service (AWS Certificate Manager) has a custom resource for this purpose: DnsValidationCertificate. Stealing ideas from that pattern may be useful. One of the complications for Lambda (vs ACM) is that Lambda functions often require assets, which is more heavy-weight than just passing the defining parameters/props.

CodePipeline has a mechanism for cross-region deployments (see the README section titled 'Cross-region CodePipelines'). This relies on creating sub-stacks in the target region with defined buckets for replicating the assets:

private createSupportResourcesForRegion(otherStack: Stack | undefined, actionRegion: string):


This is a 🚀 Feature Request

@njlynch njlynch added p2 feature-request A feature should be added or improved. @aws-cdk/aws-cloudfront Related to Amazon CloudFront @aws-cdk/aws-lambda Related to AWS Lambda effort/large Large work item – several weeks of effort labels Aug 20, 2020
@njlynch njlynch self-assigned this Aug 20, 2020
@robertd
Copy link
Contributor

robertd commented Aug 20, 2020

@njlynch This might be premature to ask right now, but would it be possible to handle Lambda@Edge scenarios where experimenting with it (especially renaming/deleting) causes stack deployments to fail due to the nature of lambda@edge versioning? Due to this we've elected to move out L@E into separate stack/repo (that and region issue of course)... Same goes for ACM :).

image

Note: I've noticed this by using aws-solutions-construct library which currently uses older version of the aws-cloudfront constructs (awslabs/aws-solutions-constructs#39). Also, aws-solutions-constructs doesn't do multi-region deployments for their aws-cloudfront-s3 solution (everything goes into us-east-1). Thus, this issue is something I'm excited to see in action (and it hopefully trickles down to aws-cloudfront-solutions repo at some point). 👍

@njlynch njlynch added p1 and removed p2 labels Sep 14, 2020
njlynch added a commit that referenced this issue Sep 23, 2020
DRAFT PR - Looking for early-stages feedback

This PR creates a construct (`EdgeFunction`) for Lambda@Edge functions.
CloudFront requires that a function be in us-east-1 to be used with Lambda@Edge,
even if the logical distribution is created via another region. The initial goal
of this construct is to make it easier to request and work with a function in
us-east-1 when the primary stack is in another region.

In the future, this can be extended to validate other Lambda@Edge restrictions.
See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-requirements-limits.html
and #9833 for more information on those limitations.

DRAFT -- What exists does work and has been successfully deployed with a
CloudFront distribution based in eu-west-1, but all of the normal Lambda
functionality (e.g., permissions) has not been verified to work yet.

Some open questions:
1. Where does this belong? There are circular dependency issues with
  `custom-resources` that prevents this from being in `aws-lambda`.
  `aws-cloudfront` seems possibly the next-best thing, but I can also see an
  argument for moving this into its own module.
2. Does this approach (creating a new stack and using SSM + an AWS custom
  resource) make sense, or should another approach be taken?
3. I intentionally didn't extend from `FunctionBase` in order to override most
  of the methods there to redirect to the delegate function; it's not clear (yet)
  that this will work and/or is a good idea. Feedback welcome.

Thanks to @asterikx for the inspiration and consolidated writeup in #1575.

fixes #9862
@SomayaB SomayaB added the in-progress This issue is being actively worked on. label Sep 23, 2020
njlynch added a commit that referenced this issue Oct 6, 2020
DRAFT PR - Looking for early-stages feedback

This PR creates a construct (`EdgeFunction`) for Lambda@Edge functions.
CloudFront requires that a function be in us-east-1 to be used with Lambda@Edge,
even if the logical distribution is created via another region. The initial goal
of this construct is to make it easier to request and work with a function in
us-east-1 when the primary stack is in another region.

In the future, this can be extended to validate other Lambda@Edge restrictions.
See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-requirements-limits.html
and #9833 for more information on those limitations.

Some open questions:
1. Is there a more clever way to "refresh" the SSM parameter reader when the
   underlying function changes?
2. How to make this and `edgeArn` play nicely together?

Thanks to @asterikx for the inspiration and consolidated writeup in #1575.

fixes #9862
njlynch added a commit that referenced this issue Oct 14, 2020
DRAFT PR - Looking for early-stages feedback

This PR creates a construct (`EdgeFunction`) for Lambda@Edge functions.
CloudFront requires that a function be in us-east-1 to be used with Lambda@Edge,
even if the logical distribution is created via another region. The initial goal
of this construct is to make it easier to request and work with a function in
us-east-1 when the primary stack is in another region.

In the future, this can be extended to validate other Lambda@Edge restrictions.
See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-requirements-limits.html
and #9833 for more information on those limitations.

Some open questions:
1. Is there a more clever way to "refresh" the SSM parameter reader when the
   underlying function changes?
2. How to make this and `edgeArn` play nicely together?

Thanks to @asterikx for the inspiration and consolidated writeup in #1575.

fixes #9862
njlynch added a commit that referenced this issue Oct 14, 2020
DRAFT PR - Looking for early-stages feedback

This PR creates a construct (`EdgeFunction`) for Lambda@Edge functions.
CloudFront requires that a function be in us-east-1 to be used with Lambda@Edge,
even if the logical distribution is created via another region. The initial goal
of this construct is to make it easier to request and work with a function in
us-east-1 when the primary stack is in another region.

In the future, this can be extended to validate other Lambda@Edge restrictions.
See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-requirements-limits.html
and #9833 for more information on those limitations.

Some open questions:
1. Is there a more clever way to "refresh" the SSM parameter reader when the
   underlying function changes?
2. How to make this and `edgeArn` play nicely together?

Thanks to @asterikx for the inspiration and consolidated writeup in #1575.

fixes #9862
@jbaileyashe
Copy link

@robertd did you ever find a workaround for dealing with Lambda@Edge functions? Waiting 24 hours to try and destroy again is pretty painful.

A hack that would work is for the Lambda@Edge API to return a 200/204 when you try to delete a replicated function. CloudFront is going to delete it automatically anyways, so why give the user a spurious error?

I posted a forum thread, if anyone would like to show support for the idea: https://forums.aws.amazon.com/thread.jspa?threadID=331402

@robertd
Copy link
Contributor

robertd commented Nov 18, 2020

@jbaileyashe Unfortunately no. We have name suffix randomizer component added to our Lambda@Edge functions so that each time we make change new function is deployed (rather than changed/deleted) and associated to our CF distro. Then we clean them up later on through scheduled task thru Gitlab CI/CD.

Edit:

https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-edge-delete-replicas.html and https://aws.amazon.com/blogs/networking-and-content-delivery/managing-lambdaedge-and-cloudfront-deployments-by-using-a-ci-cd-pipeline/

If you delete the stack, you’ll get a DELETE_FAILED error. This happens because, when you delete the stack, CloudFormation tries to delete the master Lambda@Edge function. But the master Lambda Function can only be deleted after CloudFront removes all of the Lambda@Edge replicas, which can take hours. So wait a few hours, and then try again to delete the stack, and then it will work.

@nihakue
Copy link

nihakue commented Nov 25, 2020

Our teams have also had success with a custom resource provider that creates the source code s3 bucket and lambda function using the aws sdk. It's a bit ick, but it lets you keep everything in one stack. I can't share code, but basically:

  1. create a bucket in the region to want to deploy to and put the lambda source code in it (can be done with normal constructs)
  2. Create a custom resource that:
    a. create a bucket in us-east-1
    b. copies source from bucket in your region to us-east-1
    c. creates lambda in us-east-1
    d. returns created lambda version/arn

I'm glad this problem is being addressed since it's been a huge pita for us, but are you also putting pressure on the Lambda@Edge / ACM teams to remove this constraint?

@mergify mergify bot closed this as completed in #10500 Nov 25, 2020
mergify bot pushed a commit that referenced this issue Nov 25, 2020
This PR creates a construct (`EdgeFunction`) for Lambda@Edge functions.
CloudFront requires that a function be in us-east-1 to be used with Lambda@Edge,
even if the logical distribution is created via another region. The initial goal
of this construct is to make it easier to request and work with a function in
us-east-1 when the primary stack is in another region.

In the future, this can be extended to validate other Lambda@Edge restrictions.
See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-requirements-limits.html
and #9833 for more information on those limitations.

Thanks to @asterikx for the inspiration and consolidated writeup in #1575.

Related changes:
* When updating the CloudFront README, I noticed that the `Distribution` sub-section hadn't been updated when it was flipped from Experimental to Dev Preview.
* A minor docstring fix for Lambda.

fixes #9862


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@github-actions
Copy link

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-cloudfront Related to Amazon CloudFront @aws-cdk/aws-lambda Related to AWS Lambda effort/large Large work item – several weeks of effort feature-request A feature should be added or improved. in-progress This issue is being actively worked on. p1
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants