我試圖使用AWS lambda來備份對象從assets.myapp.com
S3桶Account-A
下一個backup-assets.myapp.com
S3存儲Account-B
下,但我越來越Access Denied
無論IAM
或Bucket Policy
配置我使用。如何使用AWS Lambda將S3對象備份到另一個帳戶上的存儲桶?
我有一個名爲Backup-S3-Object
的Lambda函數,它由assets.myapp.com
存儲桶中的s3:PutObject
事件觸發器觸發。
期望的結果是Backup-S3-Object
函數將使用適用於Javascript的AWS-SDK執行s3.copyObject
到backup-assets.myapp.com
。
拉姆達代碼
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);
});
};
拉姆達作用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
以下桶的政策,其目的是讓lambda函數,Account-A
下運行,以寫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
桶上的觸發器觸發得很好。它會觸發Lambda函數Backup-S3-Object
,並且函數邏輯能夠確定要複製的正確存儲桶名稱和對象關鍵字,但它始終會因爲Access Denied
而失敗。
我已經做了一個測試,使用相同的設置,並轉移到另一個存儲桶,也在Account-A
,它工作得很好。所以這個問題顯然與跨賬戶權限有關,但我沒有嘗試過。
我也使用Account-A
的CanonicalID
作爲backup-assets.myapp.com
桶政策Principal
嘗試,但仍然得到Access Denied
作爲所產生的誤差。
我試圖用"AWS": "arn:aws:iam::ACCOUNT-A-NUMBER-HERE:root"
作爲主體,同樣的錯誤。
任何幫助?
一個解決方案:正如描述的以下馬特的解決方案是,你需要包括
s3:PutObject
許可在lambda作用的政策。 這對我來說有點奇怪,但總體思路是,您在您的 目標存儲桶的存儲桶政策中授予您的Lambda角色的任何 權限也必須在您的 源帳戶下的Lambda政策中進行復制。當您在Bucket Policy中引用它時,似乎Lambda角色是已採用完全是 。爲了實現此目的,我已將 第二個內聯策略添加到我的Lambda角色中,該角色允許s3:PutObject
至 ,backup-assets.myapp.com
存儲桶在Account-B
之下。這不允許 Lambda函數寫入任何源桶,但是 允許它寫入備份桶。
感謝@Matt Houser的回答,但我認爲你的政策混淆了。 'Backup-S3-Object'Lambda角色只在源桶('assets.myapp.com')上擁有'List'和'Get'權限,因爲它只需從那裏獲取對象,不需要寫入任何東西到那個桶。然後,我使用'backup-assets.myapp.com'上的桶策略來允許Lamba角色寫入'Account-B'下的備份桶。我已經試過授予'arn:aws:iam:ACCOUNT-A-NUMBER-HERE:root',但是我會再給它一次。但我認爲Lambda函數不會在'root'下激發,不確定。 – AJB
是的,使用'root'主體的同樣的問題。 – AJB
好吧,這是搞砸了。當我將's3:PutObject'添加到Lambda角色策略時,它可以工作。但爲什麼?該策略應該規定Lambda函數對源桶「assets.myapp.com」的權限,該權限只需**讀取**。爲什麼它要求源桶上的'PUT'信號將一個對象複製到'backup-assets.myapp.com'桶中? – AJB