Cloud9でJavaのLambdaをデプロイする環境を構築する

Cloud9でJavaのLambdaをデプロイする環境を構築したかったので、そのやり方を紹介します。
2020.10.21

Cloud9でJavaのLambdaをデプロイする環境を構築したかったので、そのやり方を紹介します。

基本的には、公式ドキュメントに記載されているLambdaのJavaのサンプルアプリケーションのやり方に沿って構築しています。

前提条件

次の内容は構築できていることを前提にします。

Gradleのインストール

JavaのビルドにGradleを利用します。 Amazon Linux2にはデフォルトではインストールされていないので、公式ドキュメントを参考に次のコマンドを実行してインストールします。

$ cd ~/environment
$ wget https://services.gradle.org/distributions/gradle-6.7-bin.zip
$ sudo mkdir /opt/gradle
$ sudo unzip -d /opt/gradle gradle-6.7-bin.zip

インストールができたらPATHを追加します。必要に応じてPATHの追加を .bashrc 等に追記してください。

$ export PATH=$PATH:/opt/gradle/gradle-6.7/bin
$ which gradle
/opt/gradle/gradle-6.7/bin/gradle

サンプルアプリのgit clone

AWSがLambdaのサンプルアプリをGitHubで公開しています。これをCloud9環境に持っていきます。

次のコマンドを実行して、サンプルアプリを git clone します。

$ git clone https://github.com/awsdocs/aws-lambda-developer-guide.git
$ cd aws-lambda-developer-guide/sample-apps/blank-java

Java Runtimeバージョンの修正

blank-java のサンプルアプリのJavaランタイムは Java 8 になっているので、より新しい Java 11 を利用するようにします。

具体的には、 aws-lambda-developer-guide/sample-apps/blank-java/template.yml を次のように修正します。

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

ビルドパッケージアップロード用S3 Bucketの作成

次にビルドパッケージアップロード用のS3 Bucketを作成しますが、その前にAWS CLI実行時のRegionを指定します。

次のように環境変数にRegionを設定するか。

$ export AWS_DEFAULT_REGION=ap-northeast-1

または次のようなコマンドを実行して、 ~/.aws/config ファイルで設定するようにしてください。

$ cat << 'EOS' > ~/.aws/config
[default]
region=ap-northeast-1
EOS

Regionの設定が終わったら、次のシェルスクリプトを実行することでS3 Bucketの作成ができます。

$ ./1-create-bucket.sh

依存ライブラリのコンパイル

このサンプルアプリでは、依存ライブラリをLambdaレイヤーに、作成したJavaプログラムをLambdaに分割してデプロイする構成をとっています。

まずは、次のシェルスクリプトを実行して依存ライブラリのコンパイルをします。

$ ./2-build-layer.sh

そうすると新しく build/blank-java-lib.zip というファイルが生成され、コンパイルできていることがわかります。

jar tf コマンドを実行すれば、どういったファイルが含まれているか中身を確認できます。

$ jar tf build/blank-java-lib.zip

Lambdaへのデプロイ

Javaプログラムのコンパイルのみ行いたい場合は、次のようにgradleコマンドだけ実行します。

$ gradle build -i

そうすると新しく build/distributions/blank-java.zip というファイルが生成され、コンパイルできていることがわかります。

次のシェルスクリプトを実行することで、JavaプログラムのコンパイルとLambdaへのデプロイを合わせて実行できます。

$ ./3-deploy.sh

LambdaのデプロイはCloudFormationを利用して行われるので、CloudFormationの画面を確認すればどのようなリソースが構築されているか確認できます。

Lambdaの実行

デプロイしたLambdaは次のシェルスクリプトを実行することでLambdaの実行ができます。

$ ./4-invoke.sh

実行後にCloudWatch LogsやX-Rayを見ると、実行履歴を確認できます。

AWSリソースの削除

デプロイしたAWSリソースは、不要になったら次のシェルスクリプトを実行することですべて削除できます。

$ ./5-cleanup.sh

終わりに

Cloud9でJavaのLambdaをデプロイする環境を構築してみました。

Javaのライブラリを利用したくて、LambdaのランタイムにJavaを選択するという状況もあるかと思います。

そんなときに、まず動く環境を作ってみる。ということが体験でき、このサンプルアプリが役に立つと思います。