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

最終更新日: 2020 年 11 月 11 日

ある 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 アイデンティティ (ユーザーまたはロール) には、ソースバケットに対する 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.    [Access for object owner] (オブジェクト所有者のアクセス権) と [Access for other AWS accounts] (他の 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 キーが同じアカウントに属している場合は、キーポリシーによって次のアクションに対するアクセス許可が IAM ID に付与されていることを確認します 。

"Action": [
    "kms:Encrypt",
    "kms:Decrypt",
    "kms:ReEncrypt*",
    "kms:GenerateDataKey*",
    "kms:DescribeKey"
 ]

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

詳細については、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 エンドポイントが設定されている場合、このインスタンスはリージョン B からリージョン A にあるバケットにオブジェクトをコピーできません。その際、以下のようなエラーメッセージが表示されます。

「CopyObject オペレーションの呼び出し中にエラーが発生しました (AccessDenied): VPC エンドポイントはクロスリージョンリクエストをサポートしていません」

このクロスリージョンリクエストに関する問題をトラブルシューティングするには、以下の方法を使用できます。

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