How to add CORS to an S3 bucket in AWS CDK


Borislav Hadzhiev

Wed Apr 13 20223 min read


Photo by Amal S

Updated - Wed Apr 13 2022

Setting up CORS for an S3 bucket in CDK #

CORS is a mechanism that allows a server to use a combination of HTTP headers to indicate from which domains, other than its own, it receives requests.

By default servers only take requests made from applications hosted on the same domain.

Setting CORS configuration is important when we access resources from a different domain.

All S3 buckets are hosted on the domain, which is different from where we host our client applications, so we have to set up CORS.

We often have to set up CORS when working with S3 buckets, an example being when our backend generates an S3 presigned url, which our frontend then uses to upload a file to S3.

Since our frontend is hosted on a different domain than the S3 bucket, we have to set up CORS.

In order to set CORS on an S3 bucket we have to pass the cors prop to the Bucket construct.

The code for this article is available on GitHub

To demo setting up CORS, let's create a CDK app that consists of a single S3 bucket.

import * as s3 from 'aws-cdk-lib/aws-s3'; import * as cdk from 'aws-cdk-lib'; export class MyCdkStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props: cdk.StackProps) { super(scope, id, props); const s3Bucket = new s3.Bucket(this, id, { // 👇 Setting up CORS cors: [ { allowedMethods: [ s3.HttpMethods.GET, s3.HttpMethods.POST, s3.HttpMethods.PUT, ], allowedOrigins: ['http://localhost:3000'], allowedHeaders: ['*'], }, ], }); } } const app = new cdk.App(); new MyCdkStack(app, 'my-cdk-stack', { stackName: 'my-cdk-stack', env: { region: process.env.CDK_DEFAULT_REGION, account: process.env.CDK_DEFAULT_ACCOUNT, }, });
If you still use CDK version 1, switch to the cdk-v1 branch in the GitHub repository.

In the code snippet we have:

  1. Used the Bucket construct to create an S3 bucket

  2. We've set the CORS configuration of the bucket, where:

    The allowedMethods property is an array of the HTTP methods the domains in allowedOrigins are allowed to issue.

    The allowedOrigins property is an array of the domains that have permission to access the bucket. If you own a domain, that's what you should specify here.

    The allowedHeaders property specifies the response headers we want to be able to access in our frontend code.

Depending on the HTTP methods your frontend needs to use when making requests to the bucket, you might have to tweak the options.

For example if you're only making GET requests - just set GET as an allowed method.

Let's deploy the CDK stack and look at the results:

npx aws-cdk deploy

Our CloudFormation stack has been provisioned successfully:

cloudformation stack bucket

If we open the S3 console and look at the CORS config in the Permissions section, we can see that CORS is successfully configured:

cors config bucket

Troubleshooting CORS configuration of S3 Buckets #

Note that we often get CORS errors when making HTTP requests to S3 buckets or APIs, when we type in the endpoint or the HTTP method wrong.

For instance, if I make a POST request to I'll get a CORS error in the console of my browser.

The same happens if I send the request with a wrong HTTP method that the endpoint does not support, I'll still get a CORS error.

Further Reading #

Use the search field on my Home Page to filter through my more than 1,000 articles.