Host a serverless static website with free SSL in 15 minutes.
Tags: aws, cloudfront, ssl, simplestorageservice
Published: 2019-02-20 22:31:49

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)
- Route53
- Cloudfront
- 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.

It is easiest to have a domain in Route53 for this guide. If you do not, then go to your current registrar's DNS settings. Create a CNAME record with host 'www' and the Cloudfront URL as the target. When you request your certificate, make sure to specify your domain as *.yourdomain.com. Then add www and no www variants to your Cloudfront distribution's alternate domain names field.

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 adjust bucket policy.

1. Visit [S3](https://s3.console.aws.amazon.com/s3/home) in the AWS console. 
2. Click on "Create Bucket" in the top-left corner.
3. It is recommended that your S3 bucket name be the same as your domain. (yoursite.com) without the www or http.
4. Select your preferred region. This might be the one closest to you.
5. Click "Next" and you will see "Configure Options." Leave everything as default.
6. Click "Next" and you will see "Set Permissions." Again, leave everything as default.
7. Click "Next" and then click "Create Bucket."
8. Upload all of the static files and folders for your website.

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.

1. Visit [Cloudfront](https://console.aws.amazon.com/cloudfront/home) in the AWS console.
2. Click "Create Distribution" in the top-left corner.
3. Under "Web," click "Get Started."
4. Click inside the "Origin Domain Name" input, and select your S3 bucket.
5. Click inside the "Origin ID" input, and enter your S3 bucket name.
6. Next to "Viewer Protocol Policy," select "Redirect HTTP to HTTPs."
7. 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.
8. Next to "Price Class," select which edge locations you want to support. It is more expensive to use more edge locations.
9. You can specify an alternate domain name such as "www.yoursite.com"
10. 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.

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

You have created a valid certificate. AWS Certificate Manager will handle renewals. 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.

1. In the field under "Custom SSL Certificate," paste in your ARN.
2. Leave the remaining options as default, and select "Create Distribution."
3. When your distribution state is "Enabled," select "Origin Access Identity" on the leftmost column.
4. Select "Create Origin Access Identity," at the top-left corner.
5. Your comment should be the name of your S3 bucket.
6. Click "Create" and then copy the ID column for the identity you just created.
7. 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 - Adjusting your bucket policy.

You should be in your S3 bucket again.

1. Select the "Permissions" tab on your bucket.
2. Select the "Bucket Policy" button.
3. Paste the following bucket policy in. You need to change the XXXXXXX to your Origin Access Identity. You also need to change yourdomain.com to the name of your new S3 bucket.

```
{
    "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": "arn:aws:s3:::yourdomain.com/*"
        }
    ]
}
```

4. Click "Save" and return to the "Overview" tab.
5. 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:

1. Click the "Create Hosted Zone" button in the top-left. 
2. Enter your domain name without www or http.
3. Enter the name of your website in the "comment" input.
4. Click "Create."
5. Click "Create Record Set."
6. The name is "www"
7. The type is CNAME.
8. The value is your domain without the www or http.
9. Click "Save Record Set."
10. Click "Create Record Set" again.
11. The name is blank.
12. The type is "A"
13. Select "Yes" next to "Alias."
14. Next to "Alias Target" select your Cloudfront distribution.
15. 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 dilinger.io to check and the code block escapes when I put a triple backtic. Not here it seems. I've reached out to dev.to on Twitter, and there will hopefully be an answer.

It seems that the syntax has fixed itself. Odd.

I hope this helps whoever was looking for a cheap way to host a secure, serverless, and static website.

Thank you.