Cloud / AWS / Content delivery

Amazon CloudFront

Connect CloudFront to your S3 static website and open the site through a CloudFront HTTPS address.

What CloudFront adds

Amazon CloudFront is a content delivery network (CDN). It receives requests from website visitors and can cache copies of files at locations closer to them. In this exercise, CloudFront will be the public address for the site, while the S3 website endpoint is the origin CloudFront fetches files from.

This first setup keeps the S3 website public so CloudFront can fetch it. It is useful for learning, but it does not hide the S3 endpoint or make the bucket private. Later, we can switch to a regular S3 bucket origin with Origin Access Control (OAC). A bucket configured as an S3 website endpoint must be added to CloudFront as a custom origin. AWS: S3 website endpoints as CloudFront origins.

Before you start

Finish the S3 lesson first. Confirm that its website endpoint opens your site, and copy the endpoint hostname from the S3 bucket’s Properties → Static website hosting section. It looks similar to bucket-name.s3-website-region.amazonaws.com. Use the website endpoint—not the ordinary S3 bucket URL.

Step 1: Create a CloudFront distribution

  1. Open the CloudFront console and choose Create distribution.
  2. For the origin, paste the S3 website endpoint hostname you copied. Leave off http:// and any trailing path. If asked for an origin type, choose Custom origin; a website endpoint is treated as a custom origin.
  3. Choose Redirect HTTP to HTTPS for the viewer protocol policy, so visitors using HTTP are sent to HTTPS.
  4. Use the default allowed methods GET, HEAD for a static website. Keep the default cache settings for this first exercise.
  5. Choose Create distribution.

If the creation flow does not show viewer protocol policy, create the distribution with its recommended settings, then edit the default behavior and set Viewer protocol policy to Redirect HTTP to HTTPS.

For this S3 website origin, CloudFront connects to S3 over HTTP because S3 website endpoints do not support HTTPS. The visitor-to-CloudFront connection can still use HTTPS. AWS: CloudFront origin settings · AWS: default root object.

Step 2: Wait, then test the site

  1. In CloudFront, select the new distribution. On its General tab, choose Edit in Settings.
  2. Set Default root object to index.html with no leading slash, then save. This tells CloudFront which file to return when a visitor requests the distribution’s root address.
  3. Wait until the distribution shows Enabled and is no longer deploying. Changes can take several minutes to reach CloudFront’s edge locations.
  4. Copy the distribution’s Distribution domain name, which looks like d123example.cloudfront.net, and open https:// followed by that name in a browser.

CloudFront may finish deploying the initial distribution before the root-object setting change finishes deploying. If the site does not load right away, wait for the latest change to finish and try again. AWS’s console steps for setting the default root object are in its default root object guide.

Test an image or another page too. If the home page works but styling or images do not, check that those files were uploaded with the same folder structure and that their paths in the HTML and CSS match the object keys in S3.

What this setup means

Your browser connects to CloudFront using HTTPS. CloudFront fetches uncached files from the public S3 website endpoint using HTTP and may keep copies in its cache. Since the S3 origin is public, someone can still access it directly. This is the learning version; the next improvement is to use a private S3 REST origin with OAC, then remove public access from the bucket. AWS: restrict CloudFront access to an S3 origin.

Next: use a private S3 bucket with OAC

Origin Access Control (OAC) lets CloudFront sign its requests to an S3 bucket. The bucket policy can then allow a specific CloudFront distribution to read objects while blocking direct public access to the bucket.

Visitor ──HTTPS──> CloudFront ──signed request──> Private S3 bucket

OAC works with a regular S3 bucket origin, not an S3 s3-website endpoint. To make the bucket private, switch CloudFront to a regular S3 origin (or create a new distribution). With that origin, CloudFront’s Default root object setting can serve index.html at the site’s root.

Create an OAC

  1. Open the CloudFront console and choose Origin access in the navigation.
  2. Choose Create control setting and enter a name, such as website-s3-oac.
  3. Leave Signing behavior set to Sign requests (recommended), choose S3 as the origin type, and create the OAC.

Attach it to the S3 origin

  1. Open your distribution’s Origins tab and select the regular S3 bucket origin. An s3-website origin is a custom origin and cannot use OAC.
  2. Choose Edit. Under Origin access, choose Origin access control settings (recommended), select your OAC, and save.

Allow this distribution in the S3 bucket policy

The policy is an S3 permission rule. It grants read-only access to CloudFront and limits that access to your distribution. In S3, open the bucket’s Permissions → Bucket policy → Edit. Add this statement to the policy’s Statement list, replacing all three placeholders:

{
  "Sid": "AllowThisCloudFrontDistributionReadOnly",
  "Effect": "Allow",
  "Principal": {
    "Service": "cloudfront.amazonaws.com"
  },
  "Action": "s3:GetObject",
  "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*",
  "Condition": {
    "StringEquals": {
      "AWS:SourceArn": "arn:aws:cloudfront::YOUR_AWS_ACCOUNT_ID:distribution/YOUR_DISTRIBUTION_ID"
    }
  }
}

YOUR_BUCKET_NAME is the bucket name. YOUR_AWS_ACCOUNT_ID is the 12-digit account ID. YOUR_DISTRIBUTION_ID is the CloudFront distribution ID, not its cloudfront.net domain name. Keep any other policy statements you still need. If the CloudFront console offers to update the bucket policy, you can accept its change and review it instead of adding this statement manually. AWS documents this distribution-specific permission in its OAC guide.

  1. Save the bucket policy, then wait for the CloudFront distribution to finish deploying.
  2. Test the site through its CloudFront HTTPS domain. If it loads, remove the earlier public-read statement (for example, PublicReadForWebsiteFiles) from the bucket policy.
  3. Enable S3 Block all public access. Keep the CloudFront distribution-specific permission so signed requests can still read the objects.

Do not remove public access until the regular S3 origin, OAC, and bucket permission are configured and the CloudFront URL works. Otherwise, CloudFront may not be able to fetch the files.

AWS: create and attach OAC · AWS: S3 website endpoints and custom origins.

If CloudFront shows 504 Gateway Timeout

A 504 means CloudFront did not get a response from the origin in time. Check these items in order:

  1. Open the S3 website endpoint directly from the bucket’s Properties → Static website hosting section. Confirm that the site loads there. An object URL that ends in /index.html is a different endpoint.
  2. In CloudFront, open the distribution’s Origins tab and edit the origin. Confirm its domain is exactly the S3 website endpoint hostname, with no http://, path, or trailing slash.
  3. Confirm the origin protocol is HTTP only. S3 website endpoints do not support HTTPS from CloudFront.
  4. Save any changes and wait until the distribution finishes deploying before testing again.

AWS lists origin connectivity and protocol as common things to check for a 504. AWS: troubleshoot CloudFront 504 errors.

When you finish practicing

To avoid leaving practice resources running, disable and delete the CloudFront distribution from the CloudFront console, then delete the S3 practice bucket and its objects if you no longer need them. CloudFront requires a distribution to be disabled before it can be deleted. Review any charges in the AWS Billing console.