Static Site With S3

Creating a site using Amazon S3 as an Origin

This guide describes the process of creating a CDN site using StackPath's API and setting it up to use an Amazon S3 bucket as its origin. StackPath's support portal also describes how this can be done from our customer portal.

Placing StackPath's CDN in front of your S3 bucket has important advantages both for you and for your customers. Your S3 assets will be cached at StackPath's CDN edges, reducing bandwidth costs and lowering latency to deliver assets to customers. Cached assets also provide a way to deliver S3 assets even when S3 is down. This guide also shows how to use Amazon's secretAccessKey and accessKeyId to allow StackPath's CDN to connect to a protected or private S3 bucket.

If you haven't already created StackPath API credentials, visit the getting started guide. Once you have API credentials, you're ready to begin creating your first CDN site with the API. This guide assumes you've already obtained your bearer token and created a stack with CDN service, which is also described in the getting started guide linked above.

Create a CDN Site

First, make the API call to create the site. Replace YOUR_STACK_ID with the UUID of the stack you'd like to create your stack on. You will also need to replace the BEARER_TOKEN with the bearer token provided by OAuth as listed in the getting started guide. Lastly, replace example.org with the domain of your website and my-bucket.s3.amazonaws.com with your S3 bucket's domain name. Open a terminal and run the following:

curl -X POST https://gateway.stackpath.com/cdn/v1/stacks/YOUR_STACK_ID/sites \
  -H "Authorization: bearer BEARER_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '
{
  "domain": "example.org",
  "origin": {
    "path": "/",
    "hostname": "my-bucket.s3.amazonaws.com",
    "port": 80,
    "securePort": 443 
  },
  "features": [
    "CDN"
  ],
  "type": "CDN"
}'

This request returns a JSON object that looks something like this:

{
  "site":{
    "id": "0ac0a3a7-ff9d-421f-8cce-4f3d55db93ae",
    "stackId": "993aba44-1234-433d-be5d-72dbdf62f6a5",
    "label": "my.website.com",
    "status": "ACTIVE",
    "createdAt": "2019-02-08T21:37:25.742801Z",
    "updatedAt": "2019-02-08T21:37:32.312754Z",
    "enabled": true,
    "type": "CDN"
  }
}

The ID in the above JSON object is what we will use as the SITE_ID going forward in subsequent API calls.

Get the ID of the Root CDS Scope of Your Newly Created Site

Our API exposes the full power of the configuration system to you. Configurations are exposed on a scope level, meaning a directory structure accessible over the CDN. For example, in the URL "http://www.example.org/blog/styles.css", "/" and "/blog" are both valid scopes where individual configuration policies may exist, which will affect the delivery of the assets within those directories. Each scope has a platform and a path attribute which tell the CDN which incoming path to map to. For most simple use cases, you'll want to tie configuration to the CDS root scope. "CDS" is our internal name for "Content Delivery Service" and is the internal platform name we use to indicate that a scope is for CDN traffic.

For this request, replace YOUR_STACK_ID with your stack ID, and use the ID provided by the previous API call to use as the value for SITE_ID. Use the same BEARER_TOKEN here for this call as in the previous call.

curl -X GET https://gateway.stackpath.com/cdn/v1/stacks/YOUR_STACK_ID/sites/SITE_ID/scopes \
  -H "Authorization: bearer BEARER_TOKEN" \
  -H "Content-Type: application/json"

This request will return a JSON object that looks something like:

{
  "pageInfo": {
    "totalCount": "2",
    "endCursor": "1"
  },
  "results": [
    {
      "id": "80492418-9896-4735-80e3-adb37019e001",
      "platform": "CDS",
      "path": "/"
    },
    {
      "id": "c4a4b765-8f8a-4233-8459-935871d8d60d",
      "platform": "ALL",
      "path": "/"
    }
  ]
}

Enable S3 as your Origin

Within the results section of the previous API call, you will want to grab the ID value for the result where platform is "CDS". In the response above it's "80492418-9896-4735-80e3-adb37019e001". Use this value in the next API call. The next call to the API tells our platform that you want to set up S3 as your origin on this CDN site. Make sure to replace SECRET_ACCESS_KEY and ACCESS_KEY_ID with the values provided by Amazon when you setup your S3 bucket. This is what allows our CDN platform to securely login to your S3 bucket. Make sure the awsRegion value is correct based on where your S3 bucket lives. In this example, we're using "us-east-2" for demonstration purposes. Last, make sure the originPull value is set correctly to the fully qualified domain name of your S3 bucket. We send this host header to Amazon to make sure it gets routed correctly.

curl -X PATCH https://gateway.stackpath.com/cdn/v1/stacks/YOUR_STACK_ID/sites/SITE_ID/scopes/SCOPE_ID/configuration \
  -H "Authorization: bearer BEARERTOKEN" \
  -H "Content-Type: application/json" \
  -d '
{
  "configuration": {
    "awsSignedOriginPullV4": [
      {
        "enabled": true,
        "secretAccessKey": "SECRET_ACCESS_KEY",
        "accessKeyId": "ACCESS_KEY_ID",
        "awsRegion": "us-east-2",
        "awsService": "s3",
        "expireTimeSeconds": 5,
        "authenticationType": "header"
      }
    ],
    "staticHeader": [
      {
        "originPull": "Host: my-bucket.s3.amazonaws.com"
      }
    ]
  }
}'

This request returns a JSON object containing the scope's full configuration options currently set. The snippet below is the important excerpt from the response. It should contain:

{
  "configuration": {
    "accessLogs": {
      "id": "435462008",
      "enabled": false
    },
    "awsSignedOriginPullV4": [
      {
        "id": "3016776472",
        "enabled": true,
        "accessKeyId": "ACCESS_KEY_ID",
        "awsRegion": "us-east-2",
        "awsService": "s3",
        "expireTimeSeconds": 5,
        "authenticationType": "header"
      }
    ],
    "staticHeader": [
      {
        "id": "735920235",
        "originPull": "Host: my-bucket.s3.amazonaws.com"
      }
    ]
  }
}

The accessKeyId is returned in the response, but the API will never return the secretAccessKey. Once it goes in, it cannot ever be retrieved. You will only ever need to include the secretAccessKey value in your PATCH request if it changes or you want to connect this CDN site to a different S3 bucket. To remove it completely from StackPath's platform, either delete the configuration policy or delete the CDN site.

If you want to put even more security in front of this CDN endpoint, you can always add our WAF service to protect your CDN from attacks, as well as use serverless scripting to implement your own custom authentication using JWT or other mechanisms to make sure only validated requests are made to get S3 assets. More info on this is available on Stackpath's serverless scripting examples page at GitHub. While you're there, check out the serverless CLI utility which makes deploying serverless scripts as easy as running a single command.

If you have a request, comment, or just want to say hi please send an email. If you
need immediate assistance our 24/7 support is here to help.