How can I use Amazon S3 to host a static website that uses API Gateway as the proxy?

7 minute read
1

I want to use Amazon API Gateway as a proxy for my static website hosted with Amazon Simple Storage Service (Amazon S3).

Resolution

You can use Amazon S3 to host static websites. You can also use either HTTP proxy integration or AWS service integration to configure API Gateway as a proxy for the Amazon S3 static website.

HTTP proxy integration

If your Amazon S3 static website is publicly accessible, then use HTTP integration and provide the S3 static website URL for the API Gateway.

If you haven't already done so, then follow the tutorial to configure a static website on Amazon S3.

Create a REST API

  1. Open the API Gateway console.
  2. For REST API, choose Build.
  3. For API name, enter a name for your REST API.
  4. Choose the Endpoint Type dropdown list, choose your endpoint type, and then choose Create API.
  5. In the navigation pane, choose Resources under your API name.
  6. Choose the Actions dropdown list, and then choose Create Resource.
  7. For Resource Name, enter a name. For example, key.
  8. For Resource Path, enter a path parameter. For example, {key}.
  9. Choose Create Resource.

Create the method for the root resource

  1. Choose the resource name {key}, choose the Actions dropdown list, and then choose Create Method.
  2. From the {key} dropdown list, choose GET, and then choose the check mark icon.
  3. For Integration type, choose HTTP, select Use HTTP Proxy integration, and then keep HTTP method as GET.
  4. For Endpoint URL, enter http://BUCKET_NAME.s3-website.REGION.amazonaws.com/{key} and then choose Save.

Deploy the REST API

  1. From the Actions dropdown list, choose Deploy API.
  2. From the Deployment stage dropdown list, choose [New Stage].
  3. For Stage name, enter a name. For example, Dev.
  4. Choose Deploy. From the Dev Stage Editor, note the Invoke URL. You'll need it later to test your API.
  5. Use a curl command similar to the following to test the API proxy for your Amazon S3 website:
curl -X GET https://API_ID.execute-api.REGION.amazonaws.com/index.html

AWS service integration

Configure the Amazon S3 static website

If your Amazon S3 static website is blocked for public access, then configure the website so that it's accessed only from the API proxy.

  1. If you haven't already done so, then follow the tutorial to configure a static website on Amazon S3.
    Note: Skip Step 3 of the tutorial and keep the default Block all public access setting turned on.

  2. Modify the bucket policy in Step 4 of the tutorial to allow API proxy to access only the Amazon S3 bucket similar to following example:

    {
      "Version": "2012-10-17",
      "Statement": [{
          "Sid": "APIProxyBucketPolicy",
          "Effect": "Allow",
          "Principal": {
            "Service": "apigateway.amazonaws.com"
          },
          "Action": "s3:GetObject",
          "Resource": "arn:aws:s3:::BUCKET_NAME/*",
          "Condition": {
            "ArnLike": {
              "aws:SourceArn": "arn:aws:execute-api:REGION:ACCOUNT:API_ID/*/GET/"
            }
          }
      }]
    }
  3. Create an AWS Identity and Access Management (IAM) policy with permission to the GetObject API to the Amazon S3 bucket.

    {
      "Version": "2012-10-17",
      "Statement": [{
        "Effect": "Allow",
        "Action": ["s3:GetObject"],
        "Resource": "*"
      }]
    }
  4. Create an IAM role and attach the IAM policy created in the previous step to this new role.

  5. Copy the IAM roles ARN. You'll need this in a later step.
    The IAM role must contain following trust policy for API Gateway to assume the role:

    {
      "Version": "2012-10-17",
      "Statement": [{
        "Sid": "",
        "Effect": "Allow",
        "Principal": {
            "Service": "apigateway.amazonaws.com"
        },
        "Action": "sts:AssumeRole"
      }]
    }

Create a REST API proxy for the Amazon S3 service

  1. Open the API Gateway console.
  2. Choose Create API.
  3. Choose REST API, and then choose Build.
  4. For API name, enter a name for your REST API.
  5. For Endpoint Type, choose the endpoint type depending on where the majority of client traffic originates from.
    Note: It's a best practice to use edge-optimized endpoints for public services that are accessed from the internet. Regional endpoints are used primarily for APIs that are accessed from within the same AWS Region.
  6. Choose Create API.

Create GET method for Root resource

The root method is configured for proxy requests to Amazon S3 static websites.

  1. With root resource "/" selected, choose the Actions dropdown list, and then choose Create Method.
  2. Select GET from the dropdown list, and then choose the check mark icon.
  3. For Integration type, choose AWS Service.
  4. Choose the AWS Region dropdown list, and then choose your Region.
  5. Choose the AWS Service dropdown list, and then choose Simple Storage Service (S3).
  6. For AWS Subdomain, leave this field blank.
  7. For HTTP method, select GET.
  8. For Action Type, choose Use path override.
  9. For Path override, enter the Amazon S3 bucket path similar to BUCKET_NAME/index.html.
  10. For Execution role, paste the IAM role ARN that you created previously.
  11. Choose Save.

This setup integrates the frontend API request GET https://your-api-host/stage/ to the S3 backend GET https://your-s3-host/index.html.

Create an API resource object

To access specific objects from a S3 bucket, create a resource named {object} that maps the object path in the frontend API request. For example, GET https://your-api-host/stage/home.html to the S3 backend GET https://your-s3-host/home.html.

  1. From Resources, choose the Actions dropdown list, and then choose Create Resource.
  2. For Resource Name, enter a name. For example, {object}.
  3. For Resource Path, enter a path. For example, {object}.
  4. Choose Create Resource.

Configure a GET method for the resource

  1. With {object} resource selected, choose the Actions dropdown list, and then choose Create Method.
  2. Choose GET from the dropdown list, and then choose the check mark icon.
  3. For Integration type, choose AWS Service.
  4. Choose the AWS Region dropdown list, and then choose your Region.
  5. Choose the AWS Service dropdown list, and then choose Simple Storage Service (S3).
  6. For AWS Subdomain, leave this field blank.
  7. For HTTP method, choose GET.
  8. For Action Type, choose Use path override.
  9. For Path override, enter your Amazon S3 bucket path similar to BUCKET_NAME/{object}.
  10. For Execution role, paste the IAM role ARN that you created previously.
  11. Choose Save.
  12. Choose GET for the Resource name {object}, then choose Integration Request.
  13. Expand URL Path Parameters, enter a Name value object and Mapped from value method.request.path.object, select the check box to save.

Set up the response header mappings for the GET method

Map the backend content type header parameter value to the frontend counterpart. This makes sure that the browser processes the response successfully with the content type.

  1. Choose GET, under Resources /, choose Method Response.
  2. Expand the arrow next to HTTP Status 200, under Response Headers for 200, chose Add Header.
  3. Choose the header Name as Content-Type, and then choose the check box to save.
  4. Choose Method Execution.
  5. Choose Integration Response, expand the arrow next to HTTP status regex.
  6. Expand Header Mappings, for Content-Type, enter the mapping value as integration.response.header.Content-Type.
  7. Repeat steps 1-6 for GET method under Resource /{object}.
  8. Repeat the steps in the Deploy the REST API section.

Test the API proxy

You can use a browser or a curl command to test the API proxy for your Amazon S3 static website:

Root (/) resource

curl -X GET https://API_ID.execute-api.REGION.amazonaws.com/STAGE_NAME/

{Object} resource

curl -X GET https://API_ID.execute-api.REGION.amazonaws.com/STAGE_NAME/home.html

Related information

Tutorial: Create a REST API as an Amazon S3 proxy in API Gateway

Hosting a static website using Amazon S3

Creating a REST API in Amazon API Gateway

Deploying a REST API from the API Gateway console

AWS OFFICIAL
AWS OFFICIALUpdated 9 months ago
6 Comments

Under Create the Method for the Root Resource step 4 it will not allow me to enter http://.s3-website-.amazonaws.com/{key} for endpoint URL. Is there something else I should add?

replied 10 months ago

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

profile pictureAWS
MODERATOR
replied 10 months ago

There seems to be a typo in "Configure a GET method for the resource" section, pt.9 "For Path override, enter your Amazon S3 bucket path similar to <bucket_name>/{object.".

The typo is - ' {object. ' Correction - ' {object} '

Sneha
replied 7 months ago

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

profile pictureAWS
MODERATOR
replied 7 months ago

The API gateway was returning content-type: application/json despite the s3 content type being set correctly. This was causing the page to display as text instead of rendered html by the browser. To resolve this, I added a header mapping to the 200 response:

method.response.header.Content-Type: "integration.response.header.Content-Type"

profile pictureAWS
replied 3 months ago

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

profile pictureAWS
MODERATOR
replied 3 months ago