Host a secure website in S3 using your own custom domain — Part I
Tags: aws, devops, webdev, tutorial
Published: 2020-05-17 06:27:47

**Fact:** Studies show that developers hosting their sites in S3 are healthier, wealthier and have better hair than their peers.

If you weren’t convinced by the above then at least know that the combination of Amazon S3 and CloudFront offers a simple, cheap and performant way to host static sites and serve them over https. In this two-part series, we’ll spend a little time going over the steps required to get your site live and using a custom domain. We’ll cover the following:

- **Part I** — Configuring an S3 bucket and CloudFront distribution to host and deliver your content.
- **Part II** — Transferring your domain to Amazon Route 53 and configuring an SSL certificate using Amazon Certificate Manager.

Each part will be pretty short — so don’t be put off by the breakdown above — the whole series can be completed in well under an hour.

For the purposes of this guide, I’m going to use a _.tech_ domain I purchased from GoDaddy. I decided to go with _connectr.tech_ as it was cheap, relatively non-specific and sufficiently hipster to be used in a dev.to article 🧐

#### Part IA— Creating and configuring an S3 bucket to host your site
- Login to the AWS console and navigate to the [S3 bucket creation page](https://s3.console.aws.amazon.com/s3/bucket/create).
- Create a new bucket e.g. _connectr-site_ and temporarily remove all public-access blocks as shown below<br>
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/5y2bb31au58wewr7imz9.png)<br>

- Select your newly created bucket and then head to _Properties : Static Website Hosting_ to configure the static hosting options.<br>
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/uacevk49im11he68dqnq.png)<br>
- Configure the _index_ and _error_ pages as _index.html_ and _error.html_. **You’ll also see the public endpoint of your soon-to-be site!**
- Copy the endpoint and open it up in another tab — you should receive a 403 (forbidden) response because the bucket policy has not yet been configured. To sort this out, go to the _Permissions_ tab (next to _Properties_) and add the following _Bucket Policy_ using the _Bucket Policy Editor_.<br>
{% gist https://gist.github.com/lukeojones/e1f565d0d270836cbfb65aa7f84cefb1 %}<br>
- Save the bucket policy and try hitting your new public endpoint again — this time you should receive a 404 as S3 tries to serve the non-existent index.html and error.html pages. This is what we want at this stage 👍
- Create an _index.html_ and _error.html_ file that you are happy to share with the world. For example, I created some ‘awesome’ pages below…<br>
{% gist https://gist.github.com/lukeojones/5bcec0524dfdd74446c6c1c49aa512cf %}<br>
- Whilst still in S3, select the _Overview_ tab and then upload the _error.html_ file to your S3 bucket. Make sure you provide public read access on the second page of the upload wizard before pressing _Upload_.<br>
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/5c3kkjfiuxbpmfshg21e.png)<br>
- Once the upload is finished, navigate to your site’s endpoint again and your custom error page should be displayed.<br>
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/is71l4vciln3l92evqa0.png)<br>
- Repeat the process for your _index.html_ — when you navigate to the site again, you should see your lovingly crafted html! (notice the connection is plain http and not secure)<br>
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/tocsfj059fed8bo6wju6.png)<br>
- Finally, to improve security and make sure we’re following best practices, we can lock down the bucket policy a little more. Head back to the _Permissions_ tab for your bucket and block public access for ACLs and new bucket policies as shown:<br>
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/p6cdsl9sgsfhnlswdf4z.png)<br>
- Double check you can still access your _index.html_ page and that’s it — you’re good to go.

#### Part IB— Configuring a CloudFront distribution for content delivery
To improve how your users access your content, you’ll want to make use of a CDN — in this case CloudFront — to distribute your content using a global network of proxy servers.
- In AWS, navigate to the CloudFront service and select _Create Distribution_ to get started. When asked to choose a delivery method, choose _Web_.
- Under _Origin Settings_ you should attach the S3 domain name that was created in Part IA e.g. _connectr-site.s3.amazonaws.com_ <br>
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/f5fhhs0tm0d7in2i98qh.png)<br>
- Secondly, you’ll want to redirect all _http_ traffic over _https_ by selecting Redirect _HTTP to HTTPS_ as the _Viewer Protocol Policy_ option<br>
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/55558mapto1mfg4eifbt.png)<br>
- Now set the _Default Root Object_ to _index.html_ (or whatever site root you may have decided to configure).<br>
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/lxlt4hly9pxl7gc8jy43.png)<br>
- Now, create the distribution and wait for it to show the status _Deployed_ in the Distributions overview table (this can take 5–10 minutes so find a cat video on Youtube). <br>
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/7aw24sdudk30nn2z1i6s.png)<br>

- Copy the CloudFront domain name e.g. _d32gg49xh8c4xx.cloudfront.net_ (catchy right?) and paste it into a new browser tab. If everything has gone to plan — you should see your lovingly crafted html again — this time served over the CloudFront CDN and transferred using the https protocol!<br>
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/j606lc3arkyxe1sbmj6o.png)<br>

And that’s it — you’re done for Part I. Hopefully that was relatively painless and you were able to follow along at a decent pace.<br>

In [Part II](https://dev.to/lukeojones/host-a-secure-website-in-s3-using-your-own-custom-domain-part-ii-44ia), I’ll go through the process of transferring your custom domain to Route 53, creating an individual SSL certificate and associating these both with the CloudFront distribution we’ve just created here.<br>

Good work! Grab a refreshing drink and smile smugly for a few minutes…<br>
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/onwtoyf5h6ippgizrpic.jpeg)