Host static website via AWS CloudFront

#aws#aws s3#aws cloudfront#dns

17 February 2025 | Updated on 05 March 2025

CloudFront is a content delivery network by AWS. You can host your static website there.

Login to your AWS account

  • I prefer to have separate AWS organizations with their own AWS accounts. You can use roles and switch to a specific account then.
  • so login or switch to your aws account which should contain the new website

Create a certificate

Use AWS certificate manager

Request certificate

  • click request certificate
  • request a public certificate
Domain names
  • create two entries
    yourdomain.com
    *.yourdomain.com
Other settings
  • keep the default values for the other settings (dns validation, …)
  • you can add a tag
  • click create
Domain validation

This step is only required in case you did not validate your domain before and the certificate creation stays on pending.

  • you could use the dns service route 53 to configure your domain dns records
  • but I prefer to configure these entries outside of AWS
  • so just click on Export to CSV instead of create records in route 53
  • add the cname entry in the dns settings of your domain registry
    • you only need to add the one entry without the * in case you created a wildcard certificate
    • be sure that you do leave out the domain name itself in the key field of cname (so your domain is not doubled!)
  • the status might still be pending it could take up to a few hours but most times you are ready to go after waiting a few minutes (aws dns validation)
  • you can visit list certificates and in certificate manager and refresh the page to see if the certificate was created
Check dns entries via command line
  • in case you want to check if the entries were set and can be found
    dig +noall +answer +multiline <cname_key>.yourdomain.com CNAME
    • this command should return an entry ending with .acm-validations.aws.

Create S3 bucket

  • go to S3 service and click create bucket
  • choose a region
    • you can choose a region that is geographically close to you (selector at the top right)
  • choose a name
  • leave the rest at the default
  • optionally add tags

Create CloudFront distribution

AWS CloudFront

  • go to aws service cloudfront
  • click Create a CloudFront distribution
  • select the s3 bucket as origin domain
  • leave origin path empty
  • optionally edit name
  • origin access: select Origin access control settings (recommended)
    • then click on: Create new OAC
      • keep the defaults and click create
  • in settings settings
    • WAF: do not use for now (can add later)
    • Alternate domain name (CNAME)
      • add item (and enter your domain/subdomain)
    • custom ssl certificate
      • select the one created before
    • supported http version, select both
      • HTTP/2
      • HTTP/3
    • default root object: index.html
  • Choose Create distribution

Edit S3 bucket policy

  • In The S3 bucket policy needs to be updated banner, read the message and choose Copy policy.
  • go to s3 bucket via link in notification
  • go to tab Permissions
  • Edit Bucket Policy
  • paste copied content
  • save changes

Adjust domain dns entries to use cloudfront

  • in the dns settings of your own domain change the domain (or subdomain) CNAME entry to use the domain of the cloudfront distribution
  • example
    www.yourdomain.com. CNAME d1234567890.cloudfront.net.

Add index.html to subfolders too

This step ensures that your hugo website works properly.

The default root object setting only adds index.html to the root of the website (not subfolders). You can create automatic internal redirects via CloudFront functions to get this feature for subfolders too.

  • open cloudfront
  • select functions > create function (javascript 2.0)
  • insert code
    async function handler(event) {
        var request = event.request;
        var uri = request.uri;
    
        // Check whether the URI is missing a file name.
        if (uri.endsWith('/')) {
            request.uri += 'index.html';
        } 
        // Check whether the URI is missing a file extension.
        else if (!uri.includes('.')) {
            request.uri += '/index.html';
        }
    
        return request;
    }
  • choose save changes
  • publish function
  • on same page choose add association
  • select your cloudfront distribution
  • event type viewer request
  • cache behaviour default (*) ?

Ensure correct 404 error page behaviour

By default website visitors will see Access denied errors (403) when they try to access a page/url that does not exist. You can fix this problem with custom error pages in CloudFront.

Learn how to create a custom error page in AWS CloudFront

Additional resources

CloudFront functions


Related content