Using AWS Lambda@Edge on Cloudfront
I’ve been attempting to learn more about Lambda@Edge and how to use functions at the AWS edge locations, so I wrote up this demo. It isn’t performing a very realistic operation, but it did allow me to understand the Lambda@Edge and Cloudfront cache relationship (aka “event model”) and how to intercept CDN cache requests and modify responses in a Lambda function.
The repository is at https://github.com/mbacchi/lambda-edge-cloudfront-terraform.
All the instructions for deploying the Terraform and uploading the html/js files to the S3 bucket are in the README.md. Follow those instructions to deploy using Terraform.
NOTE: Deploying can take 5 minutes in order to replicate the CloudFront distribution to all AWS edge locations.
The below steps are possible only after deploying all the AWS resources via Terraform and placing the html/js files in the S3 bucket.
The basic flow of the actions in this demo are:
- The CloudFront distribution sits in front of an S3 bucket which hosts the
- When the Submit butten is pressed, the
index.htmlpage passes the querystring to the CloudFront distribution
viewer_request.pyLambda function associated with the CloudFront distribution intercepts the request before the cache performs the lookup. In the function we perform a 302 redirect to the 2nd html page
other.html, with the same query string as passed by the
- As the response is sent to the viewer, the
origin_response.pyLambda function adds the
content-security-policythat allows the
other.pypage to execute scripts in the CloudFront distribution domain, and allows github.com to be used to connect via an API call (also known as the connect source), all on the fly by adding HTTP headers to the response.
- When loaded on the viewer’s web browser, the
other.htmlpage makes the API call in
script.jswith the query string, and the async await function loads the response into the DOM when the API query returns.
The below diagram (from the AWS documentation) explains how the request from and response to the viewer can be modified before or after the cache.
In our example we will use the viewer request and origin response points of this diagram to execute our Lambda functions and modify the request/response.
Request and Response
The viewer_request.py Lambda
first looks at the request and identifies if the referrer URI includes the string
index.html. If so it redirects to the CloudFront distribution domain name,
appending the query string passed to the page.
As that redirect is handled it goes to the cache (and possibly to the origin) to
get the 2nd html page, and in the
the Content Security Policy (i.e. CSP) is dynamically configured to allow the
CloudFront distribution domain name to execute scripts(
Finally when the
the querystring username provided to
index.html, and fills in the DOM with the
Logging and troubleshooting
The output of the Lambda@Edge function (we have multiple print statements) is
directed to AWS Cloudwatch just like any Lambda function. This allows us to take
a look at the output and either debug or use for general information. This is
going to be in the region that is closest to your user making the request, so in
my case I am in Colorado, and the edge location apparently is
You can also use the Chrome (or Brave) developer console to show errors when
making requests. Hit
Ctrl-Shift-I or use the browser menu to open the
Developer Tools and watch while you load the page.
This is all described in the README.md.
More help about CloudFront, Lambda@Edge and AWS can be found at these links:
- Using AWS Lambda with CloudFront Lambda@Edge
- Customizing Content at the Edge with Lambda@Edge
- Tutorial: Creating a Simple Lambda@Edge Function
- CloudFront Events That Can Trigger a Lambda Function
This was an interesting project to work on. CloudFront and Lambda@Edge appear quite useful now that I’ve learned the basics. Hope you got something out of this demo too.
In the original version of this post, I indicated that these deployments could take anywhere from 20-30 minutes. I’ve corrected this information because that has now changed.
The AWS CloudFront team has recently shared updated information about their deployment times. They have improved these deployments from 20-30 minutes to typically around 5 minutes.
This is a major improvement and makes it much easier to use.