admin管理员组

文章数量:1221328

I'm working on adding resource policy document to S3 bucket.

It works fine when I create a new 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' : '***.***.***.***'
        }
      }
    }));

But if I try to get a bucket that already exists and add policy document it doesn't work:

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],
    }));

Resource Policy document won't be added.

Furthermore this code deletes existing policy document and make it blank.

Anyone have experience or solution about this issue?

I'm working on adding resource policy document to S3 bucket.

It works fine when I create a new 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' : '***.***.***.***'
        }
      }
    }));

But if I try to get a bucket that already exists and add policy document it doesn't work:

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],
    }));

Resource Policy document won't be added.

Furthermore this code deletes existing policy document and make it blank.

Anyone have experience or solution about this issue?

Share Improve this question edited Feb 11, 2020 at 17:32 ResponsiblyUnranked 1,8563 gold badges22 silver badges37 bronze badges asked Feb 6, 2020 at 3:27 HanBinKimHanBinKim 1531 gold badge1 silver badge4 bronze badges 3
  • Does your CDK stack have permission to modify existing buckets? – ResponsiblyUnranked Commented Feb 11, 2020 at 15:04
  • I had similar issue, please refer 60905976 for the solution – santosh Commented Apr 2, 2020 at 7:16
  • Might be of help - github.com/aws/aws-cdk/issues/6548 – Exter Commented Feb 9, 2024 at 20:12
Add a comment  | 

3 Answers 3

Reset to default 6

yeah,its possible and i did it using the python cdk. There's a work around here. https://github.com/aws/aws-cdk/issues/6548 The CfnBucketPolicy was used there.

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])
        )

I'm grappling with the same issue. After digging around I found this, which implies it's just not possible with the CDK:

As a workaround what I'm planning to do is to output the exact AWS S3 command that needs to be run from the command line in order to append the S3 bucket resource policy. This way the user that deploys the stack (I'm using server stack) knows of this additional manual step. Hopefully the AWS CLI supports

Update: Found a way to do this programmatrically, using a GET/SET approach on the bucket policy. The below is a 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, ' ')}`)
}

This solution is even suggested by AWS in aws s3api get-bucket-policy help manual:

Get and put a bucket policy The following example shows how you can download an Amazon S3 bucket policy, make modifications to the file, and then use put-bucket-policy to apply the modified bucket policy. To download the bucket policy to a file, you can run:

      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

I believe you cannot modify the policy of an existing bucket through your CDK App. That is why it works perfectly when you create a new bucket.

If you need to make changes to that bucket's resource policy, I'm afraid you might need to do it manually.

本文标签: amazon s3How to add resource policy to existing S3 bucket with CDK in JavaScriptStack Overflow