概要
layerのコードをアップデートするPythonスクリプトを作成した。
背景と目的
Lambda レイヤーのコードをデバッグしていて、手動でアップロードするのが面倒になってきたので、スクリプト化した。
詳細
zipの構造の確認
手動でアップロードする場合、.zipファイルの構造としては、を解凍した時に以下のようになる必要がある。すなわち、pythonというフォルダが出てきて、その中にレイヤー名フォルダが入る形。
python/ レイヤー名フォルダ/ __init__.py ソースコード.py
作成したスクリプト
作成したものは以下。
引数として、レイヤー名と同じ名前のフォルダがあってその中にソースコードが入っている想定で、そのレイヤー名フォルダのパスを指定する。
一時フォルダpythonを作ってそこにソースコードを入れて、圧縮することで、必要な構造を実現する。
送信は、boto3を使う。CompatibleRuntimesは、適宜設定。
import zipfile import os import json import boto3 import sys import shutil """ Lambdaのlayerを更新 update_layer.py target target ------------------------- 親フォルダ/ python.zip --- 一時zip python/ --- zip作成用一時ディレクトリ : レイヤー名フォルダがコピーされる レイヤー名ディレクトリ/ --- ここを引数targetで指定 __init__.py ソースコード.py """ zipFileName = "python.zip" CompatibleRuntimes = [ 'python3.7', 'python3.8' ] target = None if len(sys.argv) >= 2: target = sys.argv[1] print("sys.argv[1]", sys.argv[1]) if target is None: print("no args") sys.exit() # 出力先 outputDir = os.path.dirname(target) # zip出力先 LayerName = os.path.basename(target) # フォルダ名のみ pythonDir = os.path.join(outputDir, "python") zipFilePath = os.path.join(outputDir, zipFileName) # 念のため一時ファイルを削除 try: os.remove(zipFilePath) except: pass try: shutil.rmtree(pythonDir) except: pass # 一時ディレクトリ作成 os.makedirs(pythonDir, exist_ok=True) # ソースコードフォルダをコピー shutil.copytree(target, os.path.join(pythonDir, LayerName)) # ZIPファイルを作成 zipFile = zipfile.ZipFile(zipFilePath, 'w') # 圧縮するファイルのディレクトリへ移動 os.chdir(outputDir) # ZIPファイルに追加 for dirName, dirs, files in os.walk(pythonDir): # dirNameの絶対パスを相対パス化 dirName2 = dirName.replace("\\", "/").replace(outputDir.replace("\\", "/") + "/", "") #print("dirName2", dirName2) for fileName in files: filepath = os.path.join(dirName2, fileName) print("filepath", filepath) zipFile.write(filepath, compress_type=zipfile.ZIP_DEFLATED) # 閉じる zipFile.close() # zipをバイナリで読み取る fo = open(zipFilePath, "rb") zf = fo.read() fo.close() # アップロード client = boto3.client("lambda") resp = client.publish_layer_version( LayerName=LayerName, Content={ 'ZipFile': zf }, CompatibleRuntimes=CompatibleRuntimes ) # 一時ファイル削除 try: os.remove(os.path.join(outputDir, zipFileName)) except: pass shutil.rmtree(pythonDir) # 結果 print(json.dumps(resp, indent=4))
テスト
無事、更新され新しいバージョンが発行された。
まとめと今後の課題
これで、少しレイヤー周りのデバッグが楽になる。