Creating a Static Website with S3 - Part 2

Welcome back! If you're reading this then I assume you've already read and completed the tasks in my Part 1 post. If not, please do so, or else this may not make sense.

In our last post, we created some AWS S3 buckets for hosting our static website. We'll continue on, utilizing Route53, AWS Certificate Manager (ACM), and CloudFront. This will allow us to visit our website using our custom domain name and have the connection secured over HTTPS.

Step 1 - Configuring Route53 Hosted Zone

AWS Route53 provides Domain Name System (DNS) services. If you don't already have a custom domain, you can create one here. If you've purchased your domain elsewhere (e.g., Google, GoDaddy, etc.) then you'll need to update the Name Servers on your domain to instead use Amazon's Name Servers. For example, you can see where I configured my domain on Google Domains.

First, in Route53, let's create a Hosted Zone which will help to manage our DNS records for our custom domain.

Your zone should look similar to this.

Next, we're going to add some DNS records to our newly created Hosted Zone. These will allow us to access our website by our custom domain name. Click on the Hosted Zone and choose the button Create Record. Update yours similar to mine below.

Alright, now create one more record but this time we'll create it for our second bucket, the subdomain www.

If all things work you can now view your website by its domain name.

Perhaps you noticed the Not Secure message when navigating to our website? That's because we don't have HTTPS setup. Since AWS S3 doesn't support HTTPS access to websites, we'll need to use AWS CloudFront. Prior to that though we need to request an SSL certificate through AWS Certificate Manager that we'll use with CloudFront.

Step 2 - Requesting an SSL Certificate with AWS Certificate Manager (ACM)

First, make sure your region is set to us-east-1 (N. Virginia). CloudFront won't accept an Amazon certificate unless it's been created here.

Next, within ACM, go ahead and request a public certificate. Make sure to add both your root domain and your subdomain (www).

Once that is done we need to click on our new certificate and have some DNS records created to validate our ownership of the domain.

Wait for our certificate status to say Issued and once it does we can move on to CloudFront.

Step 3 - Configuring Amazon CloudFront

Amazon CloudFront is a content delivery network (CDN) service. It's going to host our website files from our S3 bucket at various data centers around the world to speed up load times for our viewers. It's also going to route any HTTPS traffic to our website for us.

Dive into CloudFront and create a distribution. Your changes should reflect those highlighted below. Make sure the Origin is your root domain (not www). Also, we want to update our S3 Bucket Policy to allow CloudFront to have access. We'll update the policy ourselves in a bit and remove what we used earlier. This way people aren't accessing the bucket directly.

It will take a few minutes for the distribution to get created. Wait until you have an Enabled status and a date/time for last modified like so.

Now, let's go back into Route53 and adjust our A records to point at our new CloudFront distribution instead of the S3 buckets themselves.

Step 4 - Updating Route53 DNS Records

Back in Route53, we need to edit both of our A records one at a time.

When done, our records should be pointing to our CloudFront distribution and not our S3 buckets. CloudFront will route the traffic for us.

The final step now is to update our S3 Bucket Policy so that only CloudFront has access to our bucket.

Step 5 - Updating S3 Bucket Policy

Back in our S3 bucket, click on Permissions.

Scroll down and click edit next to Bucket policy. Let's update the policy as such.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "CloudFront Read",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/YOUR CLOUDFRONT ORIGIN ACCESS IDENTITY"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::YOUR ARN HERE/*"
        }
    ]
}

Now, if you go to your Bucket Website Endpoint (found under Bucket > Properties > scroll to bottom), you'll get an AccessDenied error. Take note that you'll need to open that link in a Private Tab or another browser since you're logged into your AWS account at the moment.

What this means is that other users will no longer be able to access your website directly via the Bucket Website Endpoint. Instead, they'll need to use your custom domain name and CloudFront will handle the traffic, showing the content (your website). Go ahead and navigate to your custom domain and you'll see that HTTPS is enabled now thanks to ACM and CloudFront.

Recap

Alright, so we did a lot of things. We first used Route53 to map our S3 bucket to a custom domain. This allowed us to navigate to the custom domain instead of our S3 bucket website endpoint. After that, we requested an SSL certificate through AWS Certificate Manager. Then we set up CloudFront to route our HTTPS traffic to our S3 buckets after granting it access to do so via our S3 Bucket Policy. Next, we updated our DNS records to point to our CloudFront distribution instead of our S3 buckets, and finally, we removed some old permissions no longer needed on our S3 Bucket Policy.

In a future post, we'll rebuild everything using CloudFormation. CloudFormation is an AWS capability enabling Infrastructure as Code and negating the need to do anything in the AWS console.

Last updated