Deploying a static site using AWS S3, Cloudfront and Domain.com
Tags: aws, cloudfront, staticsite, tutorial
Published: 2023-04-08 20:02:22

As part of [The Cloud Resume Challenge](https://cloudresumechallenge.dev/), one of the tasks is pointing a custom domain to your static site in a CloudFront Distribution.

Like most devs, I probably registered more domains for myself than necessary, so I figured I could use one that I had registered from [Domain.com](https://domain.com).

_This guide assumes that you've already enabled Static website hosting for your S3 bucket, and that you also own a domain. Domains can be purchased through AWS Route53 or any third party provider. For this case, we'll focus on the config required for Domain.com._ 

### Why Cloudfront?

Now, even though your static site is accessible via the bucket website endpoint, typically something like `http://some-bucket-name.s3-website-us-east-1.amazonaws.com`, the problem list in the first four characters: your content is served over HTTP.

For best practices, you want to use [HTTPS](https://www.cloudflare.com/learning/ssl/what-is-https/), which is the secure version of HTTP. It uses encryption, and that's particularly important for sensitive information. There's really no reason to _not_ use it. 

**Cloudfront enables this!!**

>  _[Amazon CloudFront](https://aws.amazon.com/cloudfront/) is a content delivery network (CDN) service built for high performance, security, and developer convenience._

---

### Creating a Distribution

In CloudFront, you'll need to click **Create Distribution** and then:

- Set your Origin domain to point to your S3 bucket.
- Enter a name for the origin. This can be anything really, but you can leave it as the default name.
- Select the recommended Origin Access Control Settings for **Origin Access**. Once selected, you will need to:
- Create a control setting. Give it a name (or leave the default) and click Create. Once you do this, you will be warned that your bucket policy will need to be updated afterwards.

![Setting Origin and OAC](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pzkhdsq7bsoinv16n3mt.png)


- Head to the **Default root object** and set your default object, which should generally be `index.html`.
- Hit **Create Distribution**
- You should receive a prompt to copy your bucket policy, so be sure to do that and paste in the permissions for the respective S3 bucket!

![Create Distribution](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u1zosx26il18nw9oz81c.png)


At this point give your distribution some time to deploy. You can test if your website is accessible going to the _Distribution domain name_ under **General>Details**. Notice the URL for this now has **https**.

---


### Distribution Deployed

Once your new or existing distribution is deployed, here's where we can set up the custom domain. In this case we'll be using the **Alternate domain name (CNAME)**.

> _A Canonical Name or CNAME record is a type of DNS record that maps an alias name to a true or canonical domain name._

The **alias name** is the domain name that you registered, eg https://iowntoomanydomains.com.
The true/canonical domain name is that set up by Cloudfront, eg. https://d2r7ncgogp998k.cloudfront.net

For your custom domain name to work, you'll need to request an SSL certificate and add it to your distribution to verify that you are authorized to use the domain.

> _An SSL certificate is a digital certificate that authenticates a website's identity and enables an encrypted connection. SSL stands for Secure Sockets Layer, a security protocol that creates an encrypted link between a web server and a web browser._

If you've deployed to Vercel or Netlify before, this is automatically done for you. With AWS, it takes a little setting up:


---

### Requesting a Certificate

- Find your static site distribution in CloudFront and open it up.
- On the **General** tab, click on _Edit_ under Settings. 
- For **Alternate domain name (CNAME)**, click _Add item_ and add your domain name, eg `https://mynewdomain.com` and you can also add a second `https://www.mynewdomain.com` to ensure that your site is accessible with the `www.` in front of it.

![Adding domains](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cmpo0bvqfwhxh6df5sld.png)

- Next up, you'll need to click _Request Certificate_ which should take to you to the AWS Certificate Manager. 
- Select _Request a public certificate_ and click Next. 
- For fully qualified domain name(without any https), enter your domain as well as a version with www, eg. `mynewdomain.com` and `www.mynewdomain.com` so your site is accessible by either name.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7n3l10j5tfg9mewii2ho.png)

7. Use the recommended _DNS validation_ and leave the key algorithm as is.
8. Request the certificate!

Open up your new certificate and you'll notice that the Status says _Pending Validation_. Here's where you'll need to head over to your Domain.com account to validate your ownership. Keep the Certificate open because you're going to need the **CNAME name** and the **CNAME value**.

In your Domain.com account, select your domain and head over to _DNS & Nameservers > DNS Records_. Here you are going to click + to add a new DNS record.

![Certificate Manager](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zhpn6dps3j414pv9y5hm.png)

1. Copy the **CNAME name** and paste it into the _Name_ field. The form should automatically truncate it to the hexadecimal string starting with an underscore, eg `40c74073be244c16356efbfd43a6461e`.
_At the time of writing, there was some weird behaviour with the form in that I would have to hit spacebar and then backspace for proper input validation. Hopefully this gets sorted out._
2. Copy the **CNAME value** and paste it into the _Content_ field.
3. Set the _Type_ to **CNAME**.
4. Set the _TTL_ to 1/2 Hour (or any value really). 
5. Click _Add DNS_ and repeat for your second domain startng with `www`.


![Domain.com config](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hfi4r5cw4w1b9bx4ab9f.png)

_Now we wait while AWS and Domain.com validate your ownership. This can take a few minutes to hours, but once it's successful, the Status should update to **Issued**_


![Certificate Issued](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wgn5oes2afzrfrzuynqg.png)
---
### Almost There!!

Yeah, this is a bit of a process. We need to create two more DNS records in Domain.com. The first records were primarily to validate ownership. This time, we're actually going to direct the custom domain name to the CloudFront domain, and this will not work till the certificates are issued.

1.  Head back over the CloudFront and grab the distribution Domain.
2. Get back to Domain.com to Add a DNS record
3. This time give it the name `@` and set the content to your distribution domain without the https, eg `d2r7ncgogp998k.cloudfront.net`.
4. Set the type to **CNAME* and once more a TTL to 1/2 hour.
5. Do this once more using the same content, but instead enter the name as `www`.

![Domain.com config](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wurgtrdj89x2rnacb87l.png)



Give it some time (minutes to hours) and with that, your static site should be available via your custom domain.

For your hard work, give yourself a pat on the back, and take a break from the screen!!