如何使用 AWS CDK 添加 S3 BucketPolicy?
How to add S3 BucketPolicy with AWS CDK?
我想将这篇 CloudFormation 文章翻译成 CDK:
Type: AWS::S3::BucketPolicy
Properties:
Bucket:
Ref: S3BucketImageUploadBuffer
PolicyDocument:
Version: "2012-10-17"
Statement:
Action:
- s3:PutObject
- s3:PutObjectAcl
Effect: Allow
Resource:
- ...
查看 documentation here,我没有找到提供政策文件本身的方法。
CDK 的做法略有不同。我相信您应该使用 bucket.addToResourcePolicy
,如记录 here.
这是来自工作 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)]
})
);
基于@Thomas Wagner 的回答,我就是这样做的。我试图将存储桶限制在给定的 IP 范围内:
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
});
}
}
我能够使用 s3.arnForObjects() and iam.AnyPrincipal() 辅助函数,而不是直接指定 ARN 或委托人。
我要部署到存储桶的资产保存在我项目目录的根目录中名为 mysite
的目录中,然后通过调用 s3Deployment.BucketDeployment
进行引用。当然,这可以是您的构建过程有权访问的任何目录。
按照最初的问题,@thomas-wagner 的回答就是正确的选择。
如果有人来这里寻找如何在不创建对存储桶的依赖性的情况下为 CloudFront 分发创建存储桶策略,那么您需要使用 L1 构造 CfnBucketPolicy
(下面的粗略 C# 示例):
IOriginAccessIdentity originAccessIdentity = new OriginAccessIdentity(this, "origin-access-identity", new OriginAccessIdentityProps
{
Comment = "Origin Access Identity",
});
PolicyStatement bucketAccessPolicy = new PolicyStatement(new PolicyStatementProps
{
Effect = Effect.ALLOW,
Principals = new[]
{
originAccessIdentity.GrantPrincipal
},
Actions = new[]
{
"s3:GetObject",
},
Resources = new[]
{
Props.OriginBucket.ArnForObjects("*"),
}
});
_ = new CfnBucketPolicy(this, $"bucket-policy", new CfnBucketPolicyProps
{
Bucket = Props.OriginBucket.BucketName,
PolicyDocument = new PolicyDocument(new PolicyDocumentProps
{
Statements = new[]
{
bucketAccessPolicy,
},
}),
});
其中 Props.OriginBucket
是 IBucket
的一个实例(只是一个桶)。
我想将这篇 CloudFormation 文章翻译成 CDK:
Type: AWS::S3::BucketPolicy
Properties:
Bucket:
Ref: S3BucketImageUploadBuffer
PolicyDocument:
Version: "2012-10-17"
Statement:
Action:
- s3:PutObject
- s3:PutObjectAcl
Effect: Allow
Resource:
- ...
查看 documentation here,我没有找到提供政策文件本身的方法。
CDK 的做法略有不同。我相信您应该使用 bucket.addToResourcePolicy
,如记录 here.
这是来自工作 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)]
})
);
基于@Thomas Wagner 的回答,我就是这样做的。我试图将存储桶限制在给定的 IP 范围内:
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
});
}
}
我能够使用 s3.arnForObjects() and iam.AnyPrincipal() 辅助函数,而不是直接指定 ARN 或委托人。
我要部署到存储桶的资产保存在我项目目录的根目录中名为 mysite
的目录中,然后通过调用 s3Deployment.BucketDeployment
进行引用。当然,这可以是您的构建过程有权访问的任何目录。
按照最初的问题,@thomas-wagner 的回答就是正确的选择。
如果有人来这里寻找如何在不创建对存储桶的依赖性的情况下为 CloudFront 分发创建存储桶策略,那么您需要使用 L1 构造 CfnBucketPolicy
(下面的粗略 C# 示例):
IOriginAccessIdentity originAccessIdentity = new OriginAccessIdentity(this, "origin-access-identity", new OriginAccessIdentityProps
{
Comment = "Origin Access Identity",
});
PolicyStatement bucketAccessPolicy = new PolicyStatement(new PolicyStatementProps
{
Effect = Effect.ALLOW,
Principals = new[]
{
originAccessIdentity.GrantPrincipal
},
Actions = new[]
{
"s3:GetObject",
},
Resources = new[]
{
Props.OriginBucket.ArnForObjects("*"),
}
});
_ = new CfnBucketPolicy(this, $"bucket-policy", new CfnBucketPolicyProps
{
Bucket = Props.OriginBucket.BucketName,
PolicyDocument = new PolicyDocument(new PolicyDocumentProps
{
Statements = new[]
{
bucketAccessPolicy,
},
}),
});
其中 Props.OriginBucket
是 IBucket
的一个实例(只是一个桶)。