Lambdaで、S3に画像がアップロードされたら、別のバケットにコピーする(python3)

[最終更新] 2018年8月3日

S3のバケットsrc-bucketに画像がアップロードされたら、それをトリガーにして別のバケットdest-bucketにコピーする関数をLambdaで作成する。言語はpython 3.6。

スポンサーリンク

やりたいこと

src-bucketにobj.jpgがアップロードされたら、自動的にobj.jpgをdest-bucketにコピーしたい。

AWSのLambdaを使って、そのような関数を作成する。

IAMロールの作成

Lambda関数に適用するIAM ロールを作成する。

IAMロールには、以下のポリシーを適用する。

  • AWSLambdaBasicExecutionRole
    • テンプレートにある
    • CloudWatch Logsに書き込むため
  • s3:GetObjectとs3:PutObjectをsrc-bucketおよびdest-bucketに対して利用できるようなポリシー

ビジュアルエディターで作ると楽。作ったもののjsonは以下。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::src-bucket/*",
                "arn:aws:s3:::dest-bucket/*"
            ]
        }
    ]
}

Resourceのバケット名は適当に。ちなみにこれだと、srcとdestの両方に読み書きの権限が与えられてしまうので、ちゃんとわけたほうが丁寧だが、ここでは一緒にする。

Lambda関数の作成

Lambda関数を作る。コンソール画面から行う。

IAMロールは前節で作ったものを適用する。ソースコードは以下。

import json
import urllib.parse
import boto3
import os

print('Loading function')

s3 = boto3.client('s3')


def lambda_handler(event, context):
    src_bucket  = os.getenv('SRC_BUCKET_NAME')
    dest_bucket = os.getenv('DEST_BUCKET_NAME')
    src_key  = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
    dest_key = src_key

    try:
        cp_src = f"{src_bucket}/{src_key}"
        print(f"src: {cp_src}")
        print(f"dest: {dest_bucket}/{dest_key}")
        response = s3.copy_object(Bucket=dest_bucket, CopySource=cp_src, Key=dest_key)
        return True
    except Exception as e:
        print(e)
        print('Error getting/putting object.')
        raise e

バケット名を環境変数でSRC_BUCKET_NAMEとDEST_BUCKET_NAMEにしているので、そのように設定する。

テストイベントは、「S3 Put」をテンプレートにして、event[‘Records’][0][‘s3’][‘object’][‘key’]に相当するところを、適当なファイル名にするとよい。そのファイル名で、src_bucketにファイルを上げておけば、テストができる。

トリガーの設定

テストがとおるようになったら、トリガーを設定する。Designerより、「トリガーの追加」からS3を選択し、「バケット」と「イベントタイプ」を選ぶ。バケットはsrc-bucket、イベントタイプは「オブジェクトの作成(すべて)」。トリガーの有効化にチェックを入れて追加。

これで、なにかsrc-bucketにアップロードして、dest-bucketにコピーされていればOK。

このトリガーの設定による影響を、S3の「プロパティ」→「Events」で確認できる。Lambda関数だけ消しても、Eventsの設定は残ることに注意。

参考

ありがとうございました。

関連コンテンツ

関連記事

スポンサーリンク

カテゴリーaws

コメントを残す

メールアドレスが公開されることはありません。