信頼はずっと、挑戦はもっと。

お問い合わせ
TEL:03-3496-3888

BLOG コアテックの社員ブログ (毎週月曜~金曜更新中)

2020

26

5月

Lambdaを試してみました

テクログ

お久しぶりです。

在宅勤務になり、時間に余裕ができたのでAWSを色々試していました。


今回はLambdaについて紹介したいと思います。

処理の内容はS3のimagesにjpgの画像をアップすると、別のバケットにリサイズされた画像がアップされ、画像のアップロードパスと登録日時がdynamoDBに登録されます。


まず、Lambda上でPillowを使えるようにするために、EC2で下記を実行しました。

sudo yum -y install gcc openssl-devel bzip2-devel libffi-devel
wget https://www.python.org/ftp/python/3.8.1/Python-3.8.1.tgz
tar xzf Python-3.8.1.tgz
cd Python-3.8.1
sudo ./configure --enable-optimizations
sudo make altinstall
pip3.8 install pillow -t .

上記で作成されたPILとPillow.libsとPillow-7.1.2.dist-infoとlambda_function.pyをzipで固めてアップロードします。


次にLambdaのトリガーの設定ですが、S3を選択し、下記内容を入力し、追加をクリックします。

バケット sample
イベントタイプ すべてのオブジェクト作成イベント
プレフィックス-オプション images/
サフィックス-オプション .jpg
トリガーの有効化 チェック


次にdynamoDBで画像管理テーブルとautoincrementがないためidを管理するテーブルを作成します。

テーブルを作成後、idsテーブルにtable_nameがs3_images、idが0を登録します。

・s3_images
id 主キー   数値型
upload_path 文字列型
created_at  文字列型

・ids
table_name 主キー 文字列型
id                数値型


次にS3で下記の二つのバケットを作成します。

sample
sample-resize


最後にlambda_function.pyは下記の内容です。

import boto3
import os
import sys
import uuid
from urllib.parse import unquote_plus
from PIL import Image
import PIL.Image
import datetime

s3_client = boto3.client('s3')
dynamodb = boto3.resource('dynamodb')

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)

def get_id(table_name):
  table = dynamodb.Table('ids')
  data = table.update_item(
    Key = {
      'table_name': table_name
    },
    UpdateExpression = 'ADD id :id_val',
    ExpressionAttributeValues = {
      ':id_val': 1
    },
    ReturnValues = "UPDATED_NEW"
  )
   
  res = table.get_item(
    Key = {
      'table_name': table_name
    }
  )
  return res['Item']['id']

def insert_dynamodb(id, upload_path):
  table= dynamodb.Table('s3_images')
  now = datetime.datetime.now()
  table.put_item(
    Item = {
      'id': id,
      'upload_path': upload_path,
      'created_at': now.strftime("%Y-%m-%d %H:%M:%S")
    }
  )

def lambda_handler(event, context):
  for record in event['Records']:
    bucket = record['s3']['bucket']['name']
    key = unquote_plus(record['s3']['object']['key'])
    tmpkey = key.replace('/', '')
    download_path = '/tmp/{}{}'.format(uuid.uuid4(), tmpkey)
    upload_path = '/tmp/resized-{}'.format(tmpkey)
    s3_client.download_file(bucket, key, download_path)
    resize_image(download_path, upload_path)
    s3_client.upload_file(upload_path, '{}-resized'.format(bucket), key)
     
    id = get_id('s3_images')
    insert_dynamodb(id, upload_path)


これでS3のsampleバケットのimagesにjpgの画像をアップすると、sample-resizeバケットにリサイズされた画像がアップされます。

Lambdaの設定は一部割愛しましたが、以上となります。

この記事を書いた人

画像:投稿者アイコン

JG

所 属:
WEBインテグレーション事業部
出身地:
神奈川県
仕事内容:
プログラム