Amazon S3 Batch Operations を使用して 5 GB を超えるオブジェクトをコピーする方法を教えてください。
あるバケット内の 5 GB を超える Amazon Simple Storage Service (Amazon S3) オブジェクトを別のバケットにコピーしたいです。
簡単な説明
あるバケットから別のバケットに 5 GB を超える Amazon S3 オブジェクトをコピーするには、AWS Lambda 関数で S3 Batch Operations を使用します。詳細については、「Amazon S3 Batch Operations を使用して 5GB を超えるオブジェクトをコピーする」を参照してください。
注: マルチパートアップロード API を使用しても、5 GB を超える Amazon S3 オブジェクトをコピーできます。詳細については、「マルチパートアップロードを使用してオブジェクトをコピーする」を参照してください。
解決策
始める前に、オブジェクトのコピー先となる S3 バケットが作成済みであることを確認してください。
Lambda 関数を作成する
次の手順を実行します。
-
Lambda コンソールを開きます。
-
[関数の作成] を選択します。
-
[最初から作成] を選択します。
-
[関数名] に関数名を入力します (例: S3BatchCopy)
-
[ランタイム] ドロップダウンリストを選択し、[Python 3.9] を選択します。
-
[アーキテクチャ] で [x86_64] を選択し、[関数を作成] を選択します。
-
組み込みのコードエディタに Lambda 関数のコードを入力します。
Lambda 関数コードの例import boto3 import os from urllib import parse from botocore.client import Config from boto3.s3.transfer import TransferConfig target_bucket = os.environ['destination_bucket'] new_prefix = os.environ['destination_bucket_prefix'] metadata_copy = os.environ['copy_metadata'] tagging_copy = os.environ['copy_tagging'] storage_class = os.environ['copy_storage_class'] # Added storage class s3Client = boto3.client('s3', config=Config(retries={'max_attempts': 3})) def lambda_handler(event, context): task = event['tasks'][0] s3Key = parse.unquote_plus(task['s3Key'], encoding='utf-8') s3VersionId = task['s3VersionId'] s3Bucket = task['s3BucketArn'].split(':')[-1] try: copy_source = {'Bucket': s3Bucket, 'Key': s3Key} if s3VersionId: copy_source['VersionId'] = s3VersionId newKey = f"{new_prefix}/{s3Key}" if new_prefix else s3Key myargs = { 'ACL': 'bucket-owner-full-control', 'StorageClass': storage_class # Added storage class to copy arguments } # Add metadata if enabled if metadata_copy == 'Enable': get_metadata = s3Client.head_object(Bucket=s3Bucket, Key=s3Key, VersionId=s3VersionId if s3VersionId else None) for key in ['CacheControl', 'ContentDisposition', 'ContentEncoding', 'ContentLanguage', 'Metadata', 'WebsiteRedirectLocation', 'Expires']: if value := get_metadata.get(key): myargs[key] = value # Add tagging if enabled if tagging_copy == 'Enable': get_obj_tag = s3Client.get_object_tagging(Bucket=s3Bucket, Key=s3Key, VersionId=s3VersionId if s3VersionId else None) if tag_set := get_obj_tag.get('TagSet'): myargs['Tagging'] = "&".join([f"{parse.quote_plus(d['Key'])}={parse.quote_plus(d['Value'])}" for d in tag_set]) response = s3Client.copy(copy_source, target_bucket, newKey, ExtraArgs=myargs) result = {'resultCode': 'Succeeded', 'resultString': str(response)} except Exception as e: result = {'resultCode': 'PermanentFailure', 'resultString': str(e)} return { 'invocationSchemaVersion': event['invocationSchemaVersion'], 'treatMissingKeysAs': 'PermanentFailure', 'invocationId': event['invocationId'], 'results': [{'taskId': task['taskId'], **result}] } -
[デプロイ] を選択します。
Lambda 関数用の IAM ロールを作成する
次の手順を実行します。
-
ナビゲーションペインで [ロール] を選択し、[ロールを作成] を選択します。
-
[信頼されたエンティティタイプ] で [AWS サービス] を選択します。
-
[ユースケース] ドロップダウンリストから [Lambda] を選択します。
-
[次へ] を選択します。
-
AWSLambdaBasicExecutionRole ポリシーを選択し、[次へ] を選択します。
-
[ロール名] に名前を入力します (例: LambdaS3BatchRole)。
-
次のポリシーをアタッチします。
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "s3:GetObject", "s3:GetObjectAcl", "s3:GetObjectTagging", "s3:GetObjectVersion", "s3:GetObjectVersionAcl", "s3:GetObjectVersionTagging", "s3:ListBucket*" ], "Resource": "*", "Effect": "Allow" }, { "Action": [ "s3:PutObject", "s3:PutObjectAcl", "s3:PutObjectTagging", "s3:PutObjectLegalHold", "s3:PutObjectRetention", "s3:GetBucketObjectLockConfiguration", "s3:ListBucket*", "s3:GetBucketLocation" ], "Resource": [ "arn:aws:s3:::amzn-s3-demo-destination-bucket", "arn:aws:s3:::amzn-s3-demo-destination-bucket/*" ], "Effect": "Allow" } ] } -
[ロールの作成] を選択します。
注: カスタマーマネージド AWS Key Management Service (AWS KMS) キーを使用してバケットを暗号化する場合、IAM ロールでは追加のアクセス許可を付与する必要があります。詳細については、「Amazon S3 バケットにカスタム AWS KMS キーを使用したデフォルトの暗号化が設定されています。ユーザーがそのバケットでダウンロードやアップロードを行えるようにする方法を教えてください」を参照してください。
Batch Operations のアクセス許可ポリシーを作成する
次の手順を実行します。
-
IAM コンソールを開きます。
-
ナビゲーションペインで [ロール] を選択し、[ロールを作成] を選択します。
-
[信頼されたエンティティタイプ] で AWS サービスを選択します。
-
[ユースケース] ドロップダウンリストから [S3] を選択します。
-
[S3 Batch Operations] を選択します。
-
[次へ] を選択します。
-
[ロール名] に名前を入力します (例: S3BatchOperationsRole)。
-
次のポリシーをアタッチします。
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "s3:GetObject", "s3:GetObjectVersion", "s3:GetBucketLocation" ], "Resource": [ "arn:aws:s3:::amzn-s3-demo-manifest-bucket", "arn:aws:s3:::amzn-s3-demo-manifest-bucket/" ], "Effect": "Allow" }, { "Action": [ "s3:PutObject", "s3:GetBucketLocation" ], "Resource": [ "arn:aws:s3:::amzn-s3-demo-completion-report-bucket", "arn:aws:s3:::amzn-s3-demo-completion-report-bucket/" ], "Effect": "Allow" }, { "Action": [ "lambda:InvokeFunction" ], "Resource": "arn_of_lambda_function_created_in_step1", "Effect": "Allow" } ] } -
[ロールの作成] を選択します。
Batch Operations ジョブを作成する
次の手順を実行します。
- Amazon S3 コンソールを開きます。
- ナビゲーションペインで [Batch Operations] を選択し、[ジョブの作成] を選択します。
- [マニフェスト形式] には [S3 インベントリレポート] または [CSV] を選択します。
- [マニフェストオブジェクト] で [S3 を参照] を選択します。
- オブジェクトのコピー元となるソースバケットを選択します。
- ソースバケット内のオブジェクトを選択し、[パスの選択] を選択します。
- [次へ] を選択します。
- [操作を選択] で [Copy] を選択します。
- [コピー先] で [S3 を参照] を選択します。
- オブジェクトのコピー先となる宛先バケットを選択し、[パスの選択] を選択します。
- [同じ名前の既存のオブジェクトは上書きされることを理解しています] を選択し、[次へ] を選択します。
- [アクセス許可] で [IAM ロール] ドロップダウンリストを選択し、該当する S3BatchOperationsRole IAM ロールを選択します。
- [次へ] を選択し、[ジョブの作成] を選択します。
クロスアカウントアクセス
宛先 S3 バケットが別の AWS アカウントにある場合は、リソースベースのポリシーをバケットにアタッチする必要があります。
リソースベースのポリシー例
{ "Version": "2012-10-17", "Id": "Policy1541018284691", "Statement": [ { "Sid": "Allow Cross Account Copy", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::SourceAccountNumber:role/LambdaS3BatchRole" }, "Action": [ "s3:PutObject", "s3:PutObjectAcl", "s3:PutObjectTagging" ], "Resource": "arn:aws:s3:::DESTINATION_BUCKET/*" } ] }
詳細については、「別の AWS アカウントから Amazon S3 オブジェクトをコピーする方法を教えてください」を参照してください。
関連情報
Amazon S3 Batch Operations に関する問題のトラブルシューティング方法を教えてください
ある Amazon S3 バケットのすべてのオブジェクトを別のバケットにコピーする方法を教えてください
ある Amazon S3 バケットから別の Amazon S3 バケットに大量のデータを転送するのに最適な方法を教えてください
関連するコンテンツ
質問済み 1年前
