为了重现您的情况,我执行了以下操作:
- In Account-A:
- 创建了一个亚马逊 S3 存储桶 (
Bucket-A
)
- 创建了一个IAM Role (
Role-A
)
- 创建了一个AWS Lambda 函数 (
Lambda-A
)并分配Role-A
到函数
- 配置了一个亚马逊 S3 事件 on
Bucket-A
引起Lambda-A
对于“所有对象创建事件”
- In Account-B:
- 创建了一个亚马逊 S3 存储桶 (
Bucket-B
)与存储桶策略(见下文)
IAM Role
Role-A
有AWSLambdaBasicExecutionRole
托管策略,以及分配 Lambda 函数读取权限的内联策略Bucket-A
并写信给Bucket-B
:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucket-a/*"
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::bucket-b/*"
}
]
}
目标存储桶的存储桶策略
桶政策Bucket-B
允许从Role-A
IAM 政策:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNT-A:role/role-a"
},
"Action": [
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::bucket-b/*"
}
]
}
拉姆达函数
Lambda-A
当对象被创建时触发Bucket-A
,并将其复制到Bucket-B
:
import boto3
import urllib
TARGET_BUCKET = 'bucket-b'
def lambda_handler(event, context):
# Get incoming bucket and key
source_bucket = event['Records'][0]['s3']['bucket']['name']
source_key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'])
# Copy object to different bucket
s3_resource = boto3.resource('s3')
copy_source = {
'Bucket': source_bucket,
'Key': source_key
}
target_key = source_key # Change if desired
s3_resource.Bucket(TARGET_BUCKET).Object(target_key).copy(copy_source, ExtraArgs={'ACL': 'bucket-owner-full-control'})
I grant ACL=bucket-owner-full-control
因为将对象复制到不同帐户拥有的存储桶有时会导致对象仍然由原始帐户“拥有”。使用此 ACL 向拥有目标存储桶的账户授予所有权。
Testing
我上传了一个文件到Bucket-A
in Account-A
.
文件已正确复制到Bucket-B
in Account-B
.
Comments
该解决方案确实NOT要求:
- 存储桶策略
Bucket-A
, since Role-A
授予必要的权限
- 关闭S3 阻止公共访问,因为分配的权限不授予“公共”访问权限