I wanna translate this CloudFormation piece into CDK:
Type: AWS::S3::BucketPolicy
Properties:
Bucket:
Ref: S3BucketImageUploadBuffer
PolicyDocument:
Version: "2012-10-17"
Statement:
Action:
- s3:PutObject
- s3:PutObjectAcl
Effect: Allow
Resource:
- ...
Looking at the documentation here, I don't see a way to provide the policy document itself.
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.
In order to get the Arn of a resource we have to use the resource-specific resourceNameArn property, for example: bucketArn for an S3 bucket, instantiated via the Bucket construct. tableArn for a Dynamodb table instantiated via the Table construct. functionArn for a Lambda function instantiated via the Function ...
Building on @Thomas Wagner's answer, this is how I did this. I was trying to limit the bucket to a given IP range:
import * as cdk from '@aws-cdk/core';
import * as s3 from '@aws-cdk/aws-s3';
import * as s3Deployment from '@aws-cdk/aws-s3-deployment';
import * as iam from '@aws-cdk/aws-iam';
export class StaticSiteStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Bucket where frontend site goes.
const mySiteBucket = new s3.Bucket(this, 'mySiteBucket', {
websiteIndexDocument: "index.html"
});
let ipLimitPolicy = new iam.PolicyStatement({
actions: ['s3:Get*', 's3:List*'],
resources: [mySiteBucket.arnForObjects('*')],
principals: [new iam.AnyPrincipal()]
});
ipLimitPolicy.addCondition('IpAddress', {
"aws:SourceIp": ['1.2.3.4/22']
});
// Allow connections from my CIDR
mySiteBucket.addToResourcePolicy(ipLimitPolicy);
// Deploy assets
const mySiteDeploy = new s3Deployment.BucketDeployment(this, 'deployAdminSite', {
sources: [s3Deployment.Source.asset("./mysite")],
destinationBucket: mySiteBucket
});
}
}
I was able to use the s3.arnForObjects() and iam.AnyPrincipal() helper functions rather than specifying ARNs or Principals directly.
The assets I want to deploy to the bucket are kept in the root of my project directory in a directory called mysite
, and then referenced via a call to s3Deployment.BucketDeployment
. This can be any directory your build process has access to, of course.
This is an example from a working CDK-Stack:
artifactBucket.addToResourcePolicy(
new PolicyStatement({
resources: [
this.pipeline.artifactBucket.arnForObjects("*"),
this.pipeline.artifactBucket.bucketArn],
],
actions: ["s3:List*", "s3:Get*"],
principals: [new ArnPrincipal(this.deploymentRole.roleArn)]
})
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With