我正在尝试使用AWS Lambda将对象从 Account-A
下的 assets.myapp.com
S3存储桶备份到 Account-B
下的 backup-assets.myapp.com
S3存储桶,但无论我使用的 IAM
或 Bucket Policy
配置如何,我都会得到 Access Denied
.
我有一个名为 Backup-S3-Object
的Lambda函数,它被 assets.myapp.com
桶上的 s3:PutObject
事件触发器触发 .
期望的结果是 Backup-S3-Object
函数将使用AWS-SDK for Javascript执行 s3.copyObject
到 backup-assets.myapp.com
.
The Lambda Code
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);
});
};
The Lambda Role S3 Policy
我已经为 Backup-S3-Lambda-Role
提供了以下策略,该策略已分配给我的Lambda函数 . 这允许Lambda函数从 Account-A
(源帐户)下的任何存储桶访问 List
或 Get
任何对象 . 因此,此策略将允许Lambda函数从 assets.myapp.com
获取对象,这是源存储桶 .
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:ListBucketVersions",
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": [
"arn:aws:s3:::*"
]
}
]
}
The backup-assets.myapp.com Bucket Policy
然后,在 Account-B
下,我将 backup-assets.myapp.com
附加了以下存储桶策略,该策略旨在允许在 Account-A
下运行的Lambda函数写入 Account-B
下的 backup-assets.myapp.com
存储桶
{
"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/*"
]
}
]
}
What's Happening?
assets.myapp.com
斗的触发器发射得很好 . 它触发 Backup-S3-Object
Lambda函数,函数逻辑能够确定要复制的正确的存储桶名称和对象密钥,但它始终会失败 Access Denied
.
我've done a test using the same setup and transferring to another bucket that'也在 Account-A
下,它运作得很好 . 所以问题显然在于跨帐户权限,但我尝试过的任何工作都没有 .
我还尝试在 backup-assets.myapp.com
存储桶策略中使用 Account-A
Account-A
作为 Principal
,但仍然得到 Access Denied
作为结果错误 .
我试图使用 "AWS": "arn:aws:iam::ACCOUNT-A-NUMBER-HERE:root"
作为主要的同样的错误 .
有帮助吗?
解决方案:如下面的Matt所述,解决方案是您需要在Lambda角色策略中包含s3:PutObject权限 . 这对我来说有点奇怪,但一般的想法是,您在目标存储桶的Bucket Policy中授予Lambda角色的任何权限也必须在源帐户下的Lambda策略中复制 . 当您在Bucket Policy中引用Lambda角色时,似乎完全采用了该角色 . 为实现这一点,我在Lambda角色中添加了第二个内联策略,允许s3:PutObject到Account-B下的backup-assets.myapp.com存储桶 . 这不允许Lambda函数写入任何源存储桶,但允许它写入备份存储桶 .
1 回答
我看到两个可能的问题 .
尝试将
s3:PutObject
添加到您的策略中,如下所示:或者,如果您希望继续将Lambda函数限制为仅在源存储桶上访问 read ,则可以向Lambda角色添加第二个策略,允许其在备份存储桶上
s3:PutObject
,将备份存储桶命名为资源,如下:现在,只需让您的目标帐户访问源存储桶:
复制工作后,您可以尝试添加角色 .