Photo by Ibrahim Rifath on Unsplash

S3 is a great option to host a static website due to its simplicity and low cost. But if you want to use it for production, you need to connect the site to your custom domain, set up email forwarding, serve over https and other practical needs. This post describes in a concise way how to do all these so it takes no time to make your site live and serve its purpose.

Hosting on S3

The first thing to do is to put your website on S3.

1. Create a bucket

You can use any name but it is recommended to use your domain/subdomain as bucket name.

2. Upload files to the bucket

3. Enable hosting

Go to Properties tab. Click on ‘Hosting static website’. The ‘Endpoint’ on top is the AWS default URL for your website. Select ‘use this bucket to host a website’ option, and put ‘index.html’ in Index Document. For SPA, you might also need to put index.html in the Error Document for routing.

4. Set up Bucket Policy

Your content needs to be publicly readable for people to see the website. Go to Permissions tag and click Bucket Policy. Then add a template like this:

Just replace [bucket-name] to be the actual name of your bucket.

5. Test website

Lastly, hit the endpoint url and make sure if you can see the site correctly.

Serve reliably over HTTPS

Simply serve over S3 is not enough. We want to offer consistent delivery to your audiences all around the world with secure connection. AWS CloudFront service can help us do these with a breeze.

1. Setup CloudFront

Go to CloudFront, click ‘Create Distribution’, and select ‘Web’. You will see a page asking you to put various settings for your distribution.

CloudFront distribution setting.

In Origin Settings, put your S3 website url to ‘Origin Domain Name’ instead of selecting from the dropdown list when you click in the text box.

In Cache Behavior Settings, set ‘Viewer Protocol Policy’ to Redirect HTTP to HTTPS. CloudFront uses cache to store your files for efficient delivery without having to fetch them from original sources, e.g. S3 bucket. By default, the cache is refreshed every day (86400 seconds), if you want to change the behavior, find ‘Object Caching’ and select ‘Customize’ to change the TTL values.

Moving on to next section of Distribution Settings, by default, CloudFront provides us SSL Certificate already which will enable HTTPS automatically. For now, we will keep them as it is. A really important option to set is ‘Default Root Object’ which should be index.html for your site or any other file you use for the front page of your site.

That’s it, hit ‘Create Distribution’ button at the end and wait for it to finish.

2. Test CloudFront site

Once your distribution status becomes ‘Deployed’, test it by visiting cloudfront domain which is something like ‘abcd1234.cloudfront.net’. You should see your site as you see from S3 and it’s served with HTTPS.

You can always make changes to already created distributions by accessing from the CloudFront home page. One thing I want to point out is ‘Invalidations’. As we mentioned before, CloudFront cache refreshes periodically, let’s say you deployed a new version of the site and wants it to be delivered immediately, you can go to the Invalidations tab in a distribution, click ‘Create Invalidation’ and set Object Paths to all files (/*). After its status becomes Completed, your new content should be accessible.

Connect custom domain

Now You have your website hosted on S3, delivered by CloudFront and served over HTTPS. Lastly, let’s connect it to your own domain.

1. Transfer domain to Route 53

Assuming you already have purchased a domain from a domain registrar, be it GoDaddy, Google Domains or AWS Route 53. If you purchase it from Route 53, then you are all set. Otherwise, we need to transfer your domain to Route 53 to connect with CloudFront. I will use Google Domains as my registrar in this example, the steps are very similar for other domain services. Go to ‘Hosted zones’ under Route 53, click ‘Create Hosted Zone’, input ‘Domain Name’ and leave other fields untouched. The domain name is usually the root domain of your site, e.g. mydomain.com, which allows you to use any subdomain later on. Then, select the hosted zone you just created, you will see two records associated with your domain.

The NS is the name server record which is now pointing to AWS DNS address. Since our domain was registered under Google Domains, we need to change that. Go to Google Domains, in the ‘Name servers’ section, select ‘Use custom name servers’ and put the AWS NS record values in it.

2. Setup email forwarding

If you set up email forwarding in your Google Domains account, you can still do that even after transferring to AWS. In the ‘Synthetic records’ setting in Google Domains, find Email forwarding, expand it and you will see an MX type record. Copy all the Data values. Now, let’s go back to Route 53 and create a record set for your domain. As you have guessed it, we will create an MX type record. In the Value field, paste the ones you copied from Google Domains and hit ‘Create’. This way, you can still configure all email forwarding in Google Domains and it will work as usual.

3. Apply for certificate

If you still remember, when we created our CloudFront distribution, we used a default SSL certificate which is not tied to our own domain. To get one for our domain, go to AWS Certificate Manager, click ‘Request a certificate’. Add your domain names, e.g. testdomain.com and *.testdomain.com. This enables your root domain and all subdomains to use the same certificate. Next, you need to validate you actually own the domain. Either DNS or email validation can be used. If you use email validation, make sure there is a valid email address like admin@testdomain.com. Simply follow the instruction to validate and you are done. You can confirm by checking the status for your domain under certificates is ‘Issued’.

4. Connect to CloudFront

After you get the certificate, let’s go to CloudFront to use it. Enter the ‘General’ setting of your distribution, in ‘SSL Certificate’, click ‘Custom SSL Certificate’ and select the one you just created for your domain in the dropdown list. One more thing before you leave, add CNAMEs for your distribution. You can specify multiple domains if you want.

The last thing you need to do is to route queries for your domain to CloudFront distribution url. This is also very simple. Go to Route 53 and select your domain. Create a new record set for the domain you want to use, e.g. www.testdomain.com, set type to be ‘A — IPv4 address’ and Alias to be ‘Yes’. In the Alias Target, select the cloudfront distribution domain and create.

Give it a few minutes to setup. Finally, go visit your domain and you should see your site live.