この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
前回の S3イベントバージョンです。Chaliceを使ってS3の各種イベントをトリガーにLambdaを起動してみたいと思います。
環境
- macOS Catalina 10.15.4
- Python 3.7.7
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.15.4
BuildVersion: 19E287
$ python3 -VV
Python 3.7.7 (default, Mar 10 2020, 15:43:33)
[Clang 11.0.0 (clang-1100.0.33.17)]
やってみる
仮想環境の作成
今回は Python で標準機能の venv
を利用します。
$ mkdir chalice-example && cd chalice-example
$ python3 -m venv venv
仮想環境の有効化
$ source ./venv/bin/activate
(venv) $
Chaliceのインストール
(venv) $ pip install chalice
パッケージのインストール
画像処理に使用するパッケージをインストールします。
(venv) $ pip install boto3 Pillow
プロジェクトの作成
new-project
コマンドを利用してプロジェクトの雛形を作成します。s3-event-lambda フォルダが作成され、各種ファイルが作成されています。
(venv) $ chalice new-project s3-event-lambda
コーディング
app.py
の内容を下記のようにします。処理内容は指定したバケットにオブジェクトが作成された時に、キーが prefix
、suffix
に合致するものを通知対象としています。画像のリサイズを行い、別のバケットにアップロードしています。
app.py
import logging
import uuid
import boto3
from PIL import Image
from chalice import Chalice
from chalice.app import S3Event
app = Chalice(app_name='s3-event-lambda')
app.log.setLevel(logging.INFO)
s3 = boto3.client('s3')
def resize_image(image_path, resized_path):
with Image.open(image_path) as image:
image.thumbnail(tuple(x / 2 for x in image.size))
image.save(resized_path)
@app.on_s3_event(bucket='chalice-s3-event-demo', # 必須: 対象バケット名
events=['s3:ObjectCreated:*'], # オプション: 対象イベント (省略時は s3:ObjectCreated:*)
prefix='images/', # オプション: 対象プレフィックス
suffix='jpg', # オプション: 対象サフィックス
name='resize-image') # オプション: Lambda名 (省略時は関数名を使用)
def lambda_handler(event: S3Event):
bucket = event.bucket
key = event.key
tmp_key = key.replace('/', '')
image_path = '/tmp/{}{}'.format(uuid.uuid4(), tmp_key)
resized_path = '/tmp/resized-{}'.format(tmp_key)
s3.download_file(bucket, key, image_path)
resize_image(image_path, resized_path)
s3.upload_file(resized_path, '{}-resized'.format(bucket), key)
app.log.info("resized image: %s", event.key)
必要なライブラリの設定
実行に必要なライブラリを requirements.txt
に記載します。これによりデプロイ時に一緒にアップロードされます。
(venv) $ pip freeze | grep boto3 >> requirements.txt
(venv) $ pip freeze | grep Pillow >> requirements.txt
(venv) $ cat requirements.txt
boto3~=1.12.42
Pillow~=7.1.1
S3バケットの作成
画像をアップロードするバケットと、リサイズした画像をアップロードするバケットを作成します。バケット名はユニークである必要があるので、ソースコードとあわせて適宜変更してください。
$ aws s3 mb s3://chalice-s3-event-demo
make_bucket: chalice-s3-event-demo
$ aws s3 mb s3://chalice-s3-event-demo-resized
make_bucket: chalice-s3-event-demo-resized
デプロイ
(venv) $ chalice deploy --stage dev
Creating deployment package.
Creating IAM role: s3-event-lambda-dev
Creating lambda function: s3-event-lambda-dev-resize-image
Configuring S3 events in bucket chalice-s3-event-demo to function s3-event-lambda-dev-resize-image
Resources deployed:
- Lambda ARN: arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:s3-event-lambda-dev-resize-image
作成されたものを確認
Lambda
IAMロール
ポリシーにS3の権限が自動で付与されています。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:AbortMultipartUpload",
"s3:GetObject",
"s3:PutObject"
],
"Resource": [
"*"
],
"Sid": "49a732cbfcc7454f8c3fc9ced179612d"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
}
]
}
S3バケットのイベント設定
オブジェクトの作成イベントでLambdaが呼び出される設定になっています。
動作確認
S3にトリガー条件に適合する画像をアップロードして見ます。
リサイズ用のバケットを確認します。Lambdaによってリサイズ処理されていることが分かります。
ログを確認します。
後片付け
次のコマンドで作成したリソースが削除できます。ロググループは削除されないので手動で消す必要があります。
(venv) $ chalice delete --stage dev
指定できるイベント
下記が指定できるイベント一覧です。複数組み合わせて指定することができます。詳細はAWSドキュメントをご参照ください。
Amazon S3 イベント通知の設定 - Amazon Simple Storage Service
- s3:ObjectCreated:*
- s3:ObjectCreated:Put
- s3:ObjectCreated:Post
- s3:ObjectCreated:Copy
- s3:ObjectCreated:CompleteMultipartUpload
- s3:ObjectRemoved:*
- s3:ObjectRemoved:Delete
- s3:ObjectRemoved:DeleteMarkerCreated
- s3:ObjectRestore:Post
- s3:ObjectRestore:Completed
- s3:ReducedRedundancyLostObject
- s3:Replication:OperationFailedReplication
- s3:Replication:OperationMissedThreshold
- s3:Replication:OperationReplicatedAfterThreshold
- s3:Replication:OperationNotTracked
さいごに
スケジュール実行と同様に非常に簡単にS3イベントと連携できるLambdaが作成できました。