In this blog post, we will explore how to implement S3 bucket policies using AWS CDK (Cloud Development Kit). We'll cover two approaches: explicit and implicit. By the end of this guide, you will understand how to create S3 bucket policies in a structured and reusable manner using AWS CDK.
Prerequisites
Before we dive into the code, ensure you have the following installed:
AWS CDK
AWS CLI
Node.js
TypeScript
The folder structure for the project will look like below.
S3-BUCKET-POLICY-AWS-CDK
├── bin
│ └── app.ts
├── cdk.out
├── node_modules
├── stacks
│ ├── index.ts
│ ├── s3-bucket-policy-explicit-stack.ts
│ └── s3-bucket-policy-implicit-stack.ts
├── test
├── .gitignore
├── .npmignore
├── cdk.json
├── jest.config.js
├── package.json
├── README.md
└── tsconfig.json
Link to full GitHub project.
Step 1: Setting Up the Project
First, let's initialize the project and install the necessary dependencies:
mkdir S3-BUCKET-POLICY-AWS-CDK
cd S3-BUCKET-POLICY-AWS-CDK
cdk init app --language=typescript
Step 2: Defining the Explicit S3 Bucket Policy Stack
We will start with the explicit method, where we create a separate BucketPolicy
resource and attach it to the S3 bucket.
Create a new file stacks/s3-bucket-policy-explicit-stack.ts
and add the following code:
import { RemovalPolicy, Stack, StackProps } from 'aws-cdk-lib';
import { Effect, PolicyStatement, ServicePrincipal } from 'aws-cdk-lib/aws-iam';
import { Bucket, BucketPolicy } from 'aws-cdk-lib/aws-s3';
import { Construct } from 'constructs';
export class S3BucketPolicyExplicitStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// Create the S3 bucket
const explicitBucket = new Bucket(this, 'explicit-s3-bucket', {
removalPolicy: RemovalPolicy.DESTROY,
});
// Create the bucket policy
const bucketPolicy = new BucketPolicy(this, 'explicit-bucket-policy-id', {
bucket: explicitBucket,
});
// Add policy statements to the bucket policy
bucketPolicy.document.addStatements(
new PolicyStatement({
effect: Effect.ALLOW,
principals: [new ServicePrincipal('lambda.amazonaws.com')],
actions: ['s3:GetObject'],
resources: [`${explicitBucket.bucketArn}/*`],
}),
);
}
}
Step 3: Defining the Implicit S3 Bucket Policy Stack
Next, we will use the implicit method, where we add the bucket policy directly to the bucket resource.
Create a new file stacks/s3-bucket-policy-implicit-stack.ts
and add the following code:
import { RemovalPolicy, Stack, StackProps } from 'aws-cdk-lib';
import { Effect, PolicyStatement, ServicePrincipal } from 'aws-cdk-lib/aws-iam';
import { Bucket } from 'aws-cdk-lib/aws-s3';
import { Construct } from 'constructs';
export class S3BucketPolicyImplicitStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// Create the S3 bucket
const implicitBucket = new Bucket(this, 'implicit-s3-bucket', {
removalPolicy: RemovalPolicy.DESTROY,
});
// Create a bucket policy automatically
implicitBucket.addToResourcePolicy(
new PolicyStatement({
effect: Effect.ALLOW,
principals: [new ServicePrincipal('lambda.amazonaws.com')],
actions: ['s3:GetObject'],
resources: [`${implicitBucket.bucketArn}/*`],
}),
);
// Access the bucket policy
implicitBucket.policy?.document.addStatements(
new PolicyStatement({
effect: Effect.ALLOW,
principals: [new ServicePrincipal('lambda.amazonaws.com')],
actions: ['s3:GetBucketTagging'],
resources: [implicitBucket.bucketArn],
}),
);
}
}
Step 4: Setting Up the Application Entry Point
Now, let's set up the application entry point to deploy these stacks. Update the bin/app.ts
file as follows:
#!/usr/bin/env node
import 'source-map-support/register';
import { App } from 'aws-cdk-lib';
import { S3BucketPolicyExplicitStack, S3BucketPolicyImplicitStack } from '../stacks';
const app = new App();
new S3BucketPolicyImplicitStack(app, 'S3BucketPolicyImplicitStack', { });
new S3BucketPolicyExplicitStack(app, 'S3BucketPolicyExplicitStack', { });
Step 5: Deploying the Stacks
Finally, deploy the stacks using the following commands:
cdk bootstrap
cdk deploy S3BucketPolicyImplicitStack
cdk deploy S3BucketPolicyExplicitStack
Conclusion
In this blog post, we demonstrated how to create and manage S3 bucket policies using AWS CDK in both explicit and implicit ways. This approach provides flexibility and a clear structure for managing your infrastructure as code.
Feel free to reach out in the comments if you have any questions or run into issues.
Find the complete CDK code below.