Serverless Front-end

  • Daniel Pedroso
  • January 24, 2019

Background

When I first started to get into serverless architecture, my first question was “What about the front-end?”.

Well, the truth is, unless you require server-side rendering, your front-end is naturally just a bunch of static assets.
Sure, it doesn’t sound that static considering it’s a whole application (in many cases nowadays, your front-end is even more complex than your backend!), but most applications are a collection of:

So, all you need is a static host!

S3 to the rescue

It’s only now starting to become common knowledge, but S3 has been an option for static website hosting for a long time. Here’s how you can do it:

Create a bucket

I usually use the final address for my website as the bucket name. This very blog you’re looking at comes from an S3 bucket named www.danielpedroso.com.
You can create the bucket either via the AWS Console or using the AWS CLI:

  aws s3 mb s3://www.mywebsite.com

Enable Static Website Hosting

In the console, navigate to S3 > your bucket > Properties.
Enable the Static website hosting option, setting both the index and error documents to your index.html page.

Make the bucket publicly available (for reading)

You’ll need the following policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::www.mywebsite.com/*"
        }
    ]
}

Upload your application

This is the exact script I use in CodePipelines to deploy one of my React apps:

  npm run build

  # Upload all files
  aws s3 sync ./build s3://${DeployBucket}

  # Ensure the index.html page won't be cached
  aws s3 cp --acl public-read --cache-control="max-age=0, no-cache, no-store, must-revalidate" ./build/index.html s3://${DeployBucket}/

  # Invalidate the CloudFront cache
  aws cloudfront create-invalidation --distribution-id ${DistributionID} --paths /index.html

Now, as you can see, I’m using a CloudFront distribution. This next step is completely optional!

CloudFront distribution (optional)

If you want an extra performance boost, you’ll want to add a CloudFront distribution on top of your S3 bucket.

Create distribution

This step is straightforward: in the AWS Console, go to CloudFront > Create Distribution.

Select “Web” as the delivery method

Origin settings

Select your S3 bucket from the list

Default cache behaviour

This step is not mandatory, but I like to select Redirect HTTP to HTTPS and Compress objects automatically.

Distribution settings

Here comes the big gotcha - you need to make sure you select your alternate domain names here.
Explaining: by default, your CloudFront distribution is served via a different domain (something like d111111abcdef8.cloudfront.net).
To use your custom domain, you’ll need to set all the alternate CNAMES here.
If you’re using HTTPS, you’ll also need to choose your SSL certificate.
IMPORTANT: The certificate needs to be created in the us-east-1 region!

It’ll take up to 40 minutes for your distribution to be deployed.
Once ready, you can setup the DNS records.

DNS settings

Assuming you already have your Hosted Zone setup in Route 53, you’ll need a new record set.
Navigate to Route 53 > Hosted Zones > your-domain.com, then click Create Record Set

In this new form, choose the following:
Name: Leave blank (add another record with www for this value, too)
Type: A
Alias: Yes
Alias Target: Select your CloudFront distribution

Wait for your DNS to propagate, and that’s it - done!

What if I need access to environment variables or need to inject Correlation IDs?

You can check out these posts: