Static Website Hosting With Amazon S3, Route 53, ACM, And CloudFront

Frank Haubenschild
8 min readJan 11, 2021

This article explains how to use Route 53 to transfer an existing domain to AWS and setting up a secure static website on S3 which finally will be delivered worldwide via Amazon CloudFront.

Despite using several services like Route 53, S3, ACM, and CloudFront, hosting a secure static website on AWS is not much more complicated than hosting your site with a One-click provider. The major advantage of using AWS is the fact that you have everything under your control and that Amazon provides a solution that is highly scalable and can serve hundreds of thousands or even millions of requests.

AWS Services for Secure Static Website Hosting

Let’s start to get your website online with these four steps:

  1. Transfer your existing domain to Route 53
  2. Setup your website on S3
  3. Generate your HTTPS certificate with ACM
  4. Distribute your website using Amazon CloudFront

1. Transfer Your Existing Domain To Route 53

Route 53, Amazon’s DNS service, lets you register a new domain or transfer an existing domain you own from your previous provider to AWS. The following lines are describing the necessary steps to transfer an existing domain to AWS. To transfer an existing domain first check the transfer requirements for top-level domains from the Route 53 documentation. If you do not find any blocking points transferring a domain to AWS is easy. Two mandatory steps are needed which you have to perform with your current domain provider (not with AWS).

  1. Unlock your domain so that the transfer can be started
  2. Get the Authorization code from your current provider for the domain you want to transfer.

Once you have down the above two steps go to the AWS Management Console and search for Route 53 and click Transfer Domain.

You can either register a new domain or transfer an existing one via Route 53

If you have correctly unlocked your domain with your current provider you will see the following screen.

The domain was correctly unlocked

If the unlock process is still pending (this can take several minutes) or you simply did not trigger it you will see something like this:

Warning message shows that the domain was not (yet) correctly unlocked and cannot be transferred to AWS

If the domain was correctly unlocked you have to enter the Authorization code which you requested from your current provider.

If you want to use the DNS name servers from your current provider you can just continue the transfer process and finally enter your contact details to the domain name and complete the transfer process. If you want to Import name servers from a Route 53 hosted zone that has the same name as the domain you have to create a hosted zone for this domain first.

Using the Route 53 DNS servers needs a Hosted Zone for your domain name
The hosted zone with the name server was successfully created
The previously created hosted zone can now be selected. For the transferred domain the Route 53 DNS servers will now be used. This is the recommended option to select

If you have entered your contact details and specified if you want to auto-renew your domain the domain transfer can be started. Theoretically, the transfer could be fast and only a matter of hours to complete. Personally, I had one transfer from ionos.com (formerly 1und1.de) which took six complete days. Please note that the propagation of the DNS change (if you use the Route 53 ones) could take 24 up to 48 hours to propagate worldwide.

2. Setup Your Website On S3

Let’s assume that you want to reach your static website content via the domain my-domain.com and requests to www.my-domain.com should be automatically redirected to my-domain.com.

Create the Bucket first
Name the Bucket identically to your domain — in our example my-domain.com and choose the region where the bucket will be hosted within AWS. You will later copy your website content into this bucket.

Name the bucket according to your domain name

Make the Bucket accessible to the world
Due to the fact that your website should be reachable from the outside world, you have to allow public access to this bucket.

Now update the Bucket Policy to give read access to the public world. From now on every single file within this bucket my-domain.com is readable to the public. So do not put anything inside this bucket that you want to keep private — everybody can access it from now on!

Allow read access with a bucket policy — for copy and paste use the below snippet
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-domain.com/*"
}
]
}

Setup static website hosting for your bucket
Go to the properties of the bucket and enable Static website hosting. There you can also specify the index and error document of your website. These two files must be linked according to your project setup.

Enable Static website hosting for your bucket my-domain.com

Now you can copy your static website content to the bucket my-domain.com. Simply upload all your files within the AWS Management Console. Please check that you have the index.html and error.html document within your project. You can name these two files however you like but it is good practice to name them like this.

Create another bucket for www.my-domain.com
If you want to reach your domain also at www.my-domain.com you have to create a second bucket — just name it www.my-domain.com. Enable Static website hosting also for this bucket but use the Redirect-option and point to the primary bucket my-domain.com which we created in the first step. Due to the fact that we want to redirect all traffic to an SSL connection enable the corresponding protocol to HTTPS.

A second bucket will serve www.my-domain.com via a redirect to the first bucket my-domain.com

3. Generate Your HTTPS Certificate With ACM

Due to the fact that HTTPS is a MUST for serving secure website content, we have to generate a public certificate using the AWS Certificate Manager (ACM).

Amazon AWS Certificate Manager

Requesting a public certificate on ACM is free and simple to set up. First, you have to Request a public certificate and specify for which domain/subdomains it should be used. In our case for my-domain.com and www.my-domain.com. We use a wildcard and request the certificate additionally for all subdomains of my-domain.com.

Request a free public certificate
Use a wildcard to include all subdomains

The next step is to prove that you are the owner of the domain for which the certificate gets requested for. You can either choose DNS or Email validation. Using DNS validation is probably the quickest option because AWS can automatically add the DNS record to your Route 53 hosted domain.

If you host your domain with Route 53, AWS can automatically create a CNAME record to prove that the request is from the domain owner

If the DNS validation passed successfully or you have confirmed the certificate registration via Email your certificate is ready and can be used to secure your HTTP connection.

Validation successfully passed and certificate finally issued

4. Distribute Your Website Using Amazon CloudFront

Due to the fact that Amazon S3 uses an SSL wildcard certificate which cannot be used for custom domains you cannot have a static website hosted on S3 reachable via HTTPS without using CloudFront. In the previous step, we have created our own certificate for the domain *.my-domain.com which we now use within Amazon CloudFront to make our domain reachable via HTTPS. We put Amazon CloudFront in front of our website to finally have a securely hosted website on the one hand. With the CDN (Cloud Delivery Network) you will have a website that is close to your users and which will load fast — i.e. users from the US will get the data from US-based servers and users in Europe from a server somewhere in Europe.

To create your CloudFront distribution search for CloudFront within the Amazon Management Console and click Create Distribution

Click Get Started to create a Web Distribution

First, you specify the Origin Domain Name of your distribution. In our case, this is the name of our my-domain.com bucket. We always want HTTPS so we set the Viewer Protocol Policy to Redirect HTTP to HTTPS and the Allowed HTTP Methods options to GET, HEAD, OPTIONS.

Forcing HTTPS via the Viewer Protocol Policy

To continue we have to generate DNS record CNAMEs under which the distribution will be available. In our case my-domain.com and www.my-domain.com.

Specify the CNAMES and choose your own SSL certificate

You can leave the other options at their default values and press the button Create Distribution. It’s probably worth enabling Standard Logging and specifying an S3 bucket where the access logs to your website will be written into. For logging do not use the same bucket as for your website content because this bucket is readable from the outside world!

If the CloudFront distribution was created successfully you have to create four CNAME records within the Route 53 hosted zone for your domain my-domain.com which are all routing the traffic to the created CloudFront distribution.

  1. CNAME-A for my-domain.com
  2. CNAME-AAAA for my-domain.com
  3. CNAME-A for www.my-domain.com
  4. CNAME-AAAA for www.my-domain.com
CNAME-A for my-domain.com pointing to our created CloudFront Distribution

You’ve Reached Your Destination

That’s it. You now have a static website that you can access securely via HTTPS on a low-cost footprint of S3 within a highly scalable cloud environment of Amazon AWS.

Photo by Kolleen Gladden on Unsplash

References:

--

--

Frank Haubenschild

Dad, Software Engineer, Photographer, Reef- & Bee-Keeper, Founder, Drone Pilot — 🤓 💻 📷 🐝 🐠 💡👨‍✈️