S3 Bucket Policy Example in AWS CDK

avatar

Borislav Hadzhiev

Last updated: Apr 14, 2022

banner

Check out my new book

Creating an S3 Bucket Policy in AWS CDK #

Bucket policies are used to grant permissions to an S3 bucket.

There are 2 ways to create a bucket policy in AWS CDK:

The approach with the addToResourcePolicy method is implicit - once we add a policy statement to the bucket, CDK automatically creates a bucket policy for us.

The second approach is explicit and a bit easier for the reader of our code to understand.

The code for this article is available on GitHub

Let's look at an example of both. We will start with the addToResourcePolicy method first:

lib/cdk-starter-stack.ts
import * as iam from 'aws-cdk-lib/aws-iam'; import * as s3 from 'aws-cdk-lib/aws-s3'; import * as cdk from 'aws-cdk-lib'; export class CdkStarterStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); // 👇 create the s3 bucket const bucket1 = new s3.Bucket(this, 'bucket-id-1', { removalPolicy: cdk.RemovalPolicy.DESTROY, }); // 👇 `addToResourcePolicy` creates a Bucket Policy automatically bucket1.addToResourcePolicy( new iam.PolicyStatement({ effect: iam.Effect.ALLOW, principals: [new iam.ServicePrincipal('lambda.amazonaws.com')], actions: ['s3:GetObject'], resources: [`${bucket1.bucketArn}/*`], }), ); // 👇 access the bucket policy bucket1.policy?.document.addStatements( new iam.PolicyStatement({ effect: iam.Effect.ALLOW, principals: [new iam.ServicePrincipal('lambda.amazonaws.com')], actions: ['s3:GetBucketTagging'], resources: [bucket1.bucketArn], }), ); } }

Let's go over what we did in the code snippet.

  1. We created an s3 bucket
  2. We used the addToResourcePolicy method on the bucket instance passing it a policy statement as the only parameter. A bucket policy was automatically created for us by CDK once we added a policy statement.
  3. We directly accessed the bucket policy to add another policy statement to it

After I've ran the npx aws-cdk deploy command, we can see that the bucket policy has been attached:

bucket policy attached

Let's look at an example, where we use the explicit approach - by instantiating the BucketPolicy class to achieve the same result.

lib/cdk-starter-stack.ts
import * as iam from 'aws-cdk-lib/aws-iam'; import * as s3 from 'aws-cdk-lib/aws-s3'; import * as cdk from 'aws-cdk-lib'; export class CdkStarterStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); // ... rest // 👇 create the s3 bucket const bucket2 = new s3.Bucket(this, 'bucket-id-2', { removalPolicy: cdk.RemovalPolicy.DESTROY, }); // 👇 create the bucket policy const bucketPolicy = new s3.BucketPolicy(this, 'bucket-policy-id-2', { bucket: bucket2, }); // 👇 add policy statements ot the bucket policy bucketPolicy.document.addStatements( new iam.PolicyStatement({ effect: iam.Effect.ALLOW, principals: [new iam.ServicePrincipal('lambda.amazonaws.com')], actions: ['s3:GetObject'], resources: [`${bucket2.bucketArn}/*`], }), ); } }

Let's go over the code snippet.

  1. We created an S3 bucket
  2. We created a bucket policy by instantiating the BucketPolicy class.
  3. We added a policy statement to the S3 bucket policy. The statement allows the lambda service to get objects from the bucket.

Let's run the deploy command:

shell
npx aws-cdk deploy

If we take a look at the S3 management console, we can see that the bucket policy has been attached successfully:

bucket policy attached

Further Reading #

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