---
title: Amazon S3
summary: null
url: >-
  https://www.fastly.com/documentation/guides/integrations/non-fastly-services/amazon-s3
---

[Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/gsg/GetStartedWithS3.html) public and private buckets can be used as [origins](https://www.fastly.com/documentation/guides/getting-started/hosts/working-with-hosts) with Fastly.

## Using Amazon S3 as an origin

To make your S3 data buckets available through Fastly, follow the steps below.

### Creating a new service

Follow the instructions for [creating a new service](https://www.fastly.com/documentation/guides/getting-started/services/working-with-cdn-services#creating-a-new-cdn-service).

1. When you create the new domain and the new Host:

   - In the **Domain Name** field on the **Create a domain** page, enter the hostname you want to use as the URL (e.g., `cdn.example.com`).
   - In the **Hosts** field on the **Origins** page, enter the appropriate address for your Host using the format `.s3..amazonaws.com`. Use the table in the [Amazon S3 endpoints](https://docs.aws.amazon.com/general/latest/gr/s3.html) of the AWS general reference documentation as a guide. For example, if your bucket name is `fastlytestbucket` and your region is `us-east-2`, your hostname would be `fastlytestbucket.s3.us-east-2.amazonaws.com`.

   > **HINT:** Most customers select a region close to the [interconnect location](https://www.fastly.com/documentation/guides/concepts/shielding/#choosing-a-shield-location) they specify for [shielding](https://www.fastly.com/documentation/guides/getting-started/hosts/shielding).

2. When you [edit the Host](https://www.fastly.com/documentation/guides/getting-started/hosts/working-with-hosts#editing-a-host) details on the **Edit this host page**:
   - In the **Name** field, enter any descriptive name for your service if you haven't already done so.
   - In the **Address** field, ensure you've entered the appropriate address for your region (e.g., `fastlytestbucket.s3.us-east-2.amazonaws.com`). You entered this information during Host creation.

3. When you edit the Transport Layer Security (TLS) area information for your Host:

   - Leave the **Enable TLS?** default set to **Yes** to secure the connection between Fastly and your origin.

     > **HINT:** If you're using Amazon S3 to host a static website, **Enable TLS?** should be set to **No** instead of relying on the default. Amazon [doesn't support TLS connections](https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteEndpoints.html#WebsiteRestEndpointDiff) to S3 buckets with the [static website hosting feature](https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html) enabled. You can still use one of [Fastly's TLS service options](https://docs.fastly.com/products/tls-service-options) to secure connections between Fastly and clients.

   - Under the **SNI hostname** field, select the checkbox to **Match the SNI hostname to the Certificate hostname**. The address you entered during Host creation appears.

   - In the **Certificate hostname** field, enter `fastlytestbucket.s3.us-east-2.amazonaws.com`.

4. In the **Override host** field, enter an appropriate address for your Host (e.g., `fastlytestbucket.s3.us-east-2.amazonaws.com`). You entered this information during Host creation. If you're [using an Amazon S3 private bucket](https://www.fastly.com/documentation/guides/integrations/non-fastly-services/amazon-s3#using-an-amazon-s3-private-bucket) leave this field blank.

### Validating the DNS mapping

By default, we create a DNS mapping called **yourdomain.global.prod.fastly.net**. In the example above, it would be `cdn.example.com.global.prod.fastly.net`. Enter this URL in a browser to confirm it's working.

### Creating a DNS alias

Create a [DNS alias](https://www.fastly.com/documentation/guides/getting-started/domains/working-with-domains/working-with-cname-records-and-your-dns-provider) for the domain name you specified (e.g., CNAME `cdn.example.com` to `global-nossl.fastly.net`).

### Verifying your results

Fastly will [cache](https://www.fastly.com/documentation/guides/full-site-delivery/caching/caching-best-practices) any content without an explicit `Cache-Control` header for 1 hour. You can verify whether you are sending any cache headers [using curl](https://www.fastly.com/documentation/guides/full-site-delivery/caching/checking-cache#using-curl). For example:

```term nolinenums
$ curl -I opscode-full-stack.s3.amazonaws.com

HTTP/1.1 200 OK
x-amz-id-2: ZpzRp7IWc6MJ8NtDEFGH12QBdk2CM1+RzVOngQbhMp2f2ZyalkFsZd4qPaLMkSlh
x-amz-request-id: ABV5032583242618
Date: Fri, 18 Mar 2012 17:15:38 GMT
Content-Type: application/xml
Transfer-Encoding: chunked
Server: AmazonS3
```

In this example, no Cache-Control headers are set so the default [Time to Live (TTL)](https://www.fastly.com/documentation/guides/full-site-delivery/caching/controlling-caching#determining-the-ttl-of-an-object) will be applied.

### Enhanced cache control

If you need more control over how different types of assets are cached (e.g., JavaScript files, images), check out our [documentation on cache freshness](https://www.fastly.com/documentation/guides/concepts/cache/cache-freshness).

## Using an Amazon S3 private bucket

To use an Amazon S3 private bucket with Fastly, you must implement version 4 of [Amazon’s header-based authentication](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html). You can do this using [custom VCL](https://www.fastly.com/documentation/guides/full-site-delivery/fastly-vcl/about-fastly-vcl). Start by obtaining the following information from AWS:

| Item        | Description                                                                                                                                     |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| Bucket name | The name of your AWS S3 bucket. When you download items from your bucket, this is the string listed in the URL path or hostname of each object. |
| Region      | The AWS region code of the location where your bucket resides (e.g., `us-east-1`).                                                              |
| Access key  | The AWS access key string for an IAM account that has at least read permission on the bucket.                                                   |
| Secret key  | The AWS secret access key paired with the access key above.                                                                                     |

Once you have this information, you can configure your Fastly service to authenticate against your S3 bucket using header authentication by calculating the appropriate header value in VCL.

> **HINT:** Consider leaving the **Override host** field for the origin blank in your service settings. This setting will override the Host header from the snippets shown here and may invalidate the signature that authenticates the information being sent.

Start by creating a [VCL snippet](https://www.fastly.com/documentation/guides/full-site-delivery/fastly-vcl/vcl-snippets/using-vcl-snippets). Give it a meaningful name, such as `AWS protected origin`. When you create the snippet, select **within subroutine** to specify its placement and choose **miss** as the subroutine type. Then, populate the **VCL** field with the following code (be sure to change specific values as noted to ones relevant to your own AWS bucket):

```vcl
declare local var.awsAccessKey STRING;
declare local var.awsSecretKey STRING;
declare local var.awsS3Bucket STRING;
declare local var.awsRegion STRING;
declare local var.awsS3Host STRING;
declare local var.canonicalHeaders STRING;
declare local var.signedHeaders STRING;
declare local var.canonicalRequest STRING;
declare local var.canonicalQuery STRING;
declare local var.stringToSign STRING;
declare local var.dateStamp STRING;
declare local var.signature STRING;
declare local var.scope STRING;

set var.awsAccessKey = "YOUR_AWS_ACCESS_KEY";   # Change this value to your own data
set var.awsSecretKey = "YOUR_AWS_SECRET_KEY";   # Change this value to your own data
set var.awsS3Bucket = "YOUR_AWS_BUCKET_NAME";   # Change this value to your own data
set var.awsRegion = "YOUR_AWS_BUCKET_REGION";   # Change this value to your own data
set var.awsS3Host = var.awsS3Bucket ".s3." var.awsRegion ".amazonaws.com";

if (req.method == "GET" && !req.backend.is_shield) {

  set bereq.http.x-amz-content-sha256 = digest.hash_sha256("");
  set bereq.http.x-amz-date = strftime({"%Y%m%dT%H%M%SZ"}, now);
  set bereq.http.host = var.awsS3Host;
  set bereq.url = querystring.remove(bereq.url);
  set bereq.url = regsuball(urlencode(urldecode(bereq.url.path)), {"%2F"}, "/");
  set var.dateStamp = strftime({"%Y%m%d"}, now);
  set var.canonicalHeaders = ""
    "host:" bereq.http.host LF
    "x-amz-content-sha256:" bereq.http.x-amz-content-sha256 LF
    "x-amz-date:" bereq.http.x-amz-date LF
  ;
  set var.canonicalQuery = "";
  set var.signedHeaders = "host;x-amz-content-sha256;x-amz-date";
  set var.canonicalRequest = ""
    "GET" LF
    bereq.url.path LF
    var.canonicalQuery LF
    var.canonicalHeaders LF
    var.signedHeaders LF
    digest.hash_sha256("")
  ;

  set var.scope = var.dateStamp "/" var.awsRegion "/s3/aws4_request";

  set var.stringToSign = ""
    "AWS4-HMAC-SHA256" LF
    bereq.http.x-amz-date LF
    var.scope LF
    regsub(digest.hash_sha256(var.canonicalRequest),"^0x", "")
  ;

  set var.signature = digest.awsv4_hmac(
    var.awsSecretKey,
    var.dateStamp,
    var.awsRegion,
    "s3",
    var.stringToSign
  );

  set bereq.http.Authorization = "AWS4-HMAC-SHA256 "
    "Credential=" var.awsAccessKey "/" var.scope ", "
    "SignedHeaders=" var.signedHeaders ", "
    "Signature=" + regsub(var.signature,"^0x", "")
  ;
  unset bereq.http.Accept;
  unset bereq.http.Accept-Language;
  unset bereq.http.User-Agent;
  unset bereq.http.Fastly-Client-IP;
}
```

You may also remove the headers that [AWS adds to the response](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTCommonResponseHeaders.html). Do this by creating another VCL snippet. Give it a meaningful name, such as `Strip AWS response headers`. When you create the snippet, select **Within subroutine** to specify its placement and choose **fetch** as the subroutine type. Then, place the following code in the **VCL** field:

```vcl
unset beresp.http.x-amz-id-2;
unset beresp.http.x-amz-request-id;
unset beresp.http.x-amz-delete-marker;
unset beresp.http.x-amz-version-id;
```

## Following redirects to S3 objects and caching S3 responses

Using [VCL snippets](https://www.fastly.com/documentation/guides/full-site-delivery/fastly-vcl/vcl-snippets/about-vcl-snippets), Fastly can follow redirects to S3 objects and cache the response.

To configure Fastly to follow redirects to S3 objects, follow the steps below:

1.   Log in to the [Fastly control panel](https://manage.fastly.com).

2.   From the [**Home**](https://manage.fastly.com/home) page, select the appropriate service. You can use the search box to search by ID, name, or domain.

3.   Click **Edit configuration** and then select the option to clone the active version.

4. Click **VCL**.

5. Click **VCL snippets**.

6. Click **Add snippet**.

7. Fill out the **Add VCL snippet** fields as follows:

   - Using the **Type** controls, select the [type of snippet](https://www.fastly.com/documentation/guides/full-site-delivery/fastly-vcl/vcl-snippets/about-vcl-snippets) to create.
   - In the **Name** field, enter an appropriate name (e.g., `S3 redirect - recv`).
   - Using the **Placement** controls, select **Within subroutine**.
   - From the **Subroutine** menu, select **recv (`vcl_recv`)**.
   - _(Optional)_ In the **Priority** field, enter the order in which you want the snippet to execute. Lower numbers execute first.
   - In the VCL editor, add the following code:

     ```vcl
     if (req.http.redir != "true") {
       set req.backend = Main_Origin;
     } else {
       set req.backend = s3_backend;
       set req.http.host = "s3.amazonaws.com";
     }
     ```

     > **IMPORTANT:** Be sure to replace the `Main_Origin` and `s3_backend` placeholders with the actual names of your backends in the service to which you're applying these redirects. You can find the exact names by navigating to the **Deliver** page and clicking **Show VCL**, which appears just beneath your service name while viewing that service.

8. Click **Add** to create the snippet.

9. Click **Add snippet** again.

10. Fill out the **Add VCL snippet** fields as follows:

    - Using the **Type** controls, select the [type of snippet](https://www.fastly.com/documentation/guides/full-site-delivery/fastly-vcl/vcl-snippets/about-vcl-snippets) to create.
    - In the **Name** field, enter an appropriate name (e.g., `S3 redirect - deliver`).
    - Using the **Placement** controls, select **Within subroutine**.
    - From the **Subroutine** menu, select **deliver (`vcl_deliver`)**.
    - _(Optional)_ In the **Priority** field, enter the order in which you want the snippet to execute. Lower numbers execute first.
    - In the VCL editor, add the following code:

      ```vcl
      if (resp.status == 302 || resp.status == 301) {
        set req.http.redir = "true";
        set req.url = regsub(resp.http.Location, "http://s3.amazonaws.com/(.*)$", "/\1");
        set req.http.Fastly-Force-Shield = "yes";
        restart;
      }
      ```

11. Click **Add** to create the snippet.

12.   From the **Activate** menu, select **Activate on Production** to deploy your configuration changes.

> **NOTE:** 
>
> This article describes how to configure an integration with a service provided by a third party. As stated in our [Terms of Service](https://www.fastly.com/terms), we do not provide direct support for non-Fastly services.
>
>

## Related content

- [Working with hosts](https://www.fastly.com/documentation/guides/getting-started/hosts/working-with-hosts)
- [AWS S3 bucket origin code example](https://www.fastly.com/documentation/solutions/examples/using-s3-compatible-buckets-as-private-origins/)
- [VCL reference](https://www.fastly.com/documentation/reference/vcl/)
