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

最終更新日: 2020 年 3 月 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 アイデンティティ(ユーザーまたはロール)には、ソースバケットに対する s3:ListBucket および s3:GetObject アクションに対するアクセス許可が必要です。バケットが同じアカウントにある場合は、次にIAM ID のポリシーを使用してこれらのアクセス許可を設定できます。バケットが異なるアカウントにある場合は、次にバケットポリシーと IAM ID のポリシーの両方を使用してこれらのアクセス許可を設定します。
  • IAM ID には、少なくとも、送信先バケットの s3:ListBucket および s3:PutObject アクションに対するアクセス許可が必要です。バケットが同じアカウントにある場合は、IAM ID のポリシーを使用してこれらのアクセス許可を設定できます。バケットが異なるアカウントにある場合は、バケットポリシーと 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 アイデンティティに、ソースオブジェクトに対する s3:GetObjectTagging アクセス許可、およびコピー先バケットのオブジェクトに対する s3:PutObjectTagging アクセス許可が必要です。
  • 関連するバケットポリシーと IAM ポリシーを確認し、Resource 要素のパスが正しいことを確認します。 バケットレベルのアクセス許可の場合、Resource 要素はバケットを指している必要があります。オブジェクトレベルのアクセス許可の場合、Resource 要素は 1 つ以上のオブジェクトを指します。

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

"Resource": "arn:aws:s3:::awsexamplebucket"

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

"Resource": "arn:aws:s3:::awsexamplebucket/*"

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

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

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

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

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

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

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

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

  • オブジェクトがアカウントによって所有されている場合、[オブジェクト所有者のアクセス] の [Canonical ID] には、 (あなたの AWS アカウント)が含まれます。
  • オブジェクトが別のアカウントによって所有されており、そのオブジェクトにアクセスできる場合、[オブジェクト所有者のアクセス] の下の [Canonical ID] には (外部アカウント) が含まれます。[その他の AWS アカウントのアクセス] の [Canonical ID] には、 (あなたの AWS アカウント)が含まれています。
  • オブジェクトが別のアカウントによって所有されており、そのオブジェクトへのアクセス権がない場合、[オブジェクト所有者のアクセス] と [その他のAWS アカウントのアクセス] の両方に対する Canonical 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 のオプションを含めます。
  • 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 エンドポイントを使用していない別のインスタンスから、またはリージョン A とリージョン B のいずれでもないインスタンスから、コピーコマンドを実行します。
  • VPC エンドポイントを必ず使用しなければならない場合は、GET リクエストを送信してオブジェクトを送信元のバケットから EC2 インスタンスにコピーします。次に、PUT リクエストを送信して、オブジェクトを EC2 インスタンスから送信先のバケットにコピーします。