How To Host a Serverless Website with AWS CloudFront and S3

If you want to run a website on AWS, you may not even need a server! AWS’s CloudFront CDN can serve static web content directly from an S3 bucket, leaving you paying only for requests and data transferred (which might even be free).

How Does Serverless Hosting Work?

“Serverless” is the concept of running applications without managing dedicated Linux servers yourself, usually with a Platform-as-a-Service solution like AWS’s App Runner or Lambda Functions. While you may run a normal application like NGINX on an EC2 virtual machine, you can usually serve the same kind of app without running servers.

This particular serverless solution uses AWS’s Simple Storage Service (S3) to host the static content for a website, rather than having to serve it from an NGINX server yourself. “Static” just means that you’re serving files and not generating pages, which includes both simple HTML + CSS websites, as well as full client-side JavaScript web applications. Notably, this excludes server-side hosting frameworks like WordPress (PHP), Ruby on Rails, and ASP.NET, but many websites will be only static content.

The benefit to this solution is zero reliance on your own servers—S3 will always respond to requests, so you can have as many people as you want accessing your site. In front of S3, you can use CloudFront, AWS’s Content Delivery Network (CDN) solution. CloudFront runs hundreds of edge caches, which all cache requests to S3 for you, increasing latency & throughput, and lowering cost.

In this network setup, everything handling user requests is fully serverless. CloudFront servers are run by AWS and will automatically cache content and route users to the endpoint, which is simply an S3 bucket.

If you need to run some kind of backend or API for your web app to connect to, you can likely use other serverless tools like Lambda Functions to achieve that. This setup is even better, because requests to S3 and the API will scale separately.

If you’d like to learn more about using API Gateway as a frontend for Lambda Functions, you can read our guide on setting it up.

Despite how simple it is, this is actually a good enterprise-grade setup for hosting static content on AWS. It will be reliable, scale perfectly, and can even be used with a CodePipeline automatic deployment to update your site from its source files.

RELATED: How to Use AWS’s API Gateway as a Frontend for Lambda Functions

RELATED: How to Set Up an Automated Deployment Pipeline for an S3 Website

How Much Does This Cost?

Because serverless hosting scales exactly with usage, you only pay for what you use. This can save you a lot of money on servers that would otherwise be mostly idle. Generally, you’re going to pay a little more per CPU hour than compared to doing it yourself, but this is usually balanced by the fact that you’re charged fairly for exact usage.

However, there’s a good possibility this will just be free. AWS’s “always free tier” includes 100 GB of bandwidth, and an entire terabyte of CloudFront bandwidth. For comparison, most other free tiers from static site hosting services (like Github Pages and Firebase) will give you around 10 GB.

1 TB of bandwidth for free is certainly very nice, as it means most websites that aren’t serving tons of content will have a large buffer before being charged significant amounts.

You will still be charged for S3 requests though, which will add up, and if your site stores hundreds of GBs of content, you may also see high charges for that. Making effective use of CloudFront’s caching where possible can reduce the number of required requests to the origin (S3) however, and most sites will be fairly small.

Setting Up an S3 Bucket Static Website

To get started, head over to the S3 Management Console and create a new bucket. You must disable “Block Public Access” for it to be visible. AWS warns that this is a bad idea except for use cases like static website hosting. Because that’s exactly what we’re doing, you can ignore this, but you definitely won’t want to be uploading secrets to the bucket—it’s all going to be readable.

This just removes the block on it; you’ll also have to explicitly allow public reads with a bucket policy, under “Permissions.” Make sure to replace the resource name here with the correct bucket.

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

Next, you’ll need to upload your content. You can drag and drop, but if you’d like to transfer a whole folder manually, you can use the AWS CLI to sync an S3 bucket with a local directory. You can also set this bucket up as the output for a CodePipeline deployment, which can build your artifacts from the source repository.

RELATED: How to Install and Configure the AWS CLI

We’ll use the S3 API and upload a basic create-react-app template. Once synced, you’ll see the index.html in the S3 bucket.

aws s3 sync . s3://bucket-name

Before it’s ready, you will need to go to the bucket Properties, scroll to the bottom to find “Static Web Hosting,” and turn it on. You’ll need to configure the index and error document, and you can also write redirection rules here.

Once done, you’ll see the endpoint for the website under the properties.

Hooking Up a CloudFront CDN

CloudFront has a lot of options, but the default settings will work well for a simple S3 website, so configuration of it is fairly easy. Head over to the CloudFront console and create a new distribution.

You can configure the settings for the cache, but the default behavior should be fine for most people.

You’ll need to hook up your custom domain, and this involves creating an SSL certificate which is managed through AWS Certificate Manager (ACM). You can click this button to request a certificate, which may take a while to verify DNS if you’re not using AWS’s Route 53 DNS.

You will of course also need to configure your DNS with a CNAME record pointing towards the CloudFront endpoint.

Once your cert and DNS is configured, create the distribution, and wait about 15 minutes for CloudFront to deploy it. Once it’s done, you’ll be able to visit either the CloudFront endpoint or your custom domain, and see your site served from the S3 bucket.

s3 website test

You may also like...