【发布时间】:2016-10-22 02:26:05
【问题描述】:
我正在尝试使用 AWS Lambda 将对象从Account-A 下的assets.myapp.com S3 存储桶备份到Account-B 下的backup-assets.myapp.com S3 存储桶,但无论@987654326 是什么,我都会得到Access Denied @ 或 Bucket Policy 我使用的配置。
我有一个名为 Backup-S3-Object 的 Lambda 函数,它由 assets.myapp.com 存储桶上的 s3:PutObject 事件触发器触发。
期望的结果是 Backup-S3-Object 函数将使用适用于 Javascript 的 AWS-SDK 执行 s3.copyObject 到 backup-assets.myapp.com。
Lambda 代码
var aws = require('aws-sdk');
var s3 = new aws.S3({ apiVersion: '2006-03-01' });
exports.backupObject = function(event, context, callback) {
var data = event.Records[0];
var sourceBucket = data.s3.bucket.name;
var targetBucket = 'backup-' + data.s3.bucket.name;
var key = data.s3.object.key;
console.log('BACKUP: ' + sourceBucket + '/' + key + ' to ' + targetBucket);
s3.copyObject({
Bucket : targetBucket,
CopySource : sourceBucket + '/' + key,
Key : key,
ACL : 'private',
ServerSideEncryption : 'AES256'
}, function(error, data) {
if (error) return context.done(error);
return context.done(null, 'Successful backup of ' + sourceBucket + '/' + key);
});
};
Lambda 角色 S3 政策
我为分配给我的 Lambda 函数的 Backup-S3-Lambda-Role 制定了以下策略。这允许 Lambda 函数访问List 或Get 来自任何存储桶的任何对象,位于Account-A 下,这是源账户。因此,此策略将允许 Lambda 函数从 assets.myapp.com 获取对象,即源存储桶。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:ListBucketVersions",
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": [
"arn:aws:s3:::*"
]
}
]
}
backup-assets.myapp.com 存储桶政策
然后,在Account-B 下,我将以下存储桶策略附加到backup-assets.myapp.com,其目的是允许在Account-A 下运行的Lambda 函数写入到backup-assets.myapp.com 下的存储桶Account-B
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "Allow PUT from Account-A Lambda function",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNT-A-NUMBER-HERE:role/Backup-S3-Lambda-Role"
},
"Action": "s3:PutObject",
"Resource": [
"arn:aws:s3:::backup-assets.myapp.com",
"arn:aws:s3:::backup-assets.myapp.com/*"
]
}
]
}
发生了什么?
assets.myapp.com 存储桶上的触发器触发得很好。它触发Backup-S3-Object Lambda 函数,函数逻辑能够确定要复制的正确存储桶名称和对象键,但它总是以Access Denied 失败。
我已经使用相同的设置完成了一项测试,并将其转移到另一个也在 Account-A 下的存储桶,它工作得很好。所以问题显然出在跨账户权限上,但我尝试过的都没有。
我还尝试在backup-assets.myapp.com 存储桶策略中使用Account-A 的CanonicalID 作为Principal,但仍然得到Access Denied 作为结果错误。
我尝试使用"AWS": "arn:aws:iam::ACCOUNT-A-NUMBER-HERE:root" 作为主体,同样的错误。
有什么帮助吗?
解决方案:如下面的 Matt 所述,解决方案是您需要在 Lambda 角色策略中包含
s3:PutObject权限。 这对我来说有点奇怪,但总体思路是,任何 您在您的存储桶策略中授予 Lambda 角色的权限 目标存储桶也必须在您的 Lambda 策略中复制 源账户。似乎 Lambda 角色已完全采用 当您在存储桶策略中引用它时。为了实现这一点,我添加了 我的 Lambda 角色的第二个内联策略,允许s3:PutObjectbackup-assets.myapp.com在Account-B下的存储桶。这不允许 Lambda 函数写入任何源存储桶,但确实 允许它写入备份存储桶。
【问题讨论】:
标签: amazon-web-services amazon-s3 lambda