Skip to main content

Use an AWS S3 static website as a CDN origin

Orange's CDN can cache and deliver objects from a public Amazon S3 static website endpoint. A private S3 origin is required when objects must not be exposed by a public-read bucket policy.

The public-read policy in this procedure allows anyone to retrieve matching bucket objects. Do not use it for private or sensitive content.

S3 website and CDN resource

  1. 1

    Create and populate the S3 bucket

    1. Log in to the AWS Management Console and open Amazon S3.

    2. Create a General purpose bucket and select its AWS Region.

    3. Upload the website objects, including index.html and logo.png. The verification steps below request logo.png.

  2. 2

    Allow public bucket policies

    Account-level Block Public Access settings must permit public bucket policies. If those settings are centrally managed, contact the AWS account administrator before changing the bucket.

    1. Open the bucket and select Permissions.

    2. Under Block public access (bucket settings), click Edit.

    3. Clear Block all public access.

    4. Select I acknowledge that the current settings might result in this bucket and the objects within becoming public.

    Block Public Access options cleared with the public-access acknowledgment selected

    5. Click Save changes, then confirm the change in the dialog.

  3. 3

    Enable static website hosting

    1. Open the bucket's Properties tab.

    2. Under Static website hosting, click Edit.

    3. Set Static website hosting to Enable.

    4. Set Hosting type to Host a static website.

    5. In Index document, enter index.html or the name of another uploaded default object.

    Static website hosting enabled with index.html as the index document

    6. Click Save changes and copy the Bucket website endpoint.

    Use the endpoint provided by AWS instead of constructing it manually because its format depends on the Region.

  4. 4

    Add a public-read bucket policy

    On the Permissions tab, click Edit under Bucket policy. Replace my-bucket with the bucket name in this policy:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "PublicReadGetObject",
          "Effect": "Allow",
          "Principal": "*",
          "Action": "s3:GetObject",
          "Resource": "arn:aws:s3:::my-bucket/*"
        }
      ]
    }
    

    Click Save changes.

  5. 5

    Test the S3 website endpoint

    Append /logo.png to the HTTP website endpoint copied from AWS and open the resulting URL.

    Confirm that the object loads without a 403 or 404 response. Keep the URL on HTTP, because an S3 website endpoint does not accept HTTPS.

  6. 6

    Create the CDN resource

    1. Log in to the CDB Customer Portal and navigate to CDN > CDN resources.

    2. Click Create CDN resource.

    3. In Add domain, enter the custom domain.

    4. In Origin, keep Specify content origin selected.

    5. Select URL.

    6. Select HTTP as the origin pull protocol.

    7. In Origin source, enter the S3 website endpoint without http:// and without an object path.

    8. Click Create.

    The resource can stay in the Processing status at first, so wait until the status changes to Active before testing delivery.

  7. 7

    Configure the custom domain

    1. Configure the custom domain by pointing its CNAME record to the *.gcdn.co hostname shown in the CDN resource's Setup guide.

    2. For HTTPS delivery, attach an SSL certificate to the custom domain.

  8. 8

    Test delivery through the CDN

    1. Open the verification object through the custom CDN domain:

    https://cdn.site.com/logo.png
    

    2. Confirm that the object loads.

Create a CDN resource that pulls a public Amazon S3 website endpoint over HTTP and serves it on a custom domain.

An API token is required. The bucket website endpoint comes from static website hosting. Private objects use a private origin.

export GCORE_API_KEY="{YOUR_API_KEY}"

Create the CDN resource

Set origin to the website endpoint hostname without http:// or an object path, and set originProtocol to HTTP, because an S3 website endpoint does not accept HTTPS. The create endpoint stores that hostname as the source of a new origin group.

ParameterRequiredDescription
cnameYesCustom domain that viewers request
originYesWebsite endpoint hostname, without a scheme or an object path
originProtocolNoPull protocol. Use HTTP for an S3 website endpoint. Defaults to HTTP
from gcore import CDB

client = CDB()  # Reads GCORE_API_KEY from env

resource = client.cdn.cdn_resources.create(
    cname="cdn.site.com",
    origin="my-bucket.s3-website-eu-west-1.amazonaws.com",
    origin_protocol="HTTP",
)
print(resource.id, resource.cname, resource.origin_protocol)
package main

import (
    "context"
    "fmt"

    gcore "github.com/G-Core/gcore-go"
    "github.com/G-Core/gcore-go/cdn"
)

func main() {
    client := gcore.NewClient() // Reads GCORE_API_KEY from env
    ctx := context.Background()

    resource, err := client.CDN.CDNResources.New(ctx, cdn.CDNResourceNewParams{
        Cname:          "cdn.site.com",
        Origin:         gcore.String("my-bucket.s3-website-eu-west-1.amazonaws.com"),
        OriginProtocol: cdn.CDNResourceNewParamsOriginProtocolHTTP,
    })
    if err != nil {
        panic(err)
    }
    fmt.Println(resource.ID, resource.Cname, resource.OriginProtocol)
}
curl -X POST "https://api.cdb-staging.cdn.orange.com/cdn/resources" \
  -H "Authorization: APIKey $GCORE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "cname": "cdn.site.com",
    "origin": "my-bucket.s3-website-eu-west-1.amazonaws.com",
    "originProtocol": "HTTP"
  }'

The API returns:

{
  "id": 1001,
  "cname": "cdn.site.com",
  "active": true,
  "originProtocol": "HTTP",
  "originGroup": 1002
}

Configure the custom domain

Point the custom domain CNAME record at the printed resource ID with .gcdn.co appended — 1001.gcdn.co when that ID is 1001. Delivery over HTTPS on that domain uses an SSL certificate.

Test delivery through the CDN

Open the verification object on the custom domain. The same file already loaded from the S3 website endpoint, so a successful response here means the CDN is serving it:

https://cdn.site.com/logo.png

Declare a CDN resource that pulls a public Amazon S3 website endpoint over HTTP with the Terraform provider v2. Private objects use a private origin.

Create the CDN resource

The website endpoint does not accept HTTPS, so origin_protocol is HTTP. Set source to the endpoint hostname without a scheme or an object path.

resource "gcore_cdn_origin_group" "example" {
  name = "my-origin-group"

  sources = [
    {
      source  = "my-bucket.s3-website-eu-west-1.amazonaws.com"
      enabled = true
    }
  ]
}

resource "gcore_cdn_resource" "example" {
  cname           = "cdn.site.com"
  origin_group    = gcore_cdn_origin_group.example.id
  origin_protocol = "HTTP"
}

Configure the custom domain

Point the custom domain CNAME record at the *.gcdn.co hostname in the CDN resource setup guide. Delivery over HTTPS on that domain uses an SSL certificate.

Test delivery through the CDN

Open the verification object on the custom domain. The same file already loaded from the S3 website endpoint:

https://cdn.site.com/logo.png

Delete the CDN resource

Remove both resource blocks. The next terraform apply deletes the CDN resource, then the origin group.

# Remove the CDN resource and the origin group:
# resource "gcore_cdn_origin_group" "example" {
#   name = "my-origin-group"
#
#   sources = [
#     {
#       source  = "my-bucket.s3-website-eu-west-1.amazonaws.com"
#       enabled = true
#     }
#   ]
# }
#
# resource "gcore_cdn_resource" "example" {
#   cname           = "cdn.site.com"
#   origin_group    = gcore_cdn_origin_group.example.id
#   origin_protocol = "HTTP"
# }
terraform apply

Creating a CDN resource does not rewrite absolute asset URLs in HTML or application code. If they still point to the S3 website endpoint or another origin domain, update them to the CDN domain. Then confirm in the browser Network panel that the requests use the CDN domain.