简体   繁体   English

如何使用 AWS CDK 添加 S3 BucketPolicy?

[英]How to add S3 BucketPolicy with AWS CDK?

I wanna translate this CloudFormation piece into 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:
        - ...

Looking at the documentation here , I don't see a way to provide the policy document itself.查看此处文档,我看不到提供策略文档本身的方法。

This is an example from a working CDK-Stack:这是来自工作 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)]
      })
    );

Building on @Thomas Wagner's answer, this is how I did this.基于@Thomas Wagner 的回答,我就是这样做的。 I was trying to limit the bucket to a given IP range:我试图将存储桶限制为给定的 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
    });

  }
}

I was able to use the s3.arnForObjects() and iam.AnyPrincipal() helper functions rather than specifying ARNs or Principals directly.我能够使用s3.arnForObjects()iam.AnyPrincipal()辅助函数,而不是直接指定 ARN 或 Principals。

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 .我想要部署到存储桶的资产保存在我的项目目录的根目录中名为mysite目录中,然后通过调用s3Deployment.BucketDeployment进行s3Deployment.BucketDeployment This can be any directory your build process has access to, of course.当然,这可以是您的构建过程可以访问的任何目录。

The CDK does this a little differently. CDK 的做法略有不同。 I believe you are supposed to use bucket.addToResourcePolicy , as documented here .我相信您应该使用bucket.addToResourcePolicy ,如此处所述

As per the original question, then the answer from @thomas-wagner is the way to go.根据最初的问题,@thomas-wagner 的答案就是要走的路。

If anyone comes here looking for how to create the bucket policy for a CloudFront Distribution without creating a dependency on a bucket then you need to use the L1 construct CfnBucketPolicy (rough C# example below):如果有人来这里寻找如何为 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,
            },
        }),
    });

Where Props.OriginBucket is an instance of IBucket (just a bucket).Props.OriginBucket是一个实例IBucket (只是一个桶)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM