Search code examples
amazon-s3aws-cloudformationamazon-cloudfrontserverless-frameworkaws-lambda-edge

Lambda@Edge limitation to be deployed to us-east-1 prevents me from deploying S3 bucket to Europe


Update:

The short version of the issue that I wanted to cross-reference some values in different stacks in different regions but the documentations were so confusing to let me think it's not possible to do that but it's possible, just I had to output those values as exported values in that stack and then use: ${cf.us-east-1:another-stack.theNeededArn} in the other stack.


The Long version if you are interested:

I am maintaining the infrastructure code using a Serverless framework. I have CloudFront that connecting to an S3 bucket that hosted in Europe. I got a client request to limit access to this bucket through the CloudFront to be limited only to the authenticated users (custom auth). Lambda@Edge was the best solution and I already implemented it that way but because Lambda@Edge has to be deployed to us-east-1, I ended up moving the S3 and the Cloudfront to the same region us-east-1 (That's because Cloufront depends on the lambda edge and S3 depends on the CloudFront so I have to keep them in the same stack or at least the same region). But I don't want to move my bucket to the US for legal stuff and I want to keep the data in Europe, Also my S3 has a lambda trigger function that listens to it and writes some data to a DynamoDb hosted in Europe.

So The problem: I had S3 in Europe and I want to keep it in Europe but due to using lambda edge and because that the cloud formation or the serverless doesn't support a cross-region stack reference I ended up moving this S3 to the US but that's not the requirements!

  • I think even though we use the cloud front but having all of our customers in Europe and putting the S3 bucket in the US will increase the latency.
  • For legal stuff, I want to keep the European user's data inside Europe and not move it outside.

Here in this question's answer, I specified my approach and the full code example in case you are interested: How to access AWS CloudFront that connected with S3 Bucket via Bearer token of a specific user (JWT Custom Auth)

Any Suggestions?


Update (Steps to show the exact problem):

  1. In my serverless.yml, I created this stack contains this lambda edge:

Serverless.yml

I didn't want to configure lambda edge using a serverless framework but instead, I used cloud formation to configure the cloud front and everything.

  1. In the cloud formation resources file, I added the cloud front origins and configure the private origin through its behavior to use the lambda edge (Please check the highlights in the picture):

Cloudfront configs Please note that now I am using the lambda edge ARN inside my Cloudfront so they need to be in the same region and because lambda@edge should be in us-east-1 so I decided to move the CloudFront to the same region and that does not really matter cause it has edge behavior by design.

  1. Als if you are interested here I defined all the needed roles for the predefined lambda edge in the step.1 (And that includes publishing the correct policies and also the lambda edge version as in lambda edge, you have to reference the version, not the function and all set in this step I just put it here for completeness.):

Lambda Edge Configs

  1. Now I have the cloud front configuration, lambda edge configuration, and in the cloud front, we are referencing the lambda edge ARN which leads me to put them in the same region but now I will define my S3 bucket and will make it private so no one can access it, just the cloud front CloudFrontOriginAccessIdentity can do that:

The Bucket configs

As you may see in the role I just gave access to CloudFront to get and gave access to the (lambda edge to get and put but not sure if that's correct) but anyways even if we need the CloudFrontOriginAccessIdentity only to be connected to my bucket so now the bucket linked with my CloudFront which is also linked to the lambda edge so I can't separate them to put the S3 in Europe only??

And by that even if I have an S3 trigger lambda function so I should put this function in the US even if this function is doing some stuff related to DynamoDb in Europe? So what is the point? Also even if the Cloudfront is edged but the bucket is regional so if I really need to process some data related to it that means by putting it in us I increased the latency? So that's my full detailed problem.


Update2: I wanted to post the code as screenshots so I can highlight some lines and make it easier but for whom interested to check the code itself, I already posted the full version of it in my answer to this question here: How to access AWS CloudFront that connected with S3 Bucket via Bearer token of a specific user (JWT Custom Auth)


Solution

  • The solution was instead of moving everything over to us-east-1, just maintain two stacks which are the primary stack and the lambda edge stack. The primary stack resides in EU and the lambda edge stack resides in us-east-1. You can reference the lambda edge functions in us-east-1 by using ${cf.us-east-1:another-stack.lambdaEdgeArn}.