2 つの Amazon S3 バケット間でオブジェクトをコピーできないのはなぜですか?

最終更新日: 2021 年 4 月 27 日

ある Amazon Simple Storage Service (Amazon S3) バケットから別のバケットにオブジェクトをコピーしようとしているのですが、うまくいきません。この問題を解決するには、どうすればよいですか?

簡単な説明

バケット間でオブジェクトをコピーすることに関する問題をトラブルシューティングするには、以下を確認してください。

  • バケットポリシーおよび AWS Identity and Access Management (IAM) ポリシー
  • オブジェクトのオーナーシップ
  • AWS Key Management Service (AWS KMS) の暗号化
  • Amazon Simple Storage Service Glacier (Amazon S3 Glacier) ストレージクラス
  • バケットでリクエスタ支払いが有効になっていること
  • AWS Organizations のサービスコントロールポリシー
  • Amazon S3 の Amazon Virtual Private Cloud (VPC) エンドポイントに関するクロスリージョンリクエストの問題

解決方法

バケットポリシーと IAM ポリシー

バケット間でオブジェクトをコピーするには、正しいアクセス権限が設定されていることを確認する必要があります。同じ AWS アカウントのバケット間でオブジェクトをコピーするには、IAM ポリシーを使用してアクセス権限を設定できます。異なるアカウントのバケット間でオブジェクトをコピーするには、関連する IAM ポリシーとバケットポリシーの両方でアクセス許可を設定する必要があります。

注: バケットポリシーを変更する方法については、 S3 バケットポリシーを追加する方法を参照してください。 IAM ユーザーのアクセス権限を追加または修正する手順については、IAM ユーザーのアクセス許可の変更を参照してください。IAM ロールのアクセス許可を変更する方法については、ロールの修正を参照してください。

以下の必要なアクセス許可を確認します。

  • 少なくとも、IAM ID (ユーザーまたはロール) には、ソースバケットに対する s3:ListBucket および s3:GetObject アクションに対するアクセス権限が必要です。バケットが同じアカウントにある場合は、次に IAM ID のポリシーまたは S3 バケットポリシーを使用してこれらのアクセス権限を設定します。バケットが異なるアカウントにある場合は、次にバケットポリシーと IAM ID のポリシーの両方を使用してこれらのアクセス権限を設定します。
  • IAM ID には、少なくとも、送信先バケットの s3:ListBucket および s3:PutObject アクションに対するアクセス権限が必要です。バケットが同じアカウントにある場合は、次に IAM ID のポリシーまたは S3 バケットポリシーを使用してこれらのアクセス権限を設定します。バケットが異なるアカウントにある場合は、次にバケットポリシーと IAM ID のポリシーの両方を使用してこれらのアクセス権限を設定します。
  • 関連するバケットポリシーと IAM ポリシーを見直し、必要なアクセス許可と競合する明示的な拒否ステートメントがないことを確認します。明示的な拒否のステートメントは、許可のステートメントよりも優先されます
  • 特定のオペレーションについては、IAM ID に、 オペレーション内の必要なすべてのアクションに対するアクセス許可があることを確認します。たとえば、aws s3 cp を実行しようとしている場合は、s3:GetObject と s3:PutObject のアクセス許可が必要です。-recursive オプションを指定して aws s3 cp コマンドを実行するには、s3:GetObject、s3:PutObject、および s3:ListBucket に対するアクセス許可が必要です。コマンド aws s3 sync を実行する場合は、s3:GetObject、s3:PutObject、s3:ListBucket のアクセス許可が必要です。
    注: AssumeRole API 操作を使用して Amazon S3 にアクセスする場合は、信頼関係が正しく設定されていることも確認する必要があります。
  • バージョン固有のオペレーションでは、IAM ID にバージョン固有のアクションに対するアクセス権限があることを確認します。例えば、オブジェクトの特定のバージョンをコピーするには、s3:GetObject に加えて s3:GetObjectVersion に対するアクセス権限が必要です。
  • オブジェクトタグを持つオブジェクトをコピーする場合、IAM ID に s3:GetObjectTagging と s3:PutObjectTagging のアクセス権限が必要です。ソースオブジェクトに対して s3:GetObjectTagging アクセス権限と、レプリケート先バケット内のオブジェクトに対する s3:PutObjectTagging アクセス権限が必要です。
  • 関連するバケットポリシーと IAM ポリシーを確認し、Resource 要素のパスが正しいことを確認します。バケットレベルのアクセス許可の場合、Resource 要素はバケットを指している必要があります。オブジェクトレベルのアクセス権限の場合、Resource 要素は 1 つ以上のオブジェクトをポイントしている必要があります。

例えば、s3:ListBucket といったバケットレベルのアクションのポリシーステートメントでは、次のようにバケットを Resource 要素で指定する必要があります。

"Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET"

s3:GetObject や s3:PutObject といったオブジェクトレベルのアクションのポリシーステートメントでは、次のように 1 つ以上のオブジェクトを Resource 要素で指定する必要があります。

"Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"

オブジェクトのオーナーシップ

バケットポリシーに正しいアクセス許可があり、バケット間でオブジェクトをコピーしても問題が解決しない場合は、どのアカウントがオブジェクトを所有しているかを確認します。バケットポリシーは、バケット所有者が所有するオブジェクトのみに適用されます。別のアカウントが所有するオブジェクトには、アクセスコントロールリスト (ACL) に対するアクセス許可が競合している可能性があります。

注: オブジェクトの所有権と ACL の問題は、通常、アカウント間で AWS のサービスログをコピーするときに発生します。サービスログの例には、AWS CloudTrail ログおよび Elastic Load Balancing アクセスログが含まれます。

オブジェクトを所有するアカウントを見つけるには、以下の手順に従います。

1.    Amazon S3 コンソールを開きます。

2.    バケット間でコピーできないオブジェクトに移動します。

3.    オブジェクトの [アクセス許可] タブを選択します。

4.    [オブジェクト所有者のアクセス] と [その他のAWS アカウントのアクセス] の値を確認します。

  • オブジェクトがアカウントによって所有されている場合、[Access for object owner] (オブジェクト所有者のアクセス) の [Canonical ID] (正規 ID) には、(あなたの AWS アカウント)が含まれます。
  • オブジェクトが別のアカウントによって所有され、そのオブジェクトにアクセスできる場合、次のようになります。
    [Access for object owner] (オブジェクト所有者のアクセス) の下の [Canonical ID] (正規 ID) には (外部アカウント) が含まれます。
    [Access for other AWS accounts] (他の AWS アカウントのアクセス) の [Canonical ID] (正規 ID) には、(あなたの AWS アカウント) が含まれています。
  • オブジェクトが別のアカウントによって所有され、そのオブジェクトにアクセスできない場合、次のようになります。
    [Access for object owner] (オブジェクト所有者のアクセス) と [Access for other AWS accounts] (他の AWS アカウントのアクセス) の両方の [Canonical ID] (正規 ID) フィールドは空です。

バケット間でコピーできないオブジェクトが別のアカウントによって所有されている場合、オブジェクト所有者は次のいずれかを実行できます。

  • オブジェクト所有者は、バケット所有者にオブジェクトのフルコントロールを付与することができます。バケット所有者がオブジェクトを所有すると、バケットポリシーがオブジェクトに適用されます。
  • オブジェクト所有者はオブジェクトの所有権を保持できますが、ACL をユースケースに必要な設定に変更する必要があります。

AWS KMS 暗号化

オブジェクトが AWS KMS キーを使用して暗号化されている場合は、IAM ID にキーに対する正しいアクセス権限があることを確認します。IAM ID と AWS KMS キーが同じアカウントに属している場合は、キーポリシーが必要な AWS KMS アクセス権限を付与していることを確認します。

IAM ID と AWS KMS キーが別のアカウントに属している場合は、必要なアクセス権限がキーポリシーと IAM ポリシーの両方で付与されていることを確認します。

例えば、2 つのバケット間でオブジェクトをコピーする場合 (各バケットには独自の KMS キーがあります)、IAM ID で以下を指定する必要があります。

  • kms:Decrypt アクセス権限 (最初の KMS キーを参照)
  • kms:GenerateDataKey および kms:Decrypt アクセス権限 (2 番目の KMS キーを参照)

詳細については、AWS KMS でキーポリシーを使用するAWS Key Management Service のアクション、リソース、および条件キーをご参照ください。

Amazon S3 Glacier のストレージクラス

Amazon S3 Glacier のストレージクラスからオブジェクトのコピーをできません。オブジェクトをコピーするには、まず、Amazon S3 Glacier からオブジェクトを復元する作業が必要になります。手順は、アーカイブされた S3 オブジェクトを復元する方法を参照してください。

バケットで有効化されているリクエスタ支払い

送信元または送信先バケットでリクエスタ支払いが有効になっていて、別のアカウントからバケットにアクセスしている場合は、リクエストを確認します。リクエストに正しいリクエスタ支払いパラメータが含まれていることを確認します。

  • AWS コマンドラインインターフェイス (AWS CLI) コマンドの場合は、--request-payer オプションを含めます。
    注: AWS CLI コマンドの実行時にエラーが発生した場合は、AWS CLI の最新バージョンを使用していることを確認してください
  • GET、HEAD、および POST リクエストの場合、x-amz-request-payer : requester を含めます。
  • 署名付き URL の場合は、x-amz-request-payer=requester を含めます。

AWS Organizations のサービスコントロールポリシー

AWS Organizations を使用している場合は、サービスコントロールポリシーで Amazon S3 へのアクセスが許可されていることを確認します。

たとえば、ポリシーが以下である場合に Amazon S3 にアクセスしようとするとアクセスが明示的に拒否されるため、403 Forbidden エラーが発生します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": "S3:*",
            "Resource": "*"
        }
    ]
}

AWS Organizations の機能の詳細については、組織内のすべての機能の有効化を参照してください。

Amazon S3 の VPC エンドポイントでのクロスリージョンリクエストの問題

Amazon S3 の VPC エンドポイントは、現在クロスリージョンリクエストをサポートしていません。例えば、リージョン A に Amazon Elastic Compute Cloud (Amazon EC2) インスタンスがあり、関連付けられたルートテーブルに VPC エンドポイントが設定されているとします。さらに、Amazon EC2 インスタンスは、リージョン B からリージョン A のバケットにオブジェクトをコピーすることはできません。代わりに、次のようなエラーメッセージが表示されます。

"An error occurred (AccessDenied) when calling the CopyObject operation: VPC endpoints do not support cross-region requests"

このクロスリージョンリクエストに関する問題をトラブルシューティングするには、以下の方法をお試しいただけます。

  • ルートテーブルから VPC エンドポイントを削除します。VPC エンドポイントを削除した場合、インスタンスは代わりにインターネットに接続できなければなりません。
  • VPC エンドポイントを使用していない別のインスタンスから copy コマンドを実行します。あるいは、リージョン A にもリージョン B にもないインスタンスから copy コマンドを実行します。
  • VPC エンドポイントを使用する必要がある場合は、GET リクエストを送信してソースバケットから EC2 インスタンスにオブジェクトをコピーします。次に、PUT リクエストを送信して、オブジェクトを EC2 インスタンスからコピー先バケットにコピーします。