はじめに
筆者はAWS認定ソリューションアーキテクト-プロフェッショナル合格に向けて勉強中ですが、座学はあまり性に合わずできるだけ手を動かして勉強したいため、本ブログを通じて AWS の様々なサービスを使ってみようと思っています。本日はLambdaをメインに勉強してみようと思います。
Lambda とは
AWS Lambda は、サーバーレスでイベント駆動型のコンピューティングサービスであり、サーバーのプロビジョニングや管理をすることなく、事実上あらゆるタイプのアプリケーションやバックエンドサービスのコードを実行することができます。(出典:AWS Lambda)
今回考えたアーキテクチャ
ざっくり以下のような感じです。
- Boto3を使ってS3にファイルをPUT
- S3にファイルがPUTされるとLambdaが起動
- Lambdaのローカル保存先(/tmp)にファイルを保存、ファイル名を変更してS3にPUT
実行環境
macOS 11.3.1
Python 3.9.6
Boto3 1.20.53
手順
1.S3にバケットを作成
2022-sanvarie-bucket というバケットを作成します。設定はデフォルトでOKです。
2.S3にファイルをPUTするプログラムを作成
Boto3を使ってS3にファイルをPUTします。Boto3に関しては以下のエントリーに書いてありますのでご参照ください。
また、ファイルは以下の画像(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と様々なサービスを組み合わせてサーバーレスなアプリを作ってみようと思います。