AWS Serverless - CloudFront distribution with Lambda@Edge
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
edge
stack has a memory allocation of 128MB max. Serverless default is 1024MBThe
edge
function must not have any enviroment variables. Watch out forserverless-plugin-dotenv
if you're using it.The
edge
function execution role must be assumable withedgelamda.amazonaws.com
besides the usuallambda.amazonaws.com
. Example:
{
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com",
"edgelambda.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
},
}