【问题标题】:How to add resource policy to existing S3 bucket with CDK in JavaScript?如何在 JavaScript 中使用 CDK 将资源策略添加到现有 S3 存储桶?
【发布时间】:2020-05-22 01:07:28
【问题描述】:

我正在向 S3 存储桶添加资源策略文档。

当我创建一个新的 Bucket 时它工作正常:

const newbucket = new s3.Bucket(this, 'newBucket', {
      websiteIndexDocument : 'index.html',
      bucketName : 'NewBucket'
});

newbucket.addToResourcePolicy(new iam.PolicyStatement({
      effect : iam.Effect.ALLOW,
      actions: ['s3:*'],
      resources: [newbucket.arnForObjects('*')],
      principals: [new iam.AnyPrincipal],
    }));

newbucket.addToResourcePolicy(new iam.PolicyStatement({
      effect : iam.Effect.DENY,
      actions: ['s3:*'],
      resources: [newbucket.arnForObjects('*')],
      principals: [new iam.AnyPrincipal],
      conditions : {
        'NotIpAddress' : {
          'aws:SourceIp' : '***.***.***.***'
        }
      }
    }));

但是如果我尝试获取一个已经存在的存储桶并添加策略文档,它就不起作用:

const existingbucket = Bucket.fromBucketAttributes(this, 'ImportedBucket',{
      bucketName :'ExistingBucket'
    })

existingbucket.addToResourcePolicy(new iam.PolicyStatement({
      effect : iam.Effect.ALLOW,
      actions: ['s3:*'],
      resources: [existingbucket.arnForObjects('*')],
      principals: [new iam.AnyPrincipal],
    }));

不会添加资源策略文档。

此外,此代码删除现有的策略文档并将其设为空白。

有人对此问题有经验或解决方案吗?

【问题讨论】:

  • 您的 CDK 堆栈是否有权修改现有存储桶?
  • 我也遇到过类似的问题,请参考60905976解决方案

标签: javascript amazon-s3 aws-cdk


【解决方案1】:

我相信您无法通过 CDK 应用修改现有存储桶的策略。这就是为什么在您创建新存储桶时它可以完美运行的原因。

如果您需要更改该存储桶的资源策略,恐怕您可能需要手动进行。

【讨论】:

    【解决方案2】:

    是的,这是可能的,我使用 python cdk 做到了。这里有工作。 https://github.com/aws/aws-cdk/issues/6548 那里使用了 CfnBucketPolicy。

    existing_bucket=s3.Bucket.from_bucket_attributes(self, 'ImportedBucket', 
                bucket_arn="arn:aws:s3:::bucket"       
            )
    
            bucket_policy=iam.PolicyStatement(
                actions=["s3:Get*", "s3:List*"],
                resources=[existing_bucket.arn_for_objects('*')],
                principals=[iam.AccountRootPrincipal()]
            )
    
            s3.CfnBucketPolicy(self, 'bucketpolicy',
                bucket=existing_bucket.bucket_name,
                policy_document=iam.PolicyDocument(statements=[bucket_policy])
            )
    

    【讨论】:

    • 虽然这段代码可以解决问题,including an explanation 解决问题的方式和原因将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的答案添加解释并说明适用的限制和假设。
    • 这说,The bucket policy already exists on bucket
    【解决方案3】:

    我正在努力解决同样的问题。在四处挖掘之后,我找到了this,这意味着使用 CDK 是不可能的:

    作为一种解决方法,我计划做的是输出需要从命令行运行的确切 AWS S3 命令,以便附加 S3 存储桶资源策略。这样部署堆栈的用户(我使用server stack)就知道这个额外的手动步骤。希望 AWS CLI 支持

    更新:找到了一种以编程方式执行此操作的方法,在存储桶策略上使用 GET/SET 方法。下面是Node.js zx script

    #!/usr/bin/env zx
    
    const fs = require('fs')
    
    ...
    
    async function updateBucketPolicy ({
                                                         awsProfile,
                                                         bucket,
                                                         lambdaOneRoleArn: lambdaOneRoleArn,
                                                         lambdaTwoRoleArn: lambdaTwoRoleArn
                                                       }) {
      const policyTmpl = '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"[LAMBDA_ONE_ROLE_ARN]"},"Action":"s3:PutObject","Resource":"arn:aws:s3:::[BUCKET]/*"},{"Effect":"Allow","Principal":{"AWS":"[LAMBDA_TWO_ROLE_ARN]"},"Action":"s3:GetObject","Resource":"arn:aws:s3:::[BUCKET]/*"},{"Effect":"Allow","Principal":{"AWS":"[LAMBDA_TWO_ROLE_ARN]"},"Action":"s3:ListBucket","Resource":"arn:aws:s3:::[BUCKET]"}]}'
      const policyAmendments = JSON.parse(policyTmpl.replace(/\[BUCKET\]/g, bucket).replace(/\[LAMBDA_ONE_ROLE_ARN\]/g, lambdaOneRoleArn)
        .replace(/\[LAMBDA_TWO_ROLE_ARN\]/g, lambdaTwoRoleArn))
    
      // First get the current bucket policy
      await $`AWS_PROFILE=${awsProfile} aws s3api get-bucket-policy --bucket ${bucket} --output text > /tmp/policy.json`
      const currentBucketPolicy = JSON.parse(fs.readFileSync('/tmp/policy.json'))
    
      // Now update it, and put it right back
      const newPolicy = currentBucketPolicy
      newPolicy.Statement = currentBucketPolicy.Statement.concat(policyAmendments.Statement)
      fs.writeFileSync('/tmp/new-policy.json', JSON.stringify(newPolicy))
      await $`AWS_PROFILE=${awsProfile} aws s3api put-bucket-policy --bucket ${bucket} --policy file:///tmp/new-policy.json`
      console.log(`Updated  bucket ${bucket} policy with ${JSON.stringify(newPolicy, null, ' ')}`)
    }
    
    

    AWS 在aws s3api get-bucket-policy help 手册中甚至建议使用此解决方案:

    获取并放置存储桶策略 以下示例显示了如何下载 Amazon S3 存储桶 策略,对文件进行修改,然后使用 put-bucket-policy 应用修改后的存储桶策略。将存储桶策略下载到 一个文件,你可以运行:

          aws s3api get-bucket-policy --bucket mybucket --query Policy --output text > policy.json
    
       You can then modify the policy.json file as needed.   Finally  you  can
       apply this modified policy back to the S3 bucket by running:
    
          aws s3api put-bucket-policy --bucket mybucket --policy file://policy.json
    

    【讨论】:

      猜你喜欢
      • 2021-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-13
      • 2019-05-15
      • 1970-01-01
      • 2020-04-07
      • 1970-01-01
      相关资源
      最近更新 更多