2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

LambdaからLambdaをさっくりデプロイするためのメモ

Last updated at Posted at 2019-08-11

tl;dr

  • 管理ソースが多くなるにつれていちいちコンソールで編集やアップロードが面倒になったのでCIからデプロイで自動化したくなった
  • LambdaへのデプロイをLambdaにやらせるのが手っ取り早そう
  • CI(zip化してS3デプロイ) -> S3 -> イベントトリガーでLambda起動(デプロイ) -> Lambda関数の更新

用意するもの

  • CI(よしなに)
  • zip放置用のS3
  • デプロイ実行用のLambda関数
  • デプロイされるLambda関数

CI(よしなに)

  • 好きなものをどうぞ
  • ビルド -> zip化 -> S3までデプロイする感じで

import boto3
import glob
import os
import shutil
import mimetypes
from datetime import datetime
from datetime import timedelta
import traceback
import json

BUILD_DIR = "YOUR_BUILD_DIR"

LAMBDA_PROJECT_LIST_JSON = "./YOUR_PROJECT.json"

AWS_ACCESS_KEY = "YOUR_AWS_ACCESS_KEY"
AWS_ACCESS_SECRET = "YOUR_AWS_ACCESS_SECRET"

AWS_S3_BUCKET = "YOUR_AWS_S3_BUCKET"
AWS_REGION = "YOUR_AWS_REGION"

def run():
  # YOUR_BUILD_DIRディレクトリ削除
  # YOUR_BUILD_DIRディレクトリ作成
  # zipファイル作ってYOUR_BUILD_DIRに突っ込む
  # s3デプロイ

  with open(LAMBDA_PROJECT_LIST_JSON,"r") as l:
    lambda_project_list = json.load(l)

    try:
      if (AWS_ACCESS_KEY in os.environ)==False or (AWS_ACCESS_SECRET in os.environ)==False:
        raise "undefined access_key"
    except:
      traceback.print_exception()
      return

    session = boto3.session.Session(
                aws_access_key_id=os.environ[AWS_ACCESS_KEY],
                aws_secret_access_key=os.environ[AWS_ACCESS_SECRET],
                region_name=AWS_REGION,
              )

    client = session.client('s3')

    shutil.rmtree(BUILD_DIR, ignore_errors=True)
    os.makedirs(BUILD_DIR, exist_ok=True)

    keys = lambda_project_list.keys()

    for keyname in keys:
      val = lambda_project_list[keyname]
      shutil.make_archive(BUILD_DIR+"/"+val["lambda"], 'zip', root_dir="./"+keyname)

    file_list = glob.glob(BUILD_DIR+"/*.zip")
    
    now = datetime.today()
    expires = now+timedelta(hours=1)

    print("DEPLOY:"+AWS_REGION)

    for val in file_list:
      mimetype = mimetypes.guess_type(val)[0]
      fileneme = os.path.basename(val)
      with open(val,"rb") as f:
        try:
          response = client.put_object(
            ACL='private',
            Body=f,
            Key=fileneme,
            Bucket=AWS_S3_BUCKET,
            ContentType=mimetype,
            Expires=expires,
          )
          print("UPLOAD:"+fileneme)
        except:
          traceback.print_exception()
          break


if __name__ == "__main__":
  run()

ビルドははしょり(懺悔)subprocess使えばいいんじゃなかろうか(適当)

デプロイ実行用のLambda関数

IAMはよしなに付与しましょう


import sys
import boto3
import os

AWS_REGION = "YOUR_AWS_REGION"

def lambda_handler(event, context):

    # s3に上がったzipを取得
    # lambdaへデプロイ
    if len(event["Records"])==0:
      return

    s3_data = event["Records"][0]["s3"]

    _,ext = os.path.splitext(s3_data["object"]["key"])

    # zip以外にアップロードされたものは除外
    if ext != ".zip":
      return

    function_name = s3_data["object"]["key"].split(".")[0]
 
    session = boto3.session.Session(
                region_name=AWS_REGION,
              )

    client = session.client("lambda")

    response = client.update_function_code(
      FunctionName=function_name,
      S3Bucket=s3_data["bucket"]["name"],
      S3Key=s3_data["object"]["key"],
      DryRun=False,
    )

    print(response,file=sys.stderr)

DryRun=False は必須。
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/lambda.html#Lambda.Client.update_function_code

DryRun (boolean) -- Set to true to validate the request parameters and access permissions without modifying the function code.

zip放置用のS3

  • よしなに作成。
  • リージョンは デプロイ実行用のLambda関数 と合わせた方が楽。
  • バケットの プロパティ > Events から PUTで デプロイ実行用のLambda関数 が起動するように設定

デプロイされるLambda関数

  • よしなに指定。
  • リージョンは合わせる
  • LAMBDA_PROJECT_LIST_JSON に放り込んでいく

課題

  • 雑に作ったのでビルドやってないので後日作る(といいなあ)

参考

https://dev.classmethod.jp/cloud/aws/2018-solo-boto3-advent-calendar-day14/
https://qiita.com/asahi0301/items/a88760dd38fe0f5fcee1

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?