AWSの部屋

AWS学習者向けのブログです

S3 に格納したファイルを Lambda で操作してみる

はじめに

筆者はAWS認定ソリューションアーキテクト-プロフェッショナル合格に向けて勉強中ですが、座学はあまり性に合わずできるだけ手を動かして勉強したいため、本ブログを通じて AWS の様々なサービスを使ってみようと思っています。本日はLambdaをメインに勉強してみようと思います。

Lambda とは

AWS Lambda は、サーバーレスでイベント駆動型のコンピューティングサービスであり、サーバーのプロビジョニングや管理をすることなく、事実上あらゆるタイプのアプリケーションやバックエンドサービスのコードを実行することができます。(出典:AWS Lambda

今回考えたアーキテクチャ

ざっくり以下のような感じです。

  1. Boto3を使ってS3にファイルをPUT
  2. S3にファイルがPUTされるとLambdaが起動
  3. Lambdaのローカル保存先(/tmp)にファイルを保存、ファイル名を変更してS3にPUT

実行環境

macOS 11.3.1
Python 3.9.6
Boto3 1.20.53

手順

  1. S3にバケットを作成
  2. S3にファイルをPUTするプログラムを作成
  3. Lambdaに付与するIAMロールを作成
  4. Lambda関数を作成
  5. 作成したバケットにイベント通知を作成
  6. 動作確認

1.S3にバケットを作成

2022-sanvarie-bucket というバケットを作成します。設定はデフォルトでOKです。

2.S3にファイルをPUTするプログラムを作成

Boto3を使ってS3にファイルをPUTします。Boto3に関しては以下のエントリーに書いてありますのでご参照ください。

aws-room.hatenablog.com

また、ファイルは以下の画像(hane.jpg)を使用します。

import os
import boto3

s3 = boto3.resource('s3')
bucket = s3.Bucket('2022-sanvarie-bucket')
filepath = '/Users/xxx/Documents/AWS/blog/data/hane.jpg'

# S3にアップロード
bucket.upload_file(filepath, os.path.basename(filepath))

試しに動かしてみます。

対象のファイルがPUTされたことがわかりました。

3.Lambdaに付与するIAMロールを作成

LambdaがS3と連携できるようにIAMロールを作成します。

4.Lambda関数を作成

save-file という Lambda関数を作ってみます。

関数を作成すると関数内で実行するコードの編集が可能になります。

import os
from datetime import datetime
import urllib.parse
import boto3
import subprocess

s3 = boto3.resource('s3')

def lambda_handler(event, context):

    # 対象のバケットとファイル名取得
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
    
    # Lambdaのローカルのファイル保存先(/tmp)を設定
    file_path = '/tmp/' + datetime.now().strftime('%Y-%m-%d-%H-%M-%S')

    try:
        bucket = s3.Bucket(bucket) 
        
        # /tmpにダウンロード用のフォルダを作成
        cmd = ['mkdir', '-p', file_path]
        subprocess.run(cmd, stdout=subprocess.PIPE)

        # S3に格納したファイルを作成したフォルダにダウンロード
        bucket.download_file(key, os.path.join(file_path, key))   

        # ファイルの名前を変えてS3にPUT
        bucket.upload_file(os.path.join(file_path, key), 'hane2.jpg')

        return
    except Exception as e:
        print(e)

5.作成したバケットにイベント通知を作成

以下のようにイベント通知を作成します。

6.動作確認

「2.S3にファイルをPUTするプログラムを作成」のプログラムを実行し、S3にhane.jpg と hane2.jpg が格納されることを確認しました。

さいごに

S3 と Lambda の連携ですがかなり簡単にできることがわかりました。ただ、まだ基本的なことところしか触ってないので、今後はLambdaと様々なサービスを組み合わせてサーバーレスなアプリを作ってみようと思います。