I want to use Amazon API Gateway to create an API as a proxy for my static website. Then, I want to host the website on Amazon Simple Storage Service (Amazon S3).
Resolution
To use Amazon S3 to host a static website that uses API Gateway as the proxy, use an HTTP integration or an AWS service integration.
Use an HTTP integration
If your static website is publicly accessible, then use an HTTP integration and provide the Amazon S3 static website URL for the API.
Configure a static website on Amazon S3. Then, use the API Gateway console to create a REST API and a method for the root resource, and then deploy your REST API.
Create a REST API
Complete the following steps:
- Open the API Gateway console.
- Choose Create API.
- Under REST API, choose Build.
- For API name, enter a name for your REST API.
- From the API endpoint type dropdown list, choose your endpoint type, and then choose Create API.
- In the navigation pane, choose Resources under your API.
- Choose Create resource.
- For Resource path, keep as /.
- For Resource name, enter a name. For example, key.
- Choose Create resource.
Create the method for the root resource
Complete the following steps:
- Under Resources, select the resource you created. For example, /key.
- Under Methods, choose Create method.
- From the Method type dropdown list, choose GET.
- For Integration type, choose HTTP.
- Select HTTP proxy integration.
- From the HTTP method dropdown list, choose GET.
- For Endpoint URL, enter http://BUCKET_NAME.s3-website.REGION.amazonaws.com/key.
Note: Replace BUCKET_NAME with your bucket name, REGION with your bucket's Region, and key with the name of your resource.
- Choose Create method.
Deploy the REST API
Complete the following steps:
- Choose Deploy API.
- From the Stage dropdown list, choose *New Stage*.
- For Stage name, enter a name. For example, STAGE_NAME.
- Choose Deploy.
- Under Stage details, note the invoke URL to test your API.
- To test the API proxy for your S3 website, run the following curl command:
curl -X GET https://API_ID.execute-api.REGION.amazonaws.com/STAGE_NAME/index.html
Note: Replace API_ID with your API ID, REGION with your Region, and STAGE_NAME with the name of your stage.
Use an AWS service integration
Configure the S3 static website
If your S3 static website is blocked from public access, then configure the website so that you can access it only from the API proxy.
Complete the following steps:
- Configure a static website on Amazon S3.
Note: When you configure the static website, skip the Step 3: Edit Block Public Access settings section. Keep the default Block all public access setting on.
- Modify a bucket policy that makes your bucket content publicly available to allow the API proxy to access only the S3 bucket. Example bucket policy:
{
"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_ID:API_ID/*/GET/"
}
}
}]
}
Note: Replace BUCKET_NAME with your bucket name, REGION with your region, ACCOUNT_ID with your AWS account ID, and API_ID with your API ID.
- Create an AWS Identity and Access Management (IAM) policy to allow the GetObject API access to the S3 bucket. Example IAM policy:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": [
"arn:aws:s3:::BUCKET_NAME/*"
]
}]
}
Note: Replace BUCKET_NAME with your bucket name.
- Create an IAM role, and then attach the preceding IAM policy.
- Note the IAM role's Amazon Resource Name (ARN).
Note: The IAM role must contain the 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 S3 service
Complete the following steps:
- Open the API Gateway console.
- Choose Create API.
- For REST API, choose Build.
- For API name, enter a name for your REST API.
- From the API endpoint type dropdown list, choose the endpoint type based on where the majority of client traffic originates from.
Note: It's a best practice to use edge-optimized endpoints for public services that client traffic accesses from the internet. If your client traffic accesses your APIs only from within the same AWS Region, then use Regional endpoints.
- Choose Create API.
Create GET method for the root resource
Complete the following steps:
- Select the root resource /.
- Choose Create method.
- From the Method type dropdown list, choose GET.
- For Integration type, choose AWS service.
- From the AWS Region dropdown list, choose your Region.
- From the AWS service dropdown list, choose Simple Storage Service (S3).
- For AWS subdomain, keep the field blank.
- From the HTTP method dropdown list, choose GET.
- For Action type, choose Use path override.
- For Path override, enter your S3 bucket path. For example, BUCKET_NAME/index.html.
- For Execution role, enter the IAM role's ARN.
- Choose Create method.
Note: The setup integrates the frontend GET API request https://your-api-host/stage/ to the GET S3 backend https://your-s3-host/index.html.
Create an API resource object
Complete the following steps:
- Choose Create resource.
- For Resource Path, keep as /.
- For Resource name, enter a name. For example, object.
- Choose Create resource.
Configure a GET method for the resource
Complete the following steps:
- Under Resources, select the resource you created. For example, /object.
- Complete steps 2-12 in the Create GET method for the root resource section.
- Choose GET, and then choose Integration request.
Note: Replace object with the name of your resource.
- Choose Edit.
- Expand URL path parameters, and then choose Add path parameter.
- Under Name, enter the name of your resource.
- Under Mapped from, enter the value as method.request.path.object.
Note: Replace object with the name of your resource.
- Choose Save.
Set up the response header mappings for the GET method
You must map the backend content type header parameter value to the frontend counterpart so that the browser processes the response with the content type.
Complete the following steps:
- Under Resources, select /.
- Choose GET, and then choose Method response.
- Under Response 200, choose Edit.
- Under Header name, choose Add header.
- Set the Name as Content-Type.
- Choose Save.
- Choose Integration response, and then choose Edit.
- Under Header mappings, next to Content-Type, enter the Mapping value as integration.response.header.Content-Type.
- Repeat steps 2-8 for the GET method under the /object resource.
Note: Replace object with the name of your resource.
Deploy the REST API
Complete the following steps:
- Choose Deploy API.
- From the Stage dropdown list, choose *New Stage*.
- For Stage name, enter a name. For example, STAGE_NAME.
- Choose Deploy.
- Under Stage details, note the invoke URL to test your API.
To test the API proxy for your S3 static website, run a curl command.
Note: For the following examples, replace API_ID with your API ID, REGION with your Region, and STAGE_NAME with the name of your stage.
To test the root resource, run the following curl command:
curl -X GET https://API_ID.execute-api.REGION.amazonaws.com/STAGE_NAME/
To test the object resource, run the following curl command:
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
Host a static website using Amazon S3
Develop REST APIs in API Gateway
Create a deployment for a REST API in API Gateway