AWS Lambda:Lambda 函数 S3 到 S3 复制的跨账户策略

Kar*_*raj 4 amazon-s3 amazon-web-services amazon-iam aws-lambda

我们正在尝试实现 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"
            ]
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

基于https://www.lixu.ca/2016/09/aws-lambda-and-s3-how-to-do-cross_83.html链接,是的,我们可以借助源和目标的访问 ID 和访问密钥来实现相同的逻辑。但我尝试实现相同的逻辑,而不是源和目标的访问 ID 和访问密钥,通过适当的策略授予源存储桶和目标存储桶的访问权限,并使其像同一帐户一样工作。

Joh*_*ein 13

为了重现您的情况,我执行了以下操作:

  • 在账户 A中:
    • 创建了Amazon S3 存储桶( Bucket-A)
    • 创建了IAM 角色( Role-A)
    • 创建AWS Lambda 函数( Lambda-A) 并分配Role-A给该函数
    • 配置了Amazon S3 事件Bucket-A触发Lambda-A“所有对象创建事件”
  • 在账户 B中:
    • 使用存储桶策略创建了Amazon S3 存储桶( )(见下文)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/*"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

目标存储桶的存储桶策略

存储桶策略允许Bucket-BRole-AIAM 策略进行访问:

{
    "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/*"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

拉姆达函数

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'})
Run Code Online (Sandbox Code Playgroud)

我同意ACL=bucket-owner-full-control,因为将对象复制到不同帐户拥有的存储桶有时会导致对象仍然由原始帐户“拥有”。使用此 ACL 向拥有目标存储桶的账户授予所有权。

测试

我上传了一个文件到Bucket-Ain 中Account-A

该文件已正确复制Bucket-BAccount-B.

评论

该解决方案不需要

  • 上的存储桶策略Bucket-A,因为Role-A授予了必要的权限
  • 关闭S3 Block Public Access,因为分配的权限不会授予“公共”访问权限