26th september 2019

Static website URL optimisation with AWS serverless

We created a serverless application and published it on AWS's Serverless Repository to optimise static websites and properly redirect trailing URL slashes.

Introduction

Static websites are great, but...

At Si Novi we love the performance and security of static websites hosted on AWS S3 and CloudFront. However, unlike the working mechanisms of more traditional Linux-based Apache web servers, static website infrastructure deployed with S3 and CloudFront doesn't supply some some key features by default - such as automatic redirection of trailing slashes in a URL. This can cause confusion for users when they unexpectedly run into missing pages and 404 errors, and can have a negative impact on your website SEO.

We created a serverless solution using Node.js and AWS Lambda@Edge, hosted within the AWS Serverless Repository, which we now use to optimise the URL redirection on all our static website deployments.

Screenshot of Si Novi's Serverless Application for Static website URL optimisation

serverless solution

Using Node.js and Lambda@Edge to optimise static website delivery

We realised that the best way to solve the trailing slash redirection issue on S3 & CloudFront websites was by using Lambda@Edge - AWS's serverless Lambda service, running at edge locations around the globe.

A simple NodeJS script, deployed as a Lambda@Edge process, parses the incoming request from a user's browser. If it detects a trailing slash, it responds with HTTP 301 redirect to the same URL, minus the slash on the end. The script also preserves any query string parameters. The user's browser then makes the redirect to the non-slash URL which passes through the Lambda@Edge process untampered, and retrieves the data from CloudFront or S3 as normal.

Rather than writing the NodeJS script, storing it privately in Github and deploying it manually to each of our static website accounts, we decided to use the AWS Serverless Application Respository, which is a library of useful serverless applications built by AWS and third-party software vendors. The AWS Serverless Repo allows anyone using AWS to deploy ready-made serverless applications into their own AWS infrastructure.

The Serverless Application Model

The AWS Serverless Repository uses AWS's own Serverless Application Model (SAM) format to package the applications and define their deployment settings. In the YAML SAM file for our serverless application we defined the Node runtime, handler and other runtime properties for our Lambda function, including the path to the source files within the package.


AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: SAM configuration for creating a Lambda@Edge function to remove trailing slashes from CloudFront requests
Resources:
    LambdaEdgeRemoveTrailingSlash:
        Type: 'AWS::Serverless::Function'
        Properties:
        Handler: index.handler
        Runtime: nodejs8.10
        CodeUri: src/
        Role: !GetAtt LambdaEdgeRemoveTrailingSlashRole.Arn
        Description: 'A Lambda@Edge function to remove trailing slashes from CloudFront requests'
        MemorySize: 128
        Timeout: 3
        AutoPublishAlias: live
            ...
                

Publishing to and deploying an application from the AWS Serverless Repository

As the author of a serverless app, you first publish your application to the AWS Serverless Repo using either the CLI or AWS Console (AWS Documentation here). Initially your app is private, and only available to the same AWS account, or other specific accounts you nominate. This is useful for testing the deployment and running of your application before releasing it publicly.

Once an application is public in the AWS Serverless Repository, it can be deployed into your AWS account by clicking the Deploy button in the repo, which will then launch the package in CloudFormation and build the application into your Lambda applications in the US-East-1 (N. Virginia) region. From there you can then deploy the Lambda function as a Lambda@Edge process and choose which CloudFront distribution you'd like to associate the function with.

A small gotcha in the AWS Serverless Repo is that functions that require IAM Role creation get sort of quarantined behind a checkbox which requires the user to deliberately Show apps that create custom IAM roles or resource policies. I mean fair enough - an app could be requesting all sorts of IAM permissions, however our app keeps it simple - only requesting standard Lambda function basic execution permissions and also setting up the Trust Relationship required to publish the Lambda function onto Lambda@Edge. It's a good idea to review the permissions of a serverless function to make sure you're happy with what it's provisioned in IAM.


See our app on the AWS Serverless Repo: https://serverlessrepo.aws.amazon.com/applications/arn:aws:serverlessrepo:us-east-1:951661612909:applications~LambdaEdgeRemoveTrailingSlash

Find out more at the Github repo: https://github.com/sinovi/lambda-edge-remove-trailing-slash

Do you have any thoughts on this article? Get in touch: hello@sinovi.uk

about the author

Martin Hicks

Martin is an experienced developer and technology business owner - excelling in producing mobile and web applications for over a decade. In past five years, Martin has become a keen disciple of the serverless and cloud computing movement, and is considered an expert architect in AWS cloud environments - designing and deploying resilient infrastructure to support a range of complex workloads.

contact us

We're here to help

Talk to us today about agile software development. We operate as an outsourced technology partner for businesses - building, hosting and maintaining web and mobile applications with trusted web technologies such as PHP, MySQL, JavaScript, NodeJS and React.

Discuss your next project