S3 Bucket Policy Example in AWS CDK

avatar

Borislav Hadzhiev

Wed Apr 28 20213 min read

banner

Photo by Muye Ma

In order to create a bucket policy in AWS CDK, we have to use the `addToResourcePolicy` method on a `Bucket` instance.

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/aws-iam';
import * as s3 from '@aws-cdk/aws-s3';
import * as cdk from '@aws-cdk/core';

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 in 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 cdk deploy command, we can see that the bucket policy has been attached:

bucket policy attached

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

lib/cdk-starter-stack.ts
import * as iam from '@aws-cdk/aws-iam';
import * as s3 from '@aws-cdk/aws-s3';
import * as cdk from '@aws-cdk/core';

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. We've passed in the bucket we created in the props object.
  3. we added a policy statement to the S3 bucket policy. In our case the statement allows the lambda service to get objects from the bucket.

Let's execute a deployment:

shell
npx 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 #

Join my newsletter

I'll send you 1 email a week with links to all of the articles I've written that week

Buy Me A Coffee