Host a serverless static website with free SSL in 15 minutes.

In this guide, I will show you how to host a static website using AWS in a serverless manner.
The following AWS services will be used:

Simple Storage Service (S3)
Certificate Manager

Angular, Vue, and React apps can be compiled into static files that can be served from an S3 bucket. If you can provide these files, you can host a dynamic website from S3.
You will need an AWS account for this guide.
You will need a domain in Route53 for this guide.
It is possible to complete these steps with the SDK or by using Cloudformation.

Step 1 – Creating an S3 bucket.

We’ll be revisiting our S3 bucket later to upload files and adjust bucket policy.

Visit S3 in the AWS console.
Click on “Create Bucket" in the top-left corner.
Type in a name for your bucket. It has to be unique against all other S3 buckets.
Select your preferred region. This might be the one closest to you.
Click "Next" and you will see "Configure Options." Leave everything as default.
Click "Next" and you will see "Set Permissions." Again, leave everything as default.
Click "Next" and then click "Create Bucket."

We cannot proceed further until we create a Cloudfront distribution. Once we do, we can adjust the bucket policy to restrict access to the Cloudfront distribution we create.

Step 2 – Creating a Cloudfront distribution.

This is the resource that Route53 will access your static website from. It will draw the website’s files from your S3 bucket.

Visit Cloudfront in the AWS console.
Click "Create Distribution" in the top-left corner.
Under "Web," click "Get Started."
Click inside the "Origin Domain Name" input, and select your S3 bucket.
Click inside the "Origin ID" input, and enter your S3 bucket name.
Next to "Viewer Protocol Policy," select "Redirect HTTP to HTTPs."
Select which minimum, maximum, and default TTL makes sense for you. In default TTL, enter the number of seconds between each time Cloudfront looks at your S3 bucket, and caches changes you’ve made to your website. I use 86,400 seconds, or one day.
Next to "Price Class," select which edge locations you want to support. It is more expensive to use more edge locations.
You can specify an alternate domain name such as ""
Next to "SSL Certificate," select "Custom SSL Certificate" and then click "Request or Import a Certificate with ACM." This will open the Certificate Manager in a new tab.

Leave the Cloudfront tab open. We will be returning to it shortly.

Step 3 – Requesting an SSL certificate.

You should be in the certificate manager, with the Cloudfront distribution setup in another tab.
Please ensure that your domain is in Route53, and the registrant contact is an email you can access.

Type in your domain name under "Domain name."
Click "Next" and the select "Email Validation." This is typically the easiest method.
Click "Review" and then "Confirm and Request."
Go to your email and then confirm the request.
Your certificate should say "Validation status" as "success."
Copy your certificate ARN.

You have created a valid certificate. Close this tab, and switch back to the Cloudfront setup.

Step 4 – Finishing Cloudfront setup.

You are adding the certificate you just created to your in-progress Cloudfront distribution.

In the field under "Custom SSL Certificate," paste in your ARN.
Leave the remaining options as default, and select "Create Distribution."
When your distribution state is "Enabled," select "Origin Access Identity" on the leftmost column.
Select "Create Origin Access Identity," at the top-left corner.
Your comment should be the name of your S3 bucket.
Click "Create" and then copy the ID column for the identity you just created.
Return to S3.

Next we will upload your static files to S3 and add a bucket policy to allow secure reads from Cloudfront.

Step 5 – Uploading to S3 and adjusting bucket policy.

You should be in your S3 bucket again.

Select the "Permissions" tab on your bucket.
Select the "Bucket Policy" button.
Paste the following bucket policy in. You need to change the XXXXXXX to your Origin Access Identity.

"Version": "2012-10-17",
"Statement": [
"Sid": "2",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXXXXX"
"Action": "s3:GetObject",
"Resource": "*"

Click "Save" and return to the "Overview" tab.
Upload all of your static files and folders.
Go to Route53.

The last step is to resolve your domain to your Cloudfront distribution.

Step 6 – Resolving your domain to Cloudfront

You should be in Route53. If you haven’t created a hosted zone for your domain, here are the steps:

Click the "Create Hosted Zone" button in the top-left.
Enter your domain name without www or http.
Enter the name of your website in the "comment" input.
Click "Create."
Click "Create Record Set."
The name is "www"
The type is CNAME.
The value is your domain without the www or http.
Click "Save Record Set."
Click "Create Record Set" again.
The name is blank.
The type is "A"
Select "Yes" next to "Alias."
Next to "Alias Target" select your Cloudfront distribution.
Select "Create Record Set."

In 1-2 minutes, open a new tab, and see if your domain resolves with and without www to your static website. If it does not, check that you did the steps correctly. If it still does not work, leave a comment below the post.
I couldn’t figure out how to end a code block in markdown. I was using to check and the code block escapes when I put a triple backtic. Not here it seems. I’ve reached out to on Twitter, and there will hopefully be an answer.
I hope this helps whoever was looking for a cheap way to host a secure, serverless, and static website.
Thank you.