Deploying static sites on AWS

  10 minute read

So I’m assuming you’re here, reading this guide, because you’ve finished writing your frontend application. If so, awesome! If not, fret not, we have a demo application you can use as a starting point.

AWS is complex, beautiful, yet sometimes sadistic (obviously I say that with love). One of my favorite features in AWS is the seamless integration between Cloudfront and S3. To top it off, using Cloudfront and S3 is the cheapest way to host your static site in AWS. And considering how cheap it is, the way that it propagates your application around the world and guarantees high availability it’s a steal.

Where do you even begin?

If you’re new to AWS or new to Cloudfront and S3, I’m going to walk you through the basics. So let’s get started!


We’re going into this walk through assuming you already have a Route53 Zone and an ACM Certificate configured in your account. No? Learn how to add a Route53 Zone and an ACM certificate

Preparing your S3 Bucket

To host your website, you’re going to need to store your built assets somewhere.

The first thing you’ll need to do is create your S3 bucket. You’re strongly encouraged to block public access so your bucket can’t be hijacked and abused by other people. Keep in mind when you name it, the name has to be unique across all AWS – so if you try naming your bucket something like “test-bucket” it probably won’t work.

Likewise, I also recommend encrypting all the things just to add another layer of protection. If you choose to encrypt your resources, ensure you do not encrypt your bucket with SSE-KMS because that will prevent Cloudfront from being able to read the resources.

Once your bucket is created you’ll need to add a S3 Bucket Policy. But more on that later.

Checkout the screenshots below for an example:

Setting up Cloudfront

Configuring the origin

When you hop over to Cloudfront in the console, create a new Cloudfront distribution. You’ll specify the origin domain name (which would be the DNS name that the S3 bucket we created was assigned). Cloudfront will provide you with a dropdown typeahead field to select the S3 bucket from.

Origin ID should be generated for you, as this is just the label we’re giving to name the Cloudfront Origin. You’ll also want to say yes to Restrict Bucket Access. When you say yes, some new fields will show up.

Origin access identity is essentially the key that Cloudfront uses to access S3 bucket objects and serve your site to the world. So we definitely need that. You can likely leave the generated comment as well. AWS actually makes the next part easy: If you choose the option “Yes, Update Bucket Policy”, AWS will configure the Bucket Policy for you and that simplifies things a bit.

If you keep on going through the form, you’ll get to the default cache behavior section. Basically this is the configuration that lets Cloudfront know how, what, and when to cache your objects but it also has a bunch of other nifty settings in it and we’ll go through that next.

Configuring the default cache behavior for Cloudfront

So, to say that using SSL (using the https a URL) is a normal thing nowadays would almost be as obvious as saying the sky is blue on a clear day. Because we want to keep our users and their information safe, we’re going to want to make sure that when the users arrive, they get redirected to a secure version of your site. To do this, you’ll want to set the View Protocol Policy to “Redirect HTTP to HTTPS”. So basically if a user shows up at http://my-awesome-site.example they’d get redirected to https://my-awesome-site.example.

For most static sites, you can leave the Allow HTTP Method as “GET, HEAD”.

Keep scrolling and you’ll get to a field called “Compress Objects Automatically” and there you’ll want to say “Yes” because it will help reduce the load time for your users.

Last few Cloudfront settings

You can probably leave the price class as is, as it’s not really that big of a difference in price.

So if you have the prerequisites mentioned above done, you can define a domain in the Alternate Domain Names field and you can select a SSL Certificate that corresponds with the domain you specified.

There is one setting in this section you’ll want to change and that’s the Default Root Object. Put index.html in that field (or whatever the default HTML page is going to be).

Scroll all the way to the bottom and click “Create Distribution”.

Here’s a few screenshots for reference:

Configuring Error Pages

Once your distribution is created click the Distribution ID and open up the distribution settings page. Click on the Error Pages tab.

We need to let Cloudfront know where to send traffic if there’s an issue loading something. So click the “Create Custom Error Response” button and let’s do this:

We need to configure error handling for two specific responses – 404 and 403. In both cases, we want the traffic to be sent to index.html with a 200 response code.

Configure DNS

Now that your infrastructure is up, we need to point your domain to the Cloudfront distribution.

Go into Route 53 and add a new record. You’ll need to set the record name to match the alternative domain name you specified in the Cloudfront config. From there, you will click the “Alias” toggle.

That will modify the form a bit. Under “Route traffic to” you’ll select “Alias to Cloudfront Distribution” in the first drop down then you’ll select the region you’re using and created the Cloudfront distribution in. From there, you’ll search and select the Cloudfront distribution that corresponds to the distribution we created.

Deploy your assets

Now that our infrastructure is built we can upload our code to the S3 bucket we created.

Go into the S3 bucket and click “Upload”. You can drag and drop all the files from your build folder into the browser. You’ll just want to ensure that your index.html is in the root of the bucket to match the Cloudfront config that we defined earlier.

Validate your application is up

That’s it. We’re done. You should be able to go to the domain you specified in the Alternate Domain Name field.

If we did everything right, you should see your application.

Deploying your site with Atomized

We took all the steps above and simplified them into one simple form with at most 7 fields to fill out.

You’ll define your application name, description, the Github organization, and the Github repo where your code lives.

Optional: If you want to attach your own domain, you can pick the Route 53 zone from a list. Once you select a hosted zone, you’ll select the ACM certificate that corresponds to the domain you want to assign the site to. Finally, you’ll enter in the full domain for the domain — just make sure it is a domain that is included in the ACM certificate.

Click the Deploy button and you’re done. We’ll start deploying the application and building out the infrastructure for you.

You’ll then be able to watch the deployment process live and it will turn out like this:

Start simplifying your CI/CD processes

Atomized helps developers deploy application infrastructure
without installing CLI tools or spinning up Kubernetes clusters

Atomized makes it easier to deploy your applications to your cloud

Funded by Y Combinator