Recently I had the task to add a CloudFront distribution with a Lambda@Edge function as an autorization mechanism into an existing Serverless stack. All nice and dandy since Serverless already supports Lambda@Edge. The only problem is that if your stack is in other region than
us-east-1 you're out of luck. Lambda@Edge, while it's present in all the edge locations, it must be deployed in us-east-1.So you'll have to split the stack. Splitting it also solves another issue that I encountered, the CloudFront
LambdaFunctionAssociations requirement that you must specify a Lambda function version ARN. The param ${yourFunctionName}LambdaFunctionQualifiedArn is being exported as an Output from your CloudFormation stack by default by Serverless so you don't have to change anything there.Splitting the stack
I just created another
serverless.json named serverless.edge.json that has just the authorization function and it's set for us-east-1 region. Not perfect but you can avoid multiple commands to deploy your things with one package.json script since serverless is smart enough to not do a full deploy if nothing changed.{
"scripts": {
"deploy:dev": "sls deploy --stage dev --aws-profile X",
"deploy-edge:dev": "sls deploy -c serverless.edge.json --stage dev --aws-profile X",
"deploy-all:dev": "yarn deploy-edge:dev && yarn deploy:dev"
},
}Then referencing the Lambda function from the US region into my EU stack was just as simple as this
{
"LambdaFunctionAssociations": [
{
"EventType": "viewer-request",
"LambdaFunctionARN": "${cf.us-east-1:YOUR_US_STACK_NAME-${self:custom.currentStage}.YOUR_FUNCTION_NAMELambdaFunctionQualifiedArn}"
}
}Keep in mind that the
FunctionQualifiedArn is pointing to a function's version, so if you deploy an update to that function you'll have to redeploy the main stack as well.Other limitations to consider for Lambda@Edge
- Make sure your
edgestack has a memory allocation of 128MB max. Serverless default is 1024MB - The
edgefunction must not have any enviroment variables. Watch out forserverless-plugin-dotenvif you're using it. - The
edgefunction execution role must be assumable withedgelamda.amazonaws.combesides the usuallambda.amazonaws.com. Example:
{
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com",
"edgelambda.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
},
}

