Static Website using S3 + CloudFront + Certificate Manager

After setting up a static website using S3, AWS Certificate Manager, and Cloudfront, I decided to compile a few guides I used into one. While working through issues with my setup, I discovered that each guide I found was a little different and in the end I used a few steps from each. The purpose of this guide is to show you how to setup a static webpage with SSL using S3.

Step 1: Setup S3 bucket(s)

Navigate to S3 in the AWS console and create a new bucket or buckets that correspond to the domain you will be using for your website (i.e. or In most cases you will want to create both the naked domain and www domain bucket, as one will be used to redirect to the other.

Once you have both buckets created ( and we need to adjust a few properties. First, go into the naked domain bucket ( and setup static website hosting. This is done by selecting the bucket and going to Properties → Static website hosting. Once there, toggle "Use this bucket to host a website" and point it to your index.html (or whatever your index file is named). Also, make note of the endpoint value displayed at the top of the box, as this will come into play when setting up CloudFront. For the purpose of this guide it would correspond to

Once that is setup we want to make sure the bucket is publicly accessible so that people can visit our site. The below policy will allow anyone to see the bucket we have setup. Make sure to update the `Resource` to point to your bucket for this example it would be*.

Now that the naked domain's bucket is configured we will move onto the www bucket ( and setup the redirect. This is also setup through Properties → Static website hosting of the bucket by checking the "Redirect requests" option.

Also at this point, if you haven't already, make sure to upload your static website pages to the S3 bucket.

Step 2: Request a certificate using Certificate Manager

Navigate to the AWS's Certificate Manager and click the "Request a certificate" button. On the next screen make sure to add the corresponding domains.

After those have been added hit "Next" to choose which validation method you would like to use. For the purposes of this guide, I will use DNS validation. When DNS validation is selected, AWS will ask you to create a CNAME record at your DNS provider (since DNS providers can vary I will not be going over the creation of the CNAME record). If the CNAME record is created by hand (AWS can auto create a record in Route 53) like I did, one caveat is with the name for the CNAME record. Although AWS gives you a nice tool to copy the name directly, this can result in a broken CNAME record. Below is a snippet from AWS's documentation that pointed me to this issue.

Once the certificate has been requested all thats left is wait for it to be issued.

Step 3: Configure CloudFront distribution

Navigate to the Certificate Manager in the AWS console and click the "Create Distribution" button. On the next screen click "Get Started" under the Web section.

For the top section (Origin Settings) we only care to fill in the "Origin Domain Name". Although AWS provides an autocomplete dropdown list for this, we want to paste the endpoint url of the bucket we noted earlier in the guide ( Once thats added we can setup the next section.

As shown above, we will only be updating the "Viewer Protocol Policy" to be "Redirect HTTP to HTTPS", this will make sure anyone navigating to none SSL is pushed to HTTPS.

In the "Distribution Settings", we want to update the Alternate Domain Names to include a comma separate list of the domain names we care bout ( and After that, if your certificate has been issued you will be able to toggle "Custom SSL Certificate" and select the certificate that was issued.

After CloudFront has been setup, everything should be working as expected. At this point you should be able to navigate to your static site through either the naked domain or www domain. All in all the whole process is pretty straight forward and simple to configure. We have used this solution in cases where we have retired full websites or only have a single page we care to host.

Mar. 30 2018