跨AWS账户用Lambda复制S3对象无法设公开,需变更归属至目标账户
解决跨AWS账户复制S3对象并让目标账户成为对象所有者的问题
核心问题在于:当从源账户发起复制操作(推模式)时,S3默认会保留对象的原始所有权(源账户);而如果让目标账户主动拉取对象,则目标账户会自动成为新对象的所有者——这也是你在Update4中验证成功的方案,我先重点推荐这种方式,再补充其他可选方案。
推荐方案:目标账户主动拉取对象(已验证可行)
这种方式无需处理复杂的ACL或所有权配置,天然就能让目标账户获得对象所有权,步骤如下:
- 在目标账户创建Lambda:使用你提供的Go代码(只需确认
CopySource指向源桶的Sample.txt,Bucket为目标桶即可) - 配置目标账户Lambda角色权限:按照你的Update5配置,允许角色访问源桶和目标桶的所有S3操作
- 配置源桶的存储桶策略:参考你的Update4,允许目标账户的Lambda角色访问源桶及其对象
这种方式下,复制操作由目标账户发起,新生成的NewSample.txt直接归目标账户所有,自然能正常访问,也不会出现"Server-side encryption = Access denied"的权限问题。
可选方案:源账户推送对象(需额外配置)
如果必须从源账户发起复制,需要通过以下两种方式之一确保目标账户获得所有权:
方式1:开启目标桶的对象所有权控制(推荐)
这是AWS官方推荐的方式,直接让桶所有者自动获得所有写入对象的所有权:
- 登录目标账户的S3控制台,找到目标桶
- 进入权限标签页,找到对象所有权设置
- 选择桶所有者强制控制(或ACLs已禁用),保存配置后,所有写入该桶的对象都会自动归目标账户所有
- 你的原Go代码无需修改,直接复制即可生效
方式2:复制时指定ACL授予目标账户完全控制权
修改你的Go代码,在CopyObjectInput中添加ACL参数为bucket-owner-full-control:
input := &s3.CopyObjectInput{ Bucket: aws.String("target-bucket"), CopySource: aws.String("/source-bucket/Sample.txt"), Key: aws.String("NewSample.txt"), ACL: aws.String("bucket-owner-full-control"), // 添加该行 }
同时确保目标桶的存储桶策略(你的Update2)允许源账户的Lambda角色执行s3:PutObjectAcl操作(你当前用的s3:*已经包含了这个权限)。
关于你遇到的"Server-side encryption = Access denied"问题:这是因为对象属于源账户时,目标账户没有权限查看其加密元数据;当目标账户成为对象所有者后,这个问题会自动消失。
内容的提问来源于stack exchange,提问作者MAK
相关产品推荐
相关产品推荐

