我们正在尝试实现 lambda 函数,该函数将根据源 S3 存储桶事件将对象从一个 S3 复制到跨账户中的另一个 S3 存储桶。目前,我们能够在同一 SAG 内的源和目标之间复制文件。但是当我们尝试跨账户实现相同的逻辑时,得到了 CopyObject 操作:Access Denied 问题。我已经给出了以下存储桶策略。您能否帮助我获取正确的 IAM 和存储桶策略来解决此问题。
{
"Version": "2012-10-17",
"Id": "Policy1603404813917",
"Statement": [
{
"Sid": "Stmt1603404812651",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::6888889898:role/Staff"
},
"Action": [
"s3:GetObject",
"s3:GetObjectAcl",
"s3:ListBucket",
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": [
"arn:aws:s3:::source-bucktet-testing-lambda/*",
"arn:aws:s3:::source-bucktet-testing-lambda"
]
}
]
}
基于
https://www.lixu.ca/2016/09/aws-lambda-and-s3-how-to-do-cross_83.html
链接,是的,我们可以借助源和目标的访问 ID 和访问密钥来实现相同的逻辑。但我正在尝试实现相同的逻辑,而不是源和目标的访问 ID 和访问密钥,通过适当的策略授予源和目标存储桶的访问权限,并使其像同一帐户一样工作。
为了重现您的情况,我执行了以下操作:
Bucket-A
)Role-A
)Lambda-A
) 并将 Role-A
分配给该函数Bucket-A
上配置了 Amazon S3 事件以触发
Lambda-A
的“所有对象创建事件”Bucket-B
)(见下文)IAM 角色
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 函数
当在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'})
我同意
ACL=bucket-owner-full-control
,因为将对象复制到不同帐户拥有的存储桶有时会导致对象仍然由原始帐户“拥有”。使用此 ACL 向拥有目标存储桶的账户授予所有权。
测试
我已将文件上传到
Bucket-A
中的Account-A
。
文件已正确复制到
Bucket-B
中的Account-B
。
评论
该解决方案不需要需要:
Bucket-A
上的存储桶策略,因为Role-A
授予必要的权限假设如下
即使正确设置了所有这些,复制操作也可能会失败。这是因为策略允许您获取/放置 s3 对象,但不允许与这些 s3 对象关联的标签。
您还需要允许以下操作“s3:GetObjectTagging”和“s3:PutObjectTagging”
谢谢您的本指南,它非常适合小文件,但当我上传大文件(~200mb)时,它无法复制。 你能帮我解决这个问题吗