AWS S3跨帳號複製bucket
情境模擬
假設目前有A、B兩個AWS帳號
我們希望將A的某個bucket內的所有檔案複製到B帳號的指定bucket
並且後續由B帳號作為該bucket所有物件的owner並自行付費
以下為情境範例資訊
AWS A帳號S3 bucket: s3-sync-demo-source
AWS B帳號S3 bucket: s3-sync-demo-dest
接下來將會透過AWS CLI來將s3-sync-demo-source bucket的所有檔案搬移至s3-sync-demo-dest bucket中
開始之前請先建立好這兩個帳號下的bucket
並且公開所有存取權
建立執行操作的IAM帳號
接著我們在AWS A帳號內建立一個IAM帳號s3-cross-account-sync
類型選擇為存取金鑰類型
不須設定任何permission直接建立即可
並且存好IAM key
最後先將這個IAM帳號的ARN複製起來
後續兩個S3 bucket的存取政策將會使用到
安裝、設定AWS CLI
這邊使用Linux版本
參考連結:https://docs.aws.amazon.com/zh_tw/cli/latest/userguide/install-cliv2-linux.html#cliv2-linux-prereq
安裝
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
rm -rf ./aws
aws --version
設定
aws configure
使用此指令將可以設定IAM帳號
輸入後將會出現互動式對話
這時候輸入先前的IAM帳號(s3-cross-account-sync)的key id, key secret即可
接著AWS CLI就會在~/.aws下建立config及credentials兩個檔案
後續有需要也可以直接修改這兩個檔案
設定來源bucket(s3-sync-demo-source)
前往該bucket許可(permission)設定頁面的儲存貯體政策設定區塊(bucket policy)點擊編輯
並且使用政策產生器(policy generator)
設定產生S3 bucket政策規則
Type of Policy:S3 Bucket Policy
Principal:設定為先前設定的IAM ARN(arn:aws:iam::xxxxx:user/s3-cross-account-sync)
Actions:ListBucket、GetObject
ARN:設定為此S3 bucket arn(arn:aws:s3:::s3-sync-demo-source)
產生政策JSON
接著按下Add Statement建立Statement
再按下Generate Policy產生政策JSON並複製起來
準備貼回S3 Bucket Policy中
設定S3 bucket policy
將剛才的政策JSON貼上並儲存
這時候會發現產生action dese not apply to any resource(s) in statement錯誤
調整一下政策JSON
把Resource改為array並新增一組arn:aws:s3:::s3-sync-demo-source/*即可正常儲存
測試AWS CLI對此來源bucket的存取權
可以在這個測試的來源bucket丟幾個檔案跟資料夾
這時候透過aws s3 ls command指定S3 URI
如果可以列出裡面的S3物件
就代表前面的政策設定成功
設定目的bucket政策(s3-sync-demo-dest)
bucket政策
這邊作法跟來源bucket差不多
一樣開啟bucket的政策設定>編輯>政策產生器(Policy Generator)
物件擁有權(object ownership)
這邊很重要
如果實際需求為A帳號bucket內的檔案複製到B帳號後
希望由B帳號自行做後續的付費
還需要額外設定許可(permission)>物件擁有權(object ownership)
設定為bucket-owner-full-control
在複製檔案過來後才會將owner轉移為B帳號
否則複製完之後檔案owner將仍然會是屬於A帳號
到時候就變成A帳號繼續付錢但B帳號有使用權
當然也有其他需求方式可以針對使用bucket的帳號做付費請求(參考連結)
不過這邊就先不討論
設定目的S3 bucket政策規則
Type of Policy:S3 Bucket Policy
Principal:一樣設定為先前設定的IAM ARN(arn:aws:iam::xxxxx:user/s3-cross-account-sync)
Actions:這邊稍微不同,除了ListBucket、GetObject之外,還要增加PutObject、PutObjectAcl寫入權限
ARN:設定為目的S3 bucket arn(arn:aws:s3:::s3-sync-demo-dest)
接著一樣產生政策JSON複製S3 bucket policy設定
並且一樣調整Resource欄位設定為array並允許該bucket下所有物件
測試目的bucket存取權
會發現出現權限不足的錯誤
原因是因為這個IAM帳號(s3-cross-account-sync)是由A帳號建立
而上述設定的S3 bucket policy則是由B帳號單方面自行允許這個IAM帳號(s3-cross-account-sync)存取
但A帳號並沒有允許這件事情
所以我們還需要在A帳號的IAM設定允許該IAM帳號(s3-cross-account-sync)可以存取這個目標bucket(s3-sync-demo-dest)
AWS A帳號建立存取目的bucket的政策
IAM>政策>建立新政策
服務:S3
操作:跟上面設定目標bucket存取政策相同,ListBucket、GetObject、PubObject、PubObjectAcl
ARN限制:s3-sync-demo-dest、s3-sync-demo-dest/*
最後將IAM帳號(s3-cross-account-sync)的許可(permission)連接到這個新政策即可
連接完成後過大概30秒到1分鐘再次測試存取權
就會發先先前的存取權限不足錯誤已經沒有了
此截圖無任何輸出則是因為該目的bucket沒放任何檔案
開始執行同步bucket
使用aws s3 sync指令設定來源、目的bucket即可同步
並且注意一定要使用--acl bucket-owner-full-control參數來強制更變owner為B帳號
aws s3 sync s3://s3-sync-demo-source s3://s3-sync-demo-dest --acl bucket-owner-full-control
sync輸出結果
最後
同步完記得找任一個同步完的檔案
確認一下owner是否有正確移轉
若沒正確移轉到時候將會繼續由原始bucket帳號(A帳號)作為owner繼續付費
其他
如果移轉bucket的情境是希望保留bucket名稱
例如bucket內的檔案已經有公開連結被使用的情境
建議移轉之前先在A帳號下複製備份原始bucket
然後將原始bucket刪除
大約過數分鐘後AWS釋出S3 bucket的名稱
再由B帳號使用相同的名稱建立目的bucket
最後再由A帳號複製的備份bucket移轉至B帳號的bucket即可