How do I use CloudFront to serve a static website that’s hosted on Amazon S3?

9 minute read
3

I want to host a static website on an Amazon Simple Storage Service (Amazon S3) bucket. Then, I want to serve my website through an Amazon CloudFront distribution.

Short description

To serve a static website that's hosted on Amazon S3, use one of the following configurations to deploy a CloudFront distribution:

  • Use a REST API endpoint as the origin, and restrict access with an origin access control (OAC) or origin access identity (OAI)
    Note: It's a best practice to use origin access control (OAC) to restrict access. Origin access identity (OAI) is a legacy method for this process.
  • Use a website endpoint as the origin, and allow anonymous (public) access
  • Use a website endpoint as the origin, and restrict access with a Referer header
  • Use AWS CloudFormation to deploy a static website endpoint as the origin, and custom domain pointing to CloudFront

For more information on the two endpoint types, see Key differences between a website endpoint and a REST API endpoint.

Resolution

To configure a CloudFront distribution with the S3 endpoint type that you want to use as the origin, complete the following steps:

Use a REST API endpoint as the origin, and restrict access with an OAC or an OAI (legacy)

1.    Use the Amazon S3 console to create a bucket and to upload your website files.

Note: You don't need to turn on static website hosting on your bucket for this configuration. This configuration uses the REST API endpoint of the bucket instead of the website endpoint from the static website hosting feature.

2.    Create a CloudFront web distribution. In addition to your use case distribution settings, complete the steps in one of the following sections to restrict access to the Amazon S3 origin. It's a best practice to use OAC, as OAI is a legacy setting.

OAC

When you create your distribution, enter your Amazon S3 bucket name in Origin Domain field.

Under Origin access, select Origin access control settings (recommended).

In the Origin access control dropdown list, select the OAC name and choose Create control setting.

In the dialog box, name your control setting**.** It's a best practice to leave the default setting Sign requests (recommended). Then, choose Create.

CloudFront provides you with the policy statement to give OAC permission to access your Amazon S3 bucket after you create the distribution. Select Copy Policy and paste the policy in your S3 bucket policy configuration.

OAI

When you create your distribution, enter your Amazon S3 bucket name in Origin Domain field.

Under Origin access, select Legacy access identities.

In the Origin access identity dropdown list, select the origin access identity name. Then, choose Create new OAI.

In the dialog box, name your new origin access identity and choose Create.

For Bucket policy, select Yes, update the bucket policy.

3.    When you create your distribution, it's a best practice to use SSL (HTTPS) for your website. To use a custom domain with HTTPS, select Custom SSL certificate. Choose Request certificate to request a new certificate. If you don't use a custom domain, you can still use HTTPS with the cloudfront.net domain name for your distribution.
Important: If you enter Alternate domain names (CNAMEs) for your distribution, then the CNAMEs must match the SSL certificate that you select. To troubleshoot issues with your SSL certificate, see How can I troubleshoot issues with using a custom SSL certificate for my CloudFront distribution?

4.    Update the DNS records for your domain to point your website's domain to CloudFront. Find your distribution's domain name in the CloudFront console. The domain name looks similar to the following example: d1234abcd.cloudfront.net.

5.    Wait for your DNS changes to propagate and for the previous DNS entries to expire.
Note: The length of time for the previous DNS values to expire depends on the TTL value that's set at your hosted zone. It also depends on whether your local resolver uses those TTL values.

Use a website endpoint as the origin, and allow anonymous (public) access

This configuration allows public read access on your website's bucket. For more information, see Setting permissions for website access.
Note: When you use the Amazon S3 static website endpoint, connections between CloudFront and Amazon S3 are available only over HTTP. To use HTTPS for connections between CloudFront and Amazon S3, configure an S3 REST API endpoint for your origin.

  1. Use the Amazon S3 console to create a bucket and turn on static website hosting on the bucket.
  2. From the Static website hosting dialog box, copy the Endpoint of your bucket without the leading http://. The format is similar to DOC-EXAMPLE-BUCKET.s3-website-region.amazonaws.com. You need the endpoint in this format for a later step.
  3. Add a bucket policy that allows public read access to the bucket that you created.
    Note: For this configuration, you must turn off the S3 bucket's block public access settings. If your use case requires you to turn on the block public access settings, use the REST API endpoint as the origin. Then, restrict access by an origin access control (OAC) or origin access identity (OAI).
  4. Create a CloudFront web distribution. In addition to your use case distribution settings, complete the following steps:
    For Origin domain, enter the endpoint that you copied in the previous step.
    Note: Don't select the bucket from the dropdown list. The dropdown list includes only the S3 Bucket REST API endpoints that you don't use in this configuration.
  5. When you create your distribution, it's a best practice to use SSL (HTTPS) for your website. To use a custom domain with HTTPS, select Custom SSL certificate. Choose Request certificate to request a new certificate. If you don't use a custom domain, then you can still use HTTPS with the cloudfront.net domain name for your distribution.
    Important: If you enter Alternate domain names (CNAMEs) for your distribution, then the CNAMEs must match the SSL certificate that you select. To troubleshoot issues with your SSL certificate, see How can I troubleshoot issues with using a custom SSL certificate for my CloudFront distribution?
  6. Update the DNS records for your domain to point your website's domain to CloudFront. Find your distribution's domain name in the CloudFront console. The domain name format is similar to the following example: d1234abcd.cloudfront.net.
  7. Wait for your DNS changes to propagate and for the previous DNS entries to expire.
    Note: The length of time for the previous DNS values to expire depends on the TTL value that's set at your hosted zone. It also depends on whether your local resolver uses those TTL values.

Use a website endpoint as the origin, and restrict access with a Referer header

Important: Review if the access this setup allows meets the requirements of your use case.

This configuration sets up a custom Referer header on the distribution to restrict access. Then, it uses a bucket policy to allow access for only requests with the custom Referer header.

Note: When you use the Amazon S3 static website endpoint, connections between CloudFront and Amazon S3 are available only over HTTP. To use HTTPS for connections between CloudFront and Amazon S3, configure an S3 REST API endpoint for your origin.

  1. Use the Amazon S3 console to create a bucket and turn on static website hosting on the bucket.
  2. From the Static website hosting dialog box, copy the Endpoint of your bucket without the leading http://. The format is similar to DOC-EXAMPLE-BUCKET.s3-website-region.amazonaws.com. You need the endpoint in this format for a later step.
  3. Create a CloudFront web distribution. In addition to your use case distribution settings, complete the following steps:
    For Origin domain, enter the endpoint that you copied in the previous step.
    Note: Don't select the bucket from the dropdown list. The dropdown list includes only the S3 Bucket REST API endpoints that this configuration doesn't use.
    Under Add custom header, choose Add header.
    For Header name, enter Referer.
    For Value, enter a customer header value that you want to forward to the origin (S3 bucket). To restrict access to the origin, enter a random or secret value that only you know.
  4. When you create your distribution, it's a best practice to use SSL (HTTPS) for your website. To use a custom domain with HTTPS, select Custom SSL certificate. Choose Request certificate to request a new certificate. If you don't use a custom domain, you can still use HTTPS with the cloudfront.net domain name for your distribution.
    Important: If you enter Alternate domain names (CNAMEs) for your distribution, then the CNAMEs must match the SSL certificate that you select. To troubleshoot issues with your SSL certificate, see How can I troubleshoot issues with using a custom SSL certificate for my CloudFront distribution?
  5. Open your website's bucket from the Amazon S3 console. Then, add a bucket policy that allows s3:GetObject on the condition that the request includes the custom Referer header that you specified in step 3. For this configuration, you must turn off the S3 bucket's block public access settings. Amazon S3 considers a bucket policy that grants anonymous access restricted by a Referer to be public. If your use case requires you to turn on the block public access settings, then use the REST API endpoint as the origin. Then, restrict access with an origin access control (OAC) or origin access identity (OAI).
    Note: To block access for any request that doesn't include the custom Referer header, use an explicit deny statement in the bucket policy.
  6. Update the DNS records for your domain to point your website's domain to CloudFront. Find your distribution's domain name in the CloudFront console. The domain name is similar to the following example: d1234abcd.cloudfront.net.
  7. Wait for your DNS changes to propagate and for the previous DNS entries to expire.
    Note: The length of time for the previous DNS values to expire depends on the TTL value that's set at your hosted zone. It also depends on whether your local resolver uses those TTL values.

Use CloudFormation to deploy a static website endpoint as the origin, and custom domain pointing to CloudFront

This solution uses the following configuration for your website:

  • Deploys your website with CloudFormation
  • Hosts your website on Amazon S3
  • Distributes your website with CloudFront
  • Uses an SSL/TLS certificate from AWS Certificate Manager (ACM)
  • Uses CloudFront Response Header Policies to add security headers to every server response

For instructions on how to deploy this solution, see Amazon CloudFront Secure Static Website on the GitHub website.

Related information

Getting started with a secure static website

Email validation

DNS validation

Using alternate domain names and HTTPS

AWS OFFICIAL
AWS OFFICIALUpdated a year ago
2 Comments

It seems to be critical that the bucket is in the us-east1 region for this to work properly, as listed in the cloud formation template, why doesn't this article mention that? Is only building in a single region a requirement for most of AWS?

car
replied 5 months ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

profile pictureAWS
MODERATOR
replied 5 months ago