S3にバケット所有者でオブジェクトをUploadする
Contents
概要
- 今回は、S3バケットの"Object ownership" 設定をカスタマイズして、S3にバケット所有者としてオブジェクトをUpload する方法をご紹介します。
- S3バケットの"Object ownership" 設定は、2020年10月の Amazon S3 Updateの機能追加によって使用可能になっています。
- なお、今回の内容は下記記事でご紹介した、S3 クロスアカウント環境においてCloudWatch Logs からエクスポートされたオブジェクトを取得する際に発生するHTTP 403 エラーの対策にもなりえます。同様の問題でお困りの方は、是非試してみてください。
シチュエーション
- 今回の想定するシチュエーションは、下記2つです。
- 1つ目は、クロスアカウントで使用するS3 環境があり、アカウント:A のサーバーリソースからアカウント:B の S3バケットにオブジェクトを書き込みます。通常はオブジェクトの所有者は、オブジェクトの書き込みを行ったアカウント:A となります。"Object ownership" 設定をカスタマイズ後は、オブジェクトの所有者は、バケット所有者であるアカウント:B となります。
- 2つ目は、クロスアカウントで使用するS3 環境があり、アカウント:A のCloudWatch Logsからアカウント:B の S3バケットにログをエクスポートします。通常はオブジェクトの所有者は、CloudWatch Logsを表す“logs+prod-nrt" となります。"Object ownership" 設定をカスタマイズ後は、オブジェクトの所有者は、バケット所有者であるアカウント:B となります。
クロスアカウント環境のオブジェクト書き込み
S3 クロスアカウント環境の準備
- S3 をクロスアカウント環境で使用する場合の準備を行います。アカウント:B のS3バケットに、こちらの記事で紹介したバケットポリシーを設定します。ここで、"111111111111″ はアカウント:A のアカウント番号を表します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DelegateS3Access",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:root"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::s3-bucket-name/*",
"arn:aws:s3:::s3-bucket-name"
]
}
]
}
- アカウント:A のEC2 には、S3バケットに書き込みが可能なポリシー(例: AmazonS3FullAccess)を設定したロールを割り当てます。
Object ownershipがデフォルトの場合
- S3のObject ownershipがデフォルトのObject writer(オブジェクトライター)に設定された場合の動作は下記となります。
- アカウント:A のEC2 からアカウント:B の S3バケットに対し、aws s3 lsコマンド, aws s3 cpコマンドが成功します。aws s3api list-objects-v2コマンドで確認すると、"DisplayName"からオブジェクトの所有者はアカウント:A であることが分かります。
$ aws s3 ls s3://s3-bucket-name/test-cross-account/
2021-01-10 12:18:12 0
$ aws s3 cp TEST-A s3://s3-bucket-name/test-cross-account/
upload: ./TEST-A to s3://s3-bucket-name/test-cross-account/TEST-A
$ aws s3 ls s3://s3-bucket-name/test-cross-account/
2021-01-10 12:18:12 0
2021-01-10 12:20:18 0 TEST-A
$ aws s3api list-objects-v2 --fetch-owner --bucket s3-bucket-name --prefix test-cross-account/TEST-A
{
"Contents": [
{
"LastModified": "2021-01-10T12:20:18.000Z",
"ETag": "\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"",
"StorageClass": "STANDARD",
"Key": "test-cross-account/TEST-A",
"Owner": {
"DisplayName": "account-a",
"ID": "0123abcd0123abcd0123abcd0123abcd0123abcd0123abcd0123abcd0123abcd"
},
"Size": 0
}
]
}
- また、コンソールからの確認においても、オブジェクトの所有者はアカウント:A であることが分かります。
Object ownershipがバケット所有者の場合
- S3のObject ownershipをBucket owner preferred(希望するバケット所有者)に設定します。
- S3バケットの設定から"アクセス許可"を開きます。"オブジェクト所有者" の設定を編集します。
- 以下の通り、オブジェクト所有者を"Bucket owner preferred(希望するバケット所有者)" に変更します。
- 次に、必須ではありませんが、アカウント:B のS3バケットに記載したバケットポリシーに、ConditionとしてオブジェクトのACLに “bucket-owner-full-control" がセットされている条件を追記します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DelegateS3Access",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:root"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::s3-bucket-name/*",
"arn:aws:s3:::s3-bucket-name"
],
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
}
]
}
- 再度、アカウント:A のEC2 からアカウント:B の S3バケットに対し、AWS CLI を実行します。先ほど実行した aws s3 lsコマンド, aws s3 cpコマンドは失敗しました。
$ aws s3 ls s3://s3-bucket-name/test-cross-account/
An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied
$ aws s3 cp TEST-B s3://s3-bucket-name/test-cross-account/
upload failed: ./TEST-B to s3://s3-bucket-name/test-cross-account/TEST-B An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
- 代わりに、aws s3 cpコマンドに “–acl bucket-owner-full-control" オプションを付け実行します。
$ aws s3 cp TEST-B s3://s3-bucket-name/test-cross-account/ --acl bucket-owner-full-control
upload: ./TEST-B to s3://s3-bucket-name/test-cross-account/TEST-B
- コンソールから確認すると、オブジェクトの所有者はバケット所有者であるアカウント:B であることが分かります。
クロスアカウント環境のCloudWatch LogsのExport
S3 クロスアカウント環境の準備
- S3 をクロスアカウント環境で使用する場合の準備を行います。アカウント:B のS3バケットに、こちらの記事で紹介したバケットポリシーを設定します。
- さらに、CloudWatch Logsのログをエクスポートするために、こちらの記事で紹介したバケットポリシーを設定します。
- ここで、"111111111111″ はアカウント:A のアカウント番号を表します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DelegateS3Access",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:root"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::s3-bucket-name/*",
"arn:aws:s3:::s3-bucket-name"
]
},
{
"Effect": "Allow",
"Principal": {
"Service": "logs.ap-northeast-1.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::s3-bucket-name"
},
{
"Effect": "Allow",
"Principal": {
"Service": "logs.ap-northeast-1.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::s3-bucket-name/*",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
}
]
}
Object ownershipがデフォルトの場合
- S3のObject ownershipがデフォルトのObject writer(オブジェクトライター)に設定された場合の動作は下記となります。
- アカウント:A のコンソールからCloudWatch Logsを開き、ログをエクスポートします。
- アカウントに"Another account"、S3バケット名, プレフィックスに対象の名前を指定して、[エクスポート]を押します。
- アカウント:B のS3 コンソールから、エクスポートされたオブジェクトが書き込みされたことを確認します。
- 以下の通り、オブジェクトの所有者は、CloudWatch Logsを表す“logs+prod-nrt" となります。
Object ownershipがバケット所有者の場合
- S3のObject ownershipをBucket owner preferred(希望するバケット所有者)に設定します。
- S3バケットの設定から"アクセス許可"を開きます。"オブジェクト所有者" の設定を編集します。
- 以下の通り、オブジェクト所有者を"Bucket owner preferred(希望するバケット所有者)" に変更します。
- 次に、必須ではありませんが、アカウント:B のS3バケットに記載したバケットポリシーに、ConditionとしてオブジェクトのACLに “bucket-owner-full-control" がセットされている条件を追記します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DelegateS3Access",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:root"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::s3-bucket-name/*",
"arn:aws:s3:::s3-bucket-name"
],
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
},
{
"Effect": "Allow",
"Principal": {
"Service": "logs.ap-northeast-1.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::s3-bucket-name"
},
{
"Effect": "Allow",
"Principal": {
"Service": "logs.ap-northeast-1.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::s3-bucket-name/*",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
}
]
}
- 再度、アカウント:A のコンソールからCloudWatch Logsを開き、ログをエクスポートします。
- 最後に、アカウント:B のS3 コンソールから、エクスポートされたオブジェクトが書き込みされたことを確認します。
- 以下の通り、オブジェクトの所有者は、バケット所有者であるアカウント:B に変わりました。
参考記事
- 以下は、Amazon S3 Update がアナウンスされたAWS News Blogです。
- 以下は、Amazon S3 Developer Guide の説明となります。