Java の AWS Lambda デプロイパッケージ - AWS Lambda

Java の AWS Lambda デプロイパッケージ

デプロイパッケージは、コンパイル済み関数のコードと依存関係を含む ZIP アーカイブです。パッケージを Lambda に直接アップロードするか、Amazon S3 バケットを使用して Lambda にアップロードすることができます。デプロイパッケージが 50 MB 以上の場合は、Amazon S3 を使用する必要があります。

AWS Lambda には、Java 関数用に以下のライブラリが用意されています。

  • com.amazonaws:aws-lambda-java-core (必須) – ランタイムがハンドラーに渡すハンドラーメソッドインターフェイスとコンテキストオブジェクトを定義します。独自の入力タイプを定義する場合、これが唯一必要なライブラリです。

  • com.amazonaws:aws-lambda-java-events – Lambda 関数を呼び出すサービスからのイベントの入力タイプ。

  • com.amazonaws:aws-lambda-java-log4j2 – 現在の呼び出しのリクエスト ID を関数ログに追加するために使用できる Log4j 2 のアペンダーライブラリ。

これらのライブラリは Maven Central Repository から入手できます。以下のようにそれらのライブラリをビルド定義に追加します。

Gradle
dependencies { implementation 'com.amazonaws:aws-lambda-java-core:1.2.1' implementation 'com.amazonaws:aws-lambda-java-events:2.2.9' runtimeOnly 'com.amazonaws:aws-lambda-java-log4j2:1.2.0' }
Maven
<dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-core</artifactId> <version>1.2.1</version> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-events</artifactId> <version>2.2.9</version> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-log4j2</artifactId> <version>1.2.0</version> </dependency> </dependencies>

デプロイパッケージを作成するには、関数コードと依存関係を 1 つの ZIP または Java Archive (JAR) ファイルにコンパイルします。Gradle の場合は、Zip ビルドタイプを使用します。Maven の場合、Maven Shade プラグインを使用します。

注記

デプロイパッケージのサイズを小さく保つため、関数の依存関係をレイヤーにパッケージ化します。レイヤーにより、依存関係を独立して管理し、複数の関数で使用できます。また、他のアカウントと共有できます。詳細については、「AWS Lambda レイヤー」を参照してください。

デプロイパッケージをアップロードするには、Lambda コンソール、Lambda API、または AWS SAM を使用します。

Lambda コンソールを使用してデプロイパッケージをアップロードするには

  1. Lambda コンソール (関数ページ) を開きます。

  2. 関数を選択します。

  3. [Function code (関数コード)] で、[Upload (アップロード)] を選択します。

  4. デプロイパッケージをアップロードする

  5. [保存] を選択します。

Gradle を使用したデプロイパッケージのビルド

Zip ビルドタイプを使用して、関数のコードと依存関係を含むデプロイパッケージを作成します。

例 build.gradle – ビルドタスク

task buildZip(type: Zip) { from compileJava from processResources into('lib') { from configurations.runtimeClasspath } }

このビルド設定により、build/distributions フォルダにデプロイパッケージが作成されます。compileJava タスクは、関数のクラスをコンパイルします。processResources タスクは、ライブラリをビルドのクラスパスから lib という名前のフォルダにコピーします。

例 build.gradle – 依存関係

dependencies { implementation platform('software.amazon.awssdk:bom:2.10.73') implementation 'software.amazon.awssdk:lambda' implementation 'com.amazonaws:aws-lambda-java-core:1.2.1' implementation 'com.amazonaws:aws-lambda-java-events:2.2.9' implementation 'com.google.code.gson:gson:2.8.6' implementation 'org.apache.logging.log4j:log4j-api:2.13.0' implementation 'org.apache.logging.log4j:log4j-core:2.13.0' runtimeOnly 'org.apache.logging.log4j:log4j-slf4j18-impl:2.13.0' runtimeOnly 'com.amazonaws:aws-lambda-java-log4j2:1.2.0' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.0' }

Lambda では、Unicode のアルファベット順で JAR ファイルをロードします。lib フォルダの複数の JAR ファイルに同じクラスが含まれている場合は、最初の JAR ファイルが使用されます。重複するクラスを識別するには、次のシェルスクリプトを使用します。

例 test-zip.sh

mkdir -p expanded unzip path/to/my/function.zip -d expanded find ./expanded/lib -name '*.jar' | xargs -n1 zipinfo -1 | grep '.*.class' | sort | uniq -c | sort

Maven を使用したデプロイパッケージのビルド

Maven でデプロイパッケージをビルドするには、Maven Shade プラグインを使用します。このプラグインは、コンパイルされた関数コードとそのすべての依存関係を含む JAR ファイルを作成します。

例 pom.xml – プラグイン設定

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.2</version> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> </plugin>

デプロイパッケージをビルドするには、mvn package コマンドを使用します。

[INFO] Scanning for projects... [INFO] -----------------------< com.example:java-maven >----------------------- [INFO] Building java-maven-function 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- ... [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ java-maven --- [INFO] Building jar: target/java-maven-1.0-SNAPSHOT.jar [INFO] [INFO] --- maven-shade-plugin:3.2.2:shade (default) @ java-maven --- [INFO] Including com.amazonaws:aws-lambda-java-core:jar:1.2.1 in the shaded jar. [INFO] Including com.amazonaws:aws-lambda-java-events:jar:2.2.9 in the shaded jar. [INFO] Including joda-time:joda-time:jar:2.6 in the shaded jar. [INFO] Including com.google.code.gson:gson:jar:2.8.6 in the shaded jar. [INFO] Replacing original artifact with shaded artifact. [INFO] Replacing target/java-maven-1.0-SNAPSHOT.jar with target/java-maven-1.0-SNAPSHOT-shaded.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 8.321 s [INFO] Finished at: 2020-03-03T09:07:19Z [INFO] ------------------------------------------------------------------------

このコマンドは、target フォルダ内に JAR ファイルを生成します。

アペンダーライブラリ (aws-lambda-java-log4j2) を使用する場合は、Maven Shade プラグインのトランスフォーマーも設定する必要があります。トランスフォーマーライブラリは、アペンダーライブラリと Log4j の両方のキャッシュファイルのバージョンを組み合わせます。

例 pom.xml – Log4j 2 アペンダーを使用したプラグイン設定

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.2</version> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="com.github.edwgiz.maven_shade_plugin.log4j2_cache_transformer.PluginsCacheFileTransformer"> </transformer> </transformers> </configuration> </execution> </executions> <dependencies> <dependency> <groupId>com.github.edwgiz</groupId> <artifactId>maven-shade-plugin.log4j2-cachefile-transformer</artifactId> <version>2.13.0</version> </dependency> </dependencies> </plugin>

Lambda API を使用したデプロイパッケージのアップロード

関数のコードを AWS CLI または AWS SDK で更新するには、UpdateFunctionCode API オペレーションを使用します。AWS CLI では、update-function-code コマンドを使用します。以下のコマンドは、現在のディレクトリに my-function.zip という名前のデプロイパッケージをアップロードします。

~/my-function$ aws lambda update-function-code --function-name my-function --zip-file fileb://my-function.zip { "FunctionName": "my-function", "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:my-function", "Runtime": "java8", "Role": "arn:aws:iam::123456789012:role/lambda-role", "Handler": "example.Handler", "CodeSha256": "Qf0hMc1I2di6YFMi9aXm3JtGTmcDbjniEuiYonYptAk=", "Version": "$LATEST", "TracingConfig": { "Mode": "Active" }, "RevisionId": "983ed1e3-ca8e-434b-8dc1-7d72ebadd83d", ... }

デプロイパッケージが 50 MB よりも大きい場合、直接アップロードすることはできません。そのパッケージを Amazon S3 バケットにアップロードし、Lambda から参照されるようにします。以下のコマンド例は、デプロイパッケージを my-bucket という名前のバケットにアップロードし、それに応じて関数のコードを更新します。

~/my-function$ aws s3 cp my-function.zip s3://my-bucket upload: my-function.zip to s3://my-bucket/my-function ~/my-function$ aws lambda update-function-code --function-name my-function \ --s3-bucket my-bucket --s3-key my-function.zip { "FunctionName": "my-function", "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:my-function", "Runtime": "java8", "Role": "arn:aws:iam::123456789012:role/lambda-role", "Handler": "example.Handler", "CodeSha256": "Qf0hMc1I2di6YFMi9aXm3JtGTmcDbjniEuiYonYptAk=", "Version": "$LATEST", "TracingConfig": { "Mode": "Active" }, "RevisionId": "983ed1e3-ca8e-434b-8dc1-7d72ebadd83d", ... }

この方法を使用して、最大 250 MB (解凍後サイズ) の関数パッケージをアップロードできます。

AWS SAM によるデプロイパッケージのアップロード

AWS サーバーレスアプリケーションモデル を使用して、関数コード、設定、依存関係のデプロイを自動化できます。AWS SAM は AWS CloudFormation の拡張であり、サーバーレスアプリケーションを定義するための構文が簡略化されています。以下のサンプルテンプレートは、Gradle 用の build/distributions ディレクトリにあるデプロイパッケージを使用する関数を定義します。

例 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/java-basic.zip Handler: example.Handler Runtime: java8 Description: Java function MemorySize: 512 Timeout: 10 # Function's execution role Policies: - AWSLambdaBasicExecutionRole - AWSLambdaReadOnlyAccess - AWSXrayWriteOnlyAccess - AWSLambdaVPCAccessExecutionRole Tracing: Active

関数を作成するには、package コマンドと deploy コマンドを使用します。これらのコマンドは AWS CLI に合わせてカスタマイズされています。他のコマンドをラップして、デプロイパッケージを Amazon S3 にアップロードし、オブジェクト URI でテンプレートを書き換え、関数のコードを更新します。

以下のサンプルスクリプトは、Gradle ビルドを実行し、作成されたデプロイパッケージをアップロードします。また、初回実行時に AWS CloudFormation スタックを作成します。そのスタックがすでに存在する場合は更新します。

例 deploy.sh

#!/bin/bash set -eo pipefail aws cloudformation package --template-file template.yml --s3-bucket MY_BUCKET --output-template-file out.yml aws cloudformation deploy --template-file out.yml --stack-name java-basic --capabilities CAPABILITY_NAMED_IAM

完全な使用例については、以下のサンプルアプリケーションを参照してください。

Java のサンプル Lambda アプリケーション

  • blank-java – Lambda の Java ライブラリ、ロギング、環境変数、レイヤー、AWS X-Ray トレース、単体テスト、および AWS SDK の使用を示す Java 関数。

  • java-basic – 単体テストと変数ログ記録設定を使用する、最小限の Java 関数。

  • java-events – Amazon API Gateway など、依存関係として AWS SDK を必要としないイベントタイプで、aws-lambda-java-events ライブラリを使用する最小限の Java 関数。

  • java-events-v1sdk – Amazon Simple Storage Service や Amazon DynamoDB、Amazon Kinesis など、依存関係として AWS SDK を必要とするイベントタイプで、aws-lambda-java-events ライブラリを使用する Java 関数。

  • s3-java – Amazon S3 からの通知イベントを処理し、Java Class Library (JCL) によりアップロード済みイメージファイルからサムネイルを作成する、Java 関数。