S3にアップロードされたZIPファイル自動解凍について:
Cloudfrontに繋いでいるS3へのファイルアップロードを簡素化するため、Zipファイル格納用S3に新しいZipファイルのアップロードが検知されたら、対象Lambdaが有効化され、Zipファイル格納用S3からZipファイルをダウンロードして解凍し、Cloudfront用S3にアップロードします。
本記事はそれを実現するlambdaを紹介いたします。
処理フロー:
- Zip格納用S3にZipファイルのアップロードが検知された
↓ - 自動解凍&アップロードLambdaを呼び出す
↓ - (Lambda) Zip格納用S3から対象Zipファイルをダウンロードする
↓ - (Lambda) 対象Zipファイルを解凍する
↓ - (Lambda) 解凍した資材一式をCloudfront用S3にアップロードする
↓
終了
Lambda作成:
以下の手順を踏んで作成します
- AWSコンソール画面の上部にある検索欄から「Lambda」を入力し、検索する
- Lambda詳細画面の左メニューの「関数」をクリックする
- 右上の「関数の作成」をクリックする
- 「一から作成」を選択する
- 「関数名」には任意の文字を入力する
- 「ランタイム」は「Python 3.8」を選択する
- 「関数の作成」をクリックする
- Lambda初期生成完了まで待つ
- 「設定」タブをクリックし、「一般設定」を編集する
- 「タイムアウト」項目を3分に修正する
- 「環境変数」項目にアップロード先のS3 URLを入力する
- 「保存」を押す
- 「アクセス権限」をクリックし、ロール名をクリックする
- ロール設定画面に遷移され、許可ポリシーに必要な権限を付与する
- S3画面に遷移し、画面上部に「プロパティ」を選択する
- 「イベント通知」項目まで遷移する
- 「イベント通知を作成」をクリックする
- 「イベント名」を入力する
- 「イベントタイプ」に「すべてのオブジェクト作成イベントs3:ObjectCreated:*」を選択する
- 「送信先」は先ほど作成したlambdaを指定する
完了
ZIPファイル自動解凍再アップロードLambdaサンプルコード:
s3_eport.py
import os
import zipfile
import boto3
from tempfile import TemporaryDirectory
def lambda_handler(event, context):
# 転送先S3のイベントトリガーから情報を取得
destination_bucket = os.environ.get('DESTINATION_BUCKET')
source_bucket = event['Records'][0]['s3']['bucket']['name']
print("(1/7 対象S3読み取り:"+source_bucket+")")
source_key = event['Records'][0]['s3']['object']['key']
print("(2/7 対象Zipファイル読み取り:"+source_key+")")
# 転送先S3クライアントを作成
s3 = boto3.client('s3')
print("(3/7 Lambda用S3 Client)")
# 対象Cloudfront用Zipファイルをダウンロードおよび展開
with TemporaryDirectory() as temp_dir:
print("(4/7 S3 Clientに対象Zipファイルをダウンロードし展開)")
download_path = os.path.join(temp_dir, source_key)
s3.download_file(source_bucket, source_key, download_path)
print("(5/7 "+destination_bucket+" にアップロード開始)")
with zipfile.ZipFile(download_path, 'r') as zip_ref:
for file_info in zip_ref.infolist():
file_content = zip_ref.read(file_info.filename)
file_name = file_info.filename.encode('cp437').decode('cp932')
print("(6/7 エンコード完了:"+file_name+")")
destination_key = file_name
s3.put_object(Body=file_content, Bucket=destination_bucket, Key=destination_key)
print("(7/7 "+destination_bucket+" アップロード完了)")
return {
'statusCode': 200,
'body': 'Files extracted and uploaded to destination bucket.'
}
最後に:
Cloudfrontを運用するとき、ファイルの差し替えなどが面倒で、ファイル解凍とアップロードがLambdaで自動で行うと色々便利になると思います。
本記事を参考いただき、お役に立っていれば幸いです。