I've been trying to deploy on AWS a Lambda Function as Lambda@Edge that is been
triggered by the Cloudfront event viewer-request.
In this Lambda@Edge function I would like to validate the api key I get in the
request header Authorization.
I need to run the function on the viewer-request because I cannot cache the
validation of the key since it can be revoked.
This is the diagram of the Cloudfront events:

I managed to deploy a Lambda@Edge function manually from the AWS Console, but now I would like do it programmatically.
I first tried using Serverless Framework. Serverless Framework supports Lambda@Edge but it doesn't support to attach the Lambda@Edge to an already deployed Cloudfront distribution.
I found a plugin that does that serverless-lambda-edge-pre-existing-cloudfront
After deploying the serverless lambda function, if I check the Cloudfront
distribution behaviour, I found the Lambda@Edge correctly configured and
attached to the correct event viewer-request.
However when I call the Cloudfront URL from the browser (or Postman) I am getting a 503 Error:
503 ERROR
The request could not be satisfied.
The Lambda function associated with the CloudFront distribution is invalid or doesn't have the required permissions. We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
Generated by cloudfront (CloudFront)
Request ID: **************************************
Then I also tried to deploy the Cloudfront distribution together with the Lambda with the Serverless Framework.
Then I also tried to deploy the Cloudfront distribution and the Lambda@Edge with Terraform, first trying to associate the Lambda to the Cloudfront event, and then also trying to deploy all together.
In all cases I am getting always the same error 503.
NOTE: If I select the event
origin-requestit doesn't give me the error.
The only way I managed to make it work is with the AWS Console. Going to the
Lambda Function > Versions > (Select last version) > Add trigger >
Select Cloudfront trigger > Configure new CloudFront trigger >
Select distribution > CloudFront event (viewer-request) >
Select **"Confirm deploy to Lambda@Edge"**

This is the most important part: Selecting "Confirm deploy to Lambda@Edge"
Only by selecting this, everything works.
So I tried to use AWS CLI to add the trigger and to confirm to deploy to Lambda@Edge.
However I found that is still not supported: [https://github.com/aws-cloudformation/cloudformation-coverage-roadmap/issues/953]
So I am thinking that since there is no API for this feature it cannot be done, not with Serverless, nor with Terraform or any other SDK.
I've been testing with a Lambda function that doesn't modify anything it just log the event. This is the code:
exports.handler = (event, _context, callback) => {
console.log('EVENT', event);
const request = event.Records[0].cf.request;
console.log('REQUEST', request);
callback(null, request);
}
These are the permission I gave to the Lambda with terraform syntax. I did the same also for Serverless:
data aws_iam_policy_document assume_role {
statement {
effect = "Allow"
principals {
type = "Service"
identifiers = [
"lambda.amazonaws.com",
"edgelambda.amazonaws.com"
]
}
actions = ["sts:AssumeRole"]
}
}
resource aws_iam_role iam_for_lambda {
name = "new_cloudfront_access_lambda"
assume_role_policy = data.aws_iam_policy_document.assume_role.json
inline_policy {
name = "my_inline_policy"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"lambda:InvokeFunction",
"lambda:GetFunction",
"lambda:EnableReplication*",
"iam:CreateServiceLinkedRole",
"cloudfront:UpdateDistribution",
]
Effect = "Allow"
Resource = "*"
},
]
})
}
}
My final question is
Does anybody ever succeeded to programmatically deploy a lambda function to
Lambda@Edge as viewer-request for a Cloudfront distribution?