Rewrite URLs using CloudFront and Lambda@Edge

Static websites can be hosted in S3, however, there it cannot be used to rewrite urls. Rewriting urls is necessary when clean urls need to be displayed to the user. Also, when used with CloudFront, the static website cannot have the default file on the subdirectory level. For example, the file "index.html" on the subdirectory level will not be served by CloudFront when the site is hosted in S3. Lambda@Edge can be used to overcome this problem.

What is Lambda@Edge

Lambda@Edge is an extension of Lambda that can run code on the CloudFront's Edge locations. It is optimised for latency. Currently, there is a limitation that the code needs to be written using NodeJS and needs to be deployed in us-east-1 region.

The Url Rewriter Function

The rewriter function is a simple NodeJS function. It checks for the request url and if the path ends with a '/', then it rewrites to the 'index.html' file. The redirected url is not visible to end user. Here's the code for url redirection.

  

        'use strict';
        exports.handler = (event, context, callback) => {
            
            // Get request from CloudFront event  
            var request = event.Records[0].cf.request;
        
            // Extract the URI from the request
            var requestUrl = request.uri;
        
            // Match url ending with '/' and replace with /index.html
            var redirectUrl = requestUrl.replace(/\/$/, '\/index.html');
            
            // Replace the received URI with the URI that includes the index page
            request.uri = redirectUrl;
            
            // Return to CloudFront
            return callback(null, request);
        };

    

Deploying Lambda@Edge Function

There are certain specific rules that need to be for deploying a Lambda@Edge function. The rules are slightly different from deploying the usual Lambda function.

  • The function needs to be deployed in us-east-1 region (North Virginia).
  • CloudFront needs to be selected as the trigger on origin-request event
  • An IAM role needs to be created. Easiest is to create from within the Lamnda console using "Create new role from template" and choosing using the "Basic Edge Lambda permissions" policy template. This will add all necessary permissions.
  • A version needs to be created for the Lambda function. CloudFront cannot talk to the "$Latest" version.

The above settings will allow the lambda function to run on the CloudFront'e edge location and will rewrite the url to support default url functionality.