share facebook facebook facebook twitter twitter menu hatena pocket slack

2021.01.26 TUE

S3にバケット所有者でオブジェクトをUploadする

新川 貴章

WRITTEN BY 新川 貴章

概要

  • 今回は、S3バケットの”Object ownership” 設定をカスタマイズして、S3にバケット所有者としてオブジェクトをUpload する方法をご紹介します。
  • S3バケットの”Object ownership” 設定は、2020年10月の Amazon S3 Updateの機能追加によって使用可能になっています。
  • なお、今回の内容は下記記事でご紹介した、S3 クロスアカウント環境においてCloudWatch Logs からエクスポートされたオブジェクトを取得する際に発生するHTTP 403 エラーの対策にもなりえます。同様の問題でお困りの方は、是非試してみてください。
概要はじめに今回は、S3バケットからクロスアカウントでファイルをコピーする際に、HTTP 403のエラーが発生した事例をご紹介します。症状1つの案件の中に、システム毎にアカウント:A、アカウント:B、アカウント:C、アカウント:Dの環境があるとします。各アカウントに...

シチュエーション

  • 今回の想定するシチュエーションは、下記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 に変わりました。

参考記事

概要はじめに今回は、S3バケットからクロスアカウントでファイルをコピーする際に、HTTP 403のエラーが発生した事例をご紹介します。症状1つの案件の中に、システム毎にアカウント:A、アカウント:B、アカウント:C、アカウント:Dの環境があるとします。各アカウントに...
前提条件S3バケットに対して同一のAWSアカウントのEC2からはアクセスできるが、他アカウントのEC2からはアクセスできないという場合(下記エラーメッセージのサンプル)の対処方法です。An error occurred (AccessDenied) when calling the ListObjectsV2 operation:...
CloudWatch LogsのイベントをS3にエクスポートしたい CloudWatch Logsは従量課金制CloudWatch Logsは初期費用や最低利用料金はかかりませんが、支払いは従量課金制です。東京リージョンの場合、以下の費用が掛かります(2019/7/10現在)。収集 (データの取り込...
  • 以下は、Amazon S3 Update がアナウンスされたAWS News Blogです。
A year or so after we launched Amazon S3, I was in an elevator at a tech conference and heard a couple of developers use “just throw it into S3” as the answer to their data storage challenge. I remember that moment well because the comment was mad...
  • 以下は、Amazon S3 Developer Guide の説明となります。
Control ownership of new objects that are uploaded to your Amazon S3 bucket using S3 Object Ownership.

元記事はこちら

S3にバケット所有者でオブジェクトをUploadする

cloudpack

cloudpackは、Amazon EC2やAmazon S3をはじめとするAWSの各種プロダクトを利用する際の、導入・設計から運用保守を含んだフルマネージドのサービスを提供し、バックアップや24時間365日の監視/障害対応、技術的な問い合わせに対するサポートなどを行っております。
AWS上のインフラ構築およびAWSを活用したシステム開発など、案件のご相談はcloudpack.jpよりご連絡ください。