この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
Cloud9でJavaのLambdaを開発する際に、ちょっとLambdaを実行してみて動作確認をしたいことがよくありました。
しかし、動作確認のたびにLambdaを再デプロイするのは面倒くさいです。 そこで、 SAM(Serverless Application Model) を利用すれば、Lambdaのローカル実行が可能です。
今回、Cloud9上でLambda Layerに依存するJavaのLambdaをローカルで実行する機会があったので、その方法を紹介します。
前提
Cloud9でJavaのLambdaをデプロイする環境は、先日書いたブログと同様の環境がすでに構築されていることを前提にします。
また、SAMでDockerを利用する関係上、Dockerイメージをローカルにダウンロードするたディスク容量がそれなりに必要です。 デフォルトの8GBだと不足する可能性があります。
その場合、次のブログを参考にしてディスクサイズを拡張してください。
Layerを含むLambdaのローカル実行イメージ
SAMの sam local invoke
コマンドを利用することで、Lambdaをローカル実行できます。
Lambda Layerを含むLambdaも同じ様にローカル実行できますが、次の図のようにLayer部分だけはデプロイされているLambda Layerを参照してローカルホストにキャッシュします。 そのため、Lambdaのローカル実行したい場合、依存するLambda Layer部分は先にデプロイしておく必要があります。
SAMテンプレートの修正
Lambda Layerに依存するLambdaをローカル実行したい場合、SAMテンプレートのLayerの指定に !Ref
組込み関数は使うとうまくいきません。
ARNを直接指定する必要があります。
template.yml
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: An AWS Lambda application that calls the Lambda API.
Resources:
function:
Type: AWS::Serverless::Function
Properties:
CodeUri: build/distributions/blank-java.zip
Handler: example.Handler::handleRequest
Runtime: java11
Description: Java function
MemorySize: 512
Timeout: 10
# Function's execution role
Policies:
- AWSLambdaBasicExecutionRole
- AWSLambdaReadOnlyAccess
- AWSXrayWriteOnlyAccess
- AWSLambdaVPCAccessExecutionRole
Tracing: Active
Layers:
- !Ref libs
libs:
Type: AWS::Serverless::LayerVersion
Properties:
LayerName: blank-java-lib
Description: Dependencies for the blank-java sample app.
ContentUri: build/blank-java-lib.zip
CompatibleRuntimes:
- java11
デプロイされたLambda LayerのARNはマネジメントコンソール等で確認してください。
そしてSAMテンプレートのLambdaが依存するLayerをARNでの指定に変更します。
template.yml
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: An AWS Lambda application that calls the Lambda API.
Resources:
function:
Type: AWS::Serverless::Function
Properties:
CodeUri: build/distributions/blank-java.zip
Handler: example.Handler::handleRequest
Runtime: java11
Description: Java function
MemorySize: 512
Timeout: 10
# Function's execution role
Policies:
- AWSLambdaBasicExecutionRole
- AWSLambdaReadOnlyAccess
- AWSXrayWriteOnlyAccess
- AWSLambdaVPCAccessExecutionRole
Tracing: Active
Layers:
# - !Ref libs
- 'arn:aws:lambda:ap-northeast-1:123456789012:layer:blank-java-lib:8'
libs:
Type: AWS::Serverless::LayerVersion
Properties:
LayerName: blank-java-lib
Description: Dependencies for the blank-java sample app.
ContentUri: build/blank-java-lib.zip
CompatibleRuntimes:
- java11
Lambdaのローカル実行
SAMテンプレートでLayerをARNで指定すれば、 次のように sam local invoke
コマンドでLambdaのローカル実行ができます。
$ cd ~/environment/aws-lambda-developer-guide/sample-apps/blank-java
$ sam local invoke -e event.json
Lambda Layerパッケージは、デフォルトでは ~/.aws-sam/layers-pkg/
にキャッシュされます。
sam local invoke
実行後に確認すると、Layerパッケージが自動でダウンロードされキャッシュされていることがわかります。
$ ls ~/.aws-sam/layers-pkg/
blank-java-lib-8-14f4e6cb4d
終わりに
Cloud9でLambda Layerに依存するJavaのLambdaのローカル実行をやってみました。
Lambdaのプログラムを修正して、ちょっとテスト実行してみたいことがよくあると思いますが、そのたびに再デプロイするのはちょっと面倒くさいです。 SAMの機能を使ってローカルでサッと実行して動作が確認できると開発しやすいと思います。