AWS Lambda 関数を使用して、Amazon Simple Storage Service (Amazon S3) バケットから別のバケットにファイルをコピーしようとしています。
解決策
次の手順を実行し、コピーされたファイルをソースの Amazon S3 バケットから宛先の S3 バケットにコピーする Lambda 関数を作成します。
ソースと宛先用の S3 バケットを作成する
注: 既にソースと宛先の S3 バケットを作成済みの場合は、このステップをスキップします。
次の手順を実行します:
- Amazon S3 コンソールを開きます。
- [バケットの作成] を選択します。
- [バケット名] にソースバケットの名前を入力します。
- [バケットを作成] を選択します。
- 宛先のバケットに対して、ステップ 1~4を繰り返します。
詳細については、「バケットの作成」を参照してください。
Lambda 関数を作成します
次の手順を実行します:
-
Lambda コンソールで [関数] ページを開きます。
-
[関数を作成] を選択し、[最初から作成] を選択します。
-
[関数名] に関数の名前を入力します。
-
[ランタイム] ドロップダウンリストから [Python 3.13] を選択します。
-
[デフォルトの実行ロールの変更] を展開し、[基本的なアクセス許可を持つ新しいロールを作成] を選択します。
-
[関数の作成] を選択します。
-
[コード] タブを選択し、次の Python コードを貼り付けます:
import boto3
import botocore
import json
import os
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
s3 = boto3.resource('s3')
def lambda_handler(event, context):
logger.info("New files uploaded to the source bucket.")
key = event['Records'][0]['s3']['object']['key']
source_bucket = event['Records'][0]['s3']['bucket']['name']
destination_bucket = os.environ['destination_bucket']
source = {'Bucket': source_bucket, 'Key': key}
try:
response = s3.meta.client.copy(source, destination_bucket, key)
logger.info("File copied to the destination bucket successfully!")
except botocore.exceptions.ClientError as error:
logger.error("There was an error copying the file to the destination bucket")
print('Error Message: {}'.format(error))
except botocore.exceptions.ParamValidationError as error:
logger.error("Missing required parameters while calling the API.")
print('Error Message: {}'.format(error))
注: Lambda 関数が受け取るイベントオブジェクトから source_bucket 名を検索します。destination_bucket 名を環境変数として保存できます。
-
[デプロイ] を選択します。
Lambda は、関数が Amazon CloudWatch にログをアップロードするためのアクセス許可を付与する実行ロールを作成します。詳細については、「コンソールで Lambda 関数を作成する」を参照してください。
Lambda 関数のために Amazon S3トリガーを作成します
次の手順を実行します:
- Lambda コンソールで関数のページを開きます。
- [関数] で Lambda 関数を選択します。
- [関数の概要] で、[トリガーを追加] を選択します。
- [トリガーの設定] ドロップダウンリストで、[S3] を選択します。
- [バケット] に、ソースバケットの名前を入力します。
- 「イベントタイプ」 ドロップダウンリストから、[すべてのオブジェクト作成イベント] を選択します。
注: POST、PUT、またはマルチパートアップロードイベントタイプを使用してオブジェクトをアップロードするようにこのステップを設定します。
- [入力と出力の両方に同じ S3 バケットを使用することは推奨されていないことに同意します] を選択し、[追加] を選択します。
詳細については、「チュートリアル: Amazon S3トリガーを使用してLambda 関数を呼び出す」を参照してください。
Lambda 関数の実行ロールに IAM 権限を提供
コピー先の S3 バケットにファイルをコピーするには、Lambda 関数の実行ロールに AWS Identity and Access Management (IAM) アクセス許可を追加します。次のようなリソースベースのポリシーを使用します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "putObject",
"Effect": "Allow",
"Action": [
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::destination-s3-bucket/*"
]
},
{
"Sid": "getObject",
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::source-s3-bucket/*"
]
}
]
}
注:
- destination-s3-bucket を S3 の宛先バケットに、source-s3-bucket を S3 のソースバケットに置き換えます。
- リソースの ARN の末尾にある /* を環境に必要なプレフィックス値に置き換えると、アクセス許可を制限できます。
- タスクを実行するための最小限の権限を付与することをおすすめします。
- オブジェクトタグを含むオブジェクトをコピーするには、s3:GetObjectTagging アクセス許可と s3:PutObjectTagging アクセス許可が必要です。ソースオブジェクトには s3:GetObjectTagging アクセス許可、宛先バケット内のオブジェクトには s3:PutObjectTagging アクセス許可が必要です。
詳細については、「Lambda 関数に AWS サービスへのアクセスを付与する」を参照してください。
関連情報
Amazon S3 が返す 403 Access Denied エラーのトラブルシューティング方法を教えてください
Lambda 関数に Amazon S3 バケットへのアクセスを許可する方法を教えてください