AWS LambdaのFunctionを開発するときのMakefile

自分用のメモ

lambda-uploaderみたいなものもありますが、LambdaだけならAWS CLIで十分簡単に操作出来るのでMakefileを用意してみました。

f:id:nwpct1:20161006204151g:plain

API Gatewayに関しては、AWS CLIでやろうとすると1つのリソースあたり3個ぐらいコマンドを叩く必要があったり、AWS CLIで操作できるものではない印象でした。 まだ管理画面触ってる方が楽だと思います。 自動化したいならAWS CLIではなく、CloudFormationやServerlessフレームワークみたいなもの(例: serverless(node), Zappa(python2))を使ったほうが良さそうです(こちらについては、今作ってるフレームワークがあるのでまた後日記事書きます)。

Help text

$ make
Description:
    Quickly deployment tool for AWS Lambda.

Requirements:
    - AWS CLI
    - jq

Commands:
    deploy               Deploy to AWS Lambda
    functions            Show the list of AWS Lambda functions
    help                 Show help text
    invoke               Run lambda function and show the result and the log.
    ls-bucket            Show the files in S3 Bucket
    roles                Show the list of IAM Roles
    undeploy             Remove deploy package from s3 and Delete lambda function
    update               Update Lambda function

Deploy

  1. deploy packageの作成
  2. deploy packageをs3にupload
  3. Lambda関数の登録

Invoke

  1. input.jsonの中身をeventとして、Lambdaを呼び出す
  2. base64 encodeでログが送られてくるので、jqでパースして、base64 decode。
  3. 実行結果とログを保存して、表示

Makefile

Makefileは、ちゃんと書いたことがなかったので変な書き方してるかも。 何か変なところあれば教えてください。

.PHONY: help roles functions ls-bucket upload invoke undeploy deploy update

LAMBDA_NAME    := image-upload
LAMBDA_HANDLER := lambda_image_upload.lambda_handler
DESCRIPTION    := "Upload image posted by multipart/form-data."
TIME_OUT       := 16

INPUT_PYFILE   := lambda_image_upload.py
ZIP_FILE_NAME  := lambda_image_upload.zip
INPUT_JSON     := input.json
OUTPUT_FILE    := result.json
LOG_FILE       := invoke.log

S3_BUCKET      := lambda-packages
S3_KEY         := lambda_image_upload.zip
IAM_ROLE_ARN   := xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
REGION         := ap-northeast-1

.DEFAULT_GOAL := help
help: ## Show help text
    @echo "Description:"
    @echo "    Quickly deployment tool for AWS Lambda."
    @echo ""
    @echo "Requirements:"
    @echo "    - AWS CLI"
    @echo "    - jq"
    @echo ""
    @echo "Commands:"
    @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "    \033[36m%-20s\033[0m %s\n", $$1, $$2}'

roles: ## Show the list of IAM Roles
    aws iam list-roles | jq '.Roles | .[] | .RoleName, .Arn'

functions: ## Show the list of AWS Lambda functions
    aws lambda list-functions | jq '.Functions | .[] | .FunctionName'

ls-bucket: ## Show the files in S3 Bucket
    aws s3 ls s3://$(S3_BUCKET)

$(ZIP_FILE_NAME): $(INPUT_PYFILE) ## Create deploy package
    zip -r $(ZIP_FILE_NAME) $(INPUT_PYFILE)

upload: # Upload deploy package to S3
    make $(ZIP_FILE_NAME)
    aws s3 cp $(ZIP_FILE_NAME) s3://$(S3_BUCKET)/

# See http://docs.aws.amazon.com/lambda/latest/dg/with-userapp-walkthrough-custom-events-invoke.html
invoke: ## Run lambda function and show the result and the log.
    @aws lambda invoke \
        --payload file://$(INPUT_JSON) \
        --function-name $(LAMBDA_NAME) \
        --log-type Tail \
        $(OUTPUT_FILE) \
        | jq -r '.LogResult' \
        | base64 --decode \
        > $(LOG_FILE)

    @echo "-- Result\n"
    @cat $(OUTPUT_FILE)
    @echo "\n\n-- Log\n"
    @cat $(LOG_FILE)
    @echo ""

undeploy: ## Remove deploy package from s3 and Delete lambda function
    aws s3 rm s3://$(S3_BUCKET)/$(S3_KEY)
    aws lambda delete-function --function-name $(LAMBDA_NAME)

# See https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/with-on-demand-https-example-upload-deployment-pkg.html
deploy: ## Deploy to AWS Lambda
    make upload
    aws lambda create-function \
        --function-name $(LAMBDA_NAME) \
        --region $(REGION) \
        --code S3Bucket=$(S3_BUCKET),S3Key=$(S3_KEY) \
        --handler $(LAMBDA_HANDLER) \
        --timeout $(TIME_OUT) \
        --description $(DESCRIPTION) \
        --runtime python2.7 \
        --role $(IAM_ROLE_ARN)

update: ## Update Lambda function
    make upload
    aws lambda update-function-code \
        --function-name $(LAMBDA_NAME) \
        --s3-bucket $(S3_BUCKET) \
        --s3-key $(S3_KEY)

参考資料

AWS Lambda実践ガイド

AWS Lambda実践ガイド