The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.

AWS Lambda

quarkus-amazon-lambda エクステンションを使うと、Quarkusを使ってAWS Lambda を構築することができます。Lambda では、CDIやSpringからのインジェクションアノテーションや、必要に応じてQuarkusの他の機能を使用することができます。

Quarkusの Lambda は、Amazon Javaランタイムを使用してデプロイすることもできますが、より小さなメモリーフットプリントとより高速なコールドブート起動時間が必要な場合は、ネイティブ実行可能ファイルをビルドしてAmazonのカスタムランタイムを使用することもできます。

Quarkus と Lambda の統合は、Quarkus のライブコーディング開発サイクルもサポートします。Quarkus Lambda プロジェクトを開発モードまたはテストモードで起動し、プロジェクトのコードをライブで作成します。

前提条件

このガイドを完成させるには、以下が必要です:

  • ざっと 30 minutes

  • IDE

  • JDK 17+がインストールされ、 JAVA_HOME が適切に設定されていること

  • Apache Maven 3.9.6

  • 使用したい場合は、 Quarkus CLI

  • ネイティブ実行可能ファイルをビルドしたい場合、MandrelまたはGraalVM(あるいはネイティブなコンテナビルドを使用する場合はDocker)をインストールし、 適切に設定していること

  • An Amazon AWS account

  • AWS CLI

  • AWS SAM CLI 、ローカルテスト用

Gradle プロジェクトの場合は こちらを参照。詳細については、Gradle セットアップページ のガイドを参照してください。

はじめに

このガイドでは、mavenのArchetypeを使用してJavaプロジェクトのサンプルを生成し、AWSにデプロイする方法を説明します。

AWS ビットのインストール

AWSのすべてのツールをインストールすることは、おそらくこのガイドでは最も難しいことです。AWS CLIをインストールするためのすべての手順に従っていることを確認してください。

デプロイ用のMavenプロジェクトを作成する

Maven Archetypeを使用してQuarkus AWS Lambda mavenプロジェクトを作成します。

mvn archetype:generate \
       -DarchetypeGroupId=io.quarkus \
       -DarchetypeArtifactId=quarkus-amazon-lambda-archetype \
       -DarchetypeVersion=3.10.1

Gradleを使いたい場合は、 code.quarkus.io を使って、 quarkus-amazon-lambda エクステンションを依存関係として追加することで、素早く簡単にGradleプロジェクトを生成することができます。

このガイドと揃えるために、build.gradle、gradle.properties、settings.gradleを上記の生成されたMaven archetypeプロジェクトにコピーしてください。

Execute: gradle wrapper を実行して gradle wrapper を設定します (推奨)。

Gradleの詳細については、以下の Gradleビルドセクション を参照してください。

使用する Lambda の選択

quarkus-amazon-lambda エクステンションは、Amazon RequestHandler<?, ?> または RequestStreamHandler インターフェースを直接実装しているクラスがないか、プロジェクトをスキャンします。このインターフェイスを実装しているクラスがプロジェクト内で見つからなければ、ビルド時の失敗がスローされます。複数のハンドラクラスが見つかった場合も、ビルド時の例外がスローされます。

しかし、時にはコードを共有するいくつかの関連する Lambda があって、複数の maven モジュールを作成することは、やりたくないオーバーヘッドに過ぎないことがあるかもしれません。 quarkus-amazon-lambda エクステンションを使用すると、1 つのプロジェクトに複数のラムダをバンドルし、設定または環境変数を使用してデプロイしたいハンドラーを選択することができます。

生成されたプロジェクトは、その中に3つの Lambda を持っています。 RequestHandler<?, ?> インターフェイスを実装したものが 2 つ、 RequestStreamHandler インターフェイスを実装したものが 1 つ。1つは使用され、2つは未使用です。 src/main/resources/application.properties を開くと、このようになります。

quarkus.lambda.handler=test

quarkus.lambda.handler プロパティーは、デプロイする Lambda ハンドラーをQuarkusに伝えます。これは環境変数でオーバーライドすることもできます。

プロジェクト内で生成された3つのハンドラークラスを見てみると、異なる @Named が指定されていることがわかります。

@Named("test")
public class TestLambda implements RequestHandler<InputObject, OutputObject> {
}

@Named("unused")
public class UnusedLambda implements RequestHandler<InputObject, OutputObject> {
}

@Named("stream")
public class StreamLambda implements RequestStreamHandler {
}

ハンドラークラスのCDI名は、 quarkus.lambda.handler プロパティー内で指定された値と一致しなければなりません。

AWS Lambda Java Runtime へのデプロイ

Lambda をAWS上で動作させるには、いくつかのステップがあります。生成されたmavenプロジェクトには、pure Java とネイティブデプロイメント用の Lambda を作成、更新、削除、呼び出しするための便利なスクリプトが含まれています。

ビルドとデプロイ

プロジェクトのビルド

コマンドラインインタフェース
quarkus build
Maven
./mvnw install
Gradle
./gradlew build

これでコードがコンパイルされ、パッケージ化されます。

実行ロールの作成

AWS CLIを使った Lambda のデプロイ方法については、 Getting Started Guide を参照してください。具体的には、 Execution Role を作成していることを確認してください。プロファイルやコンソールウィンドウで LAMBDA_ROLE_ARN 環境変数を定義する必要があります。また、ビルドで生成される manage.sh スクリプトを編集して、そこに直接ロール値を置くこともできます。

LAMBDA_ROLE_ARN="arn:aws:iam::1234567890:role/lambda-role"

ビルド時に追加生成されるファイル

ビルドを実行すると、 quarkus-amazon-lambda のエクステンションで生成されるいくつかの追加ファイルがあります。これらのファイルはビルドディレクトリーにあります: mavenなら target/ 、gradleなら build/

  • function.zip - Lambda デプロイファイル

  • manage.sh - aws Lambda CLI の呼び出しのラッパー

  • bootstrap-example.sh - ネイティブデプロイメント用のブートストラップスクリプトの例

  • sam.jvm.yaml - (オプション) SAM CLI やローカル・テスト用

  • sam.native.yaml - (オプション) SAM CLI やネイティブ・ローカル・テスト用(オプション)

関数を作成する

target/manage.sh スクリプトは、AWS Lambda Java ランタイムを使用して Lambda を管理するためのものです。このスクリプトは利便性のためだけに提供されています。Lambda の作成、削除、更新のためにどのようなawsコマンドが実行されるかを知りたい場合は、 manage.sh スクリプトの出力を確認してください。

manage.sh は、 create , delete , update , invoke の 4 つの操作をサポートしています。

AWS CLIがインストールされていること、AWSアクセスキーのためのaws configureを実行していること、 LAMBDA_ROLE_ARN 環境変数を設定していること(上記の通り)を確認するには、 manage.sh をパラメーターなしで実行してください。それに応じて利用方法のガイドが表示されます。
Gradleを使用している場合、 manage.sh のバイナリーへのパスを target から build に変更しなければなりません。

usage を参照したり、AWS の設定を検証するためには次のようにします。

sh target/manage.sh

次のコマンドを使って、 Function を create します。

sh target/manage.sh create

または、このシェルで既に LAMBDA_ROLE_ARN が定義されていない場合にはこうです。

LAMBDA_ROLE_ARN="arn:aws:iam::1234567890:role/lambda-role" sh target/manage.sh create
ハンドラースイッチを変更しないでください。これは、 io.quarkus.amazon.lambda.runtime.QuarkusStreamHandler::handleRequest にハードコードする必要があります。このハンドラは、Quarkusをブートストラップし、インジェクションを実行できるように実際のハンドラをラップします。

Function の作成に問題がある場合は、 delete で Function を削除してから create コマンドを再実行する必要があります。

sh target/manage.sh delete

コマンドはスタックすることもできます。

sh target/manage.sh delete create

Lambda の呼び出し

Function を呼び出すには invoke コマンドを使用します。

sh target/manage.sh invoke

サンプルの Lambda は、プロジェクトのルートディレクトリーにある json ファイルを指す --payload スイッチを介して渡された入力を受け取ります。

Lambda は、以下のようにSAM CLI によってローカルで呼び出すこともできます。

sam local invoke --template target/sam.jvm.yaml --event payload.json

ネイティブイメージのビルドで作業している場合は、テンプレート名をネイティブバージョンに置き換えてください。

sam local invoke --template target/sam.native.yaml --event payload.json

Lambda の更新

お好きなように Java コードを更新することができます。リビルドしたら、 update コマンドを実行することで、Lambda を再配備できます。

sh target/manage.sh update

AWS Lambda カスタム (ネイティブ) ランタイムへのデプロイ

ラムダのメモリフットプリントを小さくし、初期化時間を短縮したい場合は、Javaコードをネイティブ実行可能ファイルにコンパイルできます。 -Dnative ・スイッチでプロジェクトをリビルドしてください。

Linux ホストの場合は以下を実行します。

コマンドラインインタフェース
quarkus build --native
Maven
./mvnw install -Dnative
Gradle
./gradlew build -Dquarkus.native.enabled=true
Linux 以外のシステムでビルドしている場合は、Amazon Lambda が Linux バイナリーを必要とするため、Docker ビルドを使用するように Quarkus に指示するプロパティーも渡す必要があります。これを行うには、-Dquarkus.native.container-build=true プロパティーをビルドに渡します。ただし、これには Docker をローカルにインストールする必要があります。
コマンドラインインタフェース
quarkus build --native --no-tests -Dquarkus.native.container-build=true
# The --no-tests flag is required only on Windows and macOS.
Maven
./mvnw install -Dnative -DskipTests -Dquarkus.native.container-build=true
Gradle
./gradlew build -Dquarkus.native.enabled=true -Dquarkus.native.container-build=true

これらのコマンドのいずれかがコンパイルされ、ネイティブの実行イメージが作成されます。また、zip ファイル target/function.zip も生成されます。このzipファイルには、 bootstrap にリネームされたネイティブ実行イメージが含まれています。これはAWS Lambda Custom (Provided) Runtimeの要件です。

ここでの説明は上記と全く同じですが、1つ変更点があります: manage.sh スクリプトの最初のパラメーターとして native を追加する必要があります。

sh target/manage.sh native create

上記のように、コマンドはスタックすることができます。唯一の要件は、ネイティブイメージビルドで作業したい場合、最初のパラメーターとして native を指定することです。このスクリプトは、ネイティブイメージ Function のデプロイメントを管理するために必要な残りの詳細を処理します。

Lambda を作成、削除、更新するためにどのようなawsコマンドが実行されるかを知りたい場合は、 manage.sh スクリプトの出力を調べてください。

ネイティブ用のcreateコマンドについて注意すべき点は、 aws lambda create-function 呼び出しで特定の環境変数を設定しなければならないということです。

--environment 'Variables={DISABLE_SIGNAL_HANDLERS=true}'

POM と Gradle のビルドの検証

POM には quarkus-amazon-lambda-http エクステンションが依存関係として含まれている以外に特別なことは何もありません。このエクステンションは Lambda のデプロイに必要なものをすべて自動的に生成します。

このエクステンションの以前のバージョンでは、ネイティブなデプロイをするためには、pomやgradleで実行可能ファイルをZIP圧縮するように設定する必要がありましたが、現在はそのようなことはなくなりました。

Gradle ビルド

同様に、Gradle プロジェクトの場合も、quarkus-amazon-lambda 依存関係を追加する必要があります。エクステンションは、Lambda デプロイメントに必要なすべてのものを自動的に生成します。

Gradleの依存関係の例。

dependencies {
    implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
    implementation 'io.quarkus:quarkus-resteasy'
    implementation 'io.quarkus:quarkus-amazon-lambda'

    testImplementation 'io.quarkus:quarkus-junit5'
    testImplementation 'io.rest-assured:rest-assured'
}

ライブコーディングおよび単体/統合テスト

開発環境でAWS Lambda環境をできるだけ忠実にミラーリングするために、 Quarkus AWS Lambdaエクステンションは、Quarkus Dev and TestモードでAWS Lambdaイベントサーバーのモックを起動します。 このモックイベントサーバーは、真のAWS Lambda環境をシミュレートします。

Quarkus Dev モードで実行しているときに、http://localhost:8080 に HTTP POST を実行することで、イベントをフィードできます。模擬イベントサーバーがイベントを受信し、ラムダが呼び出されます。Lambda でライブコーディングを実行すると、変更が自動的に再コンパイルされ、次に行う呼び出しで利用できるようになります。次に例を示します。

コマンドラインインタフェース
quarkus dev
Maven
./mvnw quarkus:dev
Gradle
./gradlew --console=plain quarkusDev
$ curl -d "{\"name\":\"John\"}" -X POST http://localhost:8080

単体テストでは、必要な HTTP クライアントを使用して模擬イベントサーバーで呼び出すこともできます。これは、rest-assured を使用した例です。Quarkus は、ポート 8081 で別の Mock Event サーバーを起動します。Rest Assured のデフォルトポートは、Quarkus により自動的に 8081 に設定されるため、このエンドポイントで呼び出すことができます。

import org.junit.jupiter.api.Test;

import io.quarkus.test.junit.QuarkusTest;

import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.containsString;

@QuarkusTest
public class LambdaHandlerTest {

    @Test
    public void testSimpleLambdaSuccess() throws Exception {
        Person in = new Person();
        in.setName("Stu");
        given()
                .contentType("application/json")
                .accept("application/json")
                .body(in)
                .when()
                .post()
                .then()
                .statusCode(200)
                .body(containsString("Hello Stu"));
    }
}

モックイベントサーバは @QuarkusIntegrationTest のテストでも起動されるので、ネイティブバイナリでも動作します。このように、SAM CLI のローカルテストと同様の機能を、Docker のオーバーヘッドなしに提供します。

最後に、ポート 8080 またはポート 8081 がコンピューターで使用できない場合は、application.properties を使用して開発モードとテストモードのポートを変更できます。

quarkus.lambda.mock-event-server.dev-port=8082
quarkus.lambda.mock-event-server.test-port=8083

ポート値がゼロの場合、ポートはランダムに割り当てられます。

モック・イベント・サーバーをオフにする方法:

quarkus.lambda.mock-event-server.enabled=false

SAM CLI を使用したテスト

模擬イベントサーバーを使用しない場合は、SAM CLI を使用して Lambda をテストできます。

AWS SAM CLI を利用すると、Lambda をシミュレートした環境でラップトップ上のローカルで Lambda を実行することができます。これには docker のインストールが必要です。これは、利用することを選択した場合のオプションのアプローチです。それ以外の場合は、Quarkus JUnitの統合でほとんどのニーズを満たすことができるはずです。

JVMとネイティブ実行モードの両方に対応したスターターテンプレートが生成されています。

以下の SAM CLI コマンドを実行して、適切な SAM template を渡して Lambda Function をローカルでテストします。 event パラメーターには任意の JSON ファイルを指定します。この場合はサンプル payload.json を指定しています。

Gradle を使用している場合、YAML テンプレートのバイナリーへのパスを target から build に変更しなければなりません。
sam local invoke --template target/sam.jvm.yaml --event payload.json

ネイティブイメージは、 sam.native.yaml テンプレートを使ってローカルでテストすることもできます。

sam local invoke --template target/sam.native.yaml --event payload.json

function.zip の修正

ビルドによって生成された function.zip Lambda デプロイメントにいくつかの追加を加えなければならない場合があります。これを行うには、 src/main 内に zip.jvm または zip.native ディレクトリーを作成します。Pure Java Lambda を実行している場合は zip.jvm/ を、ネイティブディプロイメントを実行している場合は zip.native/ を作成します。

zipディレクトリーの下に作成したファイルやディレクトリーは、すべて function.zip に含まれます。

カスタム bootstrap スクリプト

ラムダがネイティブの quarkus ラムダデプロイメントを起動する際に、特定のシステムプロパティーやその他の引数を設定したい場合があるかもしれません。 zip.native 内に bootstrap スクリプトファイルを含めると、Quarkus エクステンションは自動的に実行ファイルの名前を function.zip 内の runner に変更し、 bootstrap スクリプトの unix モードを実行ファイルに設定します。

カスタム bootstrap スクリプトを含む場合は、ネイティブ実行可能ファイルを runner として参照する必要があります。

このエクステンションは、サンプルのスクリプト target/bootstrap-example.sh を生成します。

AWS XRay と GraalVM を使用したトレース

ネイティブイメージをビルドしていて、Lambda で AWS X-Ray Tracing を使いたい場合は、 quarkus-amazon-lambda-xray を依存関係として pom に含める必要があります。AWS X-Ray ライブラリは GraalVM との完全な互換性がないため、これを動作させるためにいくつかの統合作業をしなければなりませんでした。

さらに、 manage.shcmd_create() 関数で AWS X-Ray tracing パラメーターを有効にすることを忘れないでください。これはAWSマネジメントコンソールでも設定できます。

    --tracing-config Mode=Active

SAM テンプレートファイルの場合は、YAML の Function Properties に以下を追加します。

    Tracing: Active

AWS X-Ray はディストリビューションに多くのクラスを追加しますが、最低でも256MBのAWS Lambdaメモリーサイズを使用していることを確認してください。これは manage.sh cmd_create() で明示的に設定されています。ネイティブイメージは常により低いメモリー設定を使用できる可能性がありますが、特にパフォーマンスを比較するためには同じ設定にしておくことをお勧めします。

HTTPS または SSL/TLS の使用

コードが hHTTPS (マイクロサービスや AWS サービスなど) を呼び出す場合、GraalVM は明示的に宣言された場合にのみ依存関係を含むため、ネイティブイメージに設定を追加する必要があります。Quarkus は、デフォルトでは、この機能を暗黙的に必要とするエクステンションでこの機能を有効にします。詳細については、Quarkus SSLガイド を参照してください。

src/main/resources/application.properties を開き、以下の行を追加してネイティブイメージでSSLを有効にします。

quarkus.ssl.native=true

AWS Java SDK v2 の使用

QuarkusにはDynamoDB、S3、SNS、SQS (他にも追加中) のエクステンションが追加されました。以下のように手動でワイヤリングするのではなく、Quarkusを使って様々なAWSサービスを利用する方法については、 これらのガイド を確認してください。

最小限のインテグレーションで、AWSのJava SDK v2を活用し、SQS、SNS、S3、DynamoDBなどのサービスを呼び出すことが可能です。

ただし、ネイティブイメージの場合、(現時点では)GraalVMのコンパイルに問題があるため、同期モードを使用する場合は、Apache HTTP ClientよりもURL Connectionクライアントを優先する必要があります。

quarkus-jaxb を依存関係として Maven pom.xml または Gradle build.gradle ファイルに追加します。

また、SQS、SNS、S3 などの AWS サービスクライアントは、HTTPS で AWS サービスに接続する URL Connection クライアントを使用するように強制する必要があり、そのため、上記の HTTPS または SSL/TLS の使用 セクションで説明したように、SSL enabled プロパティーが含まれています。

// select the appropriate client, in this case SQS, and
// insert your region, instead of XXXX, which also improves startup time over the default client
  client = SqsClient.builder().region(Region.XXXX).httpClient(software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient.builder().build()).build();

Mavenの場合は、 pom.xml に以下を追加します。

    <properties>
        <aws.sdk2.version>2.10.69</aws.sdk2.version>
    </properties>

    <dependencyManagement>
        <dependencies>

            <dependency>
                <groupId>software.amazon.awssdk</groupId>
                <artifactId>bom</artifactId>
                <version>${aws.sdk2.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

        </dependencies>
    </dependencyManagement>
    <dependencies>

        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>url-connection-client</artifactId>
        </dependency>

        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>apache-client</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <!-- sqs/sns/s3 etc -->
            <artifactId>sqs</artifactId>
            <exclusions>
                <!-- exclude the apache-client and netty client -->
                <exclusion>
                    <groupId>software.amazon.awssdk</groupId>
                    <artifactId>apache-client</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>software.amazon.awssdk</groupId>
                    <artifactId>netty-nio-client</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.jboss.logging</groupId>
            <artifactId>commons-logging-jboss-logging</artifactId>
        </dependency>
    </dependencies>
もし、 java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty 、または同様のSSLエラーが表示された場合、GraalVMの現状のため、 function.zip 、以下のようにバンドルするための追加作業があります。詳しくは、Quarkus Native SSL ガイド をご覧ください。

クライアントSSLの追加要件

ネイティブ実行可能ファイルは、S3 や他の aws ライブラリーが必要とするクライアント SSL を有効にするために、いくつかの追加の手順が必要です。

  1. カスタム bootstrap スクリプト

  2. function.ziplibsunec.so を追加する必要があります。

  3. function.zipcacerts を追加する必要があります。

これを行うには、まず、ビルドでディレクトリー src/main/zip.native/ を作成します。次に src/main/zip.native/ 内に bootstrap という名前のシェルスクリプトファイルを作成します。サンプル bootstrap-example.sh がビルドフォルダー(ターゲットまたはビルド)内に自動的に作成されます。

#!/usr/bin/env bash

./runner -Djava.library.path=./ -Djavax.net.ssl.trustStore=./cacerts

cacerts ファイルがパスワードで保護されている場合は、追加で -Djavax.net.ssl.trustStorePassword=changeit を設定してください。

次に、GraalVM ディストリビューションから src/main/zip.native/ にいくつかのファイルをコピーする必要があります。

GraalVM のバージョンは、使用しているバージョンが Java 8 か 11 かによりファイルへのパスが異なるため、適宜調整してください。
cp $GRAALVM_HOME/lib/libsunec.so $PROJECT_DIR/src/main/zip.native/
cp $GRAALVM_HOME/lib/security/cacerts $PROJECT_DIR/src/main/zip.native/

ネイティブビルドを実行すると、これらのファイルはすべて function.zip に含まれます。

Dockerイメージを使ってビルドする場合は、このイメージからこれらのファイルを抽出する必要があります。

必要な SSL を抽出するには、バックグラウンドでDockerコンテナーを起動し、そのコンテナーにアタッチしてアーティファクトをコピーする必要があります。

まず、GraalVMコンテナーを起動して、コンテナーIDの出力に注目してみましょう。

docker run -it -d --entrypoint bash quay.io/quarkus/ubi-quarkus-mandrel-builder-image:jdk-21

# This will output a container id, like 6304eea6179522aff69acb38eca90bedfd4b970a5475aa37ccda3585bc2abdde
# Note this value as we will need it for the commands below

まず、SSLの実装に使用するC言語のライブラリである libsunec.so です。

docker cp {container-id-from-above}:/opt/graalvm/lib/libsunec.so src/main/zip.native/

2つ目は、cacerts (証明書ストア)です。また、定期的に更新されたコピーを取得する必要があるかもしれません。

docker cp {container-id-from-above}:/opt/graalvm/lib/security/cacerts src/main/zip.native/

最終的なアーカイブは以下のようになります。

jar tvf target/function.zip

    bootstrap
    runner
    cacerts
    libsunec.so

コンテナイメージを使用して AWS Lambda にデプロイする

AWS Lambda は、ZIP ファイルをアップロードするのではなく、 コンテナイメージ を参照してラムダを作成することをサポートしています。これは、アップロードされた ZIP ファイルのサイズ制限を回避できるなどの利点があります。ネイティブビルドと通常の JVM ビルドの両方でラムダ関数を定義できます。

JVM コンテナイメージ

通常の JVM ディストリビューションの場合は、公式の AWS Java ベースイメージに基づいてイメージを作成する必要があります。以下は、Quarkus Lambda プロジェクトからコンテナイメージを作成する Dockerfile の例です。mvn package が実行され、バイナリーが target/ ディレクトリーで利用可能であることを想定しています。

FROM  public.ecr.aws/lambda/java:11

ADD target/my-service-0.0.1-SNAPSHOT-runner.jar /var/task/lib/my-service.jar
ADD target/lib/  /var/task/lib/

CMD ["io.quarkus.amazon.lambda.runtime.QuarkusStreamHandler::handleRequest"]

ネイティブ実行可能コンテナイメージ

ネイティブ実行可能ファイルを使用するラムダコンテナイメージを作成するには、少し異なる方法を用いる必要があります。この場合、AWS の java:11 ベースイメージを使用する必要はなく、代わりにラムダの実行環境が提供されていることを前提とした特別なイメージを使うことになります。以下の例では、そのようなコンテナを作成しています。Maven のビルドが実行され (mvn package -Dnative=true など)、ネイティブバイナリーが target/ ディレクトリーに生成されたと仮定しています。バイナリーは bootstrap という名前で、/var/runtime/ に配置する必要があります。

FROM  public.ecr.aws/lambda/provided

ADD target/my-service-0.0.1-SNAPSHOT-runner /var/runtime/bootstrap
RUN chmod ugo+x /var/runtime/bootstrap

CMD ["io.quarkus.amazon.lambda.runtime.QuarkusStreamHandler::handleRequest"]

コンテナイメージ Lambda のデプロイ

以下に、docker および aws コマンドラインツールを使用して、上記で作成したコンテナイメージをビルドして AWS にデプロイする方法を示します。これらの手順は、ネイティブコンテナイメージと jvm コンテナイメージの両方で機能し、aws コマンドラインツールがログインしていることを前提としています。

Docker イメージのビルド

# Assuming we are located in the root directory of the project and created a Dockerfile there
docker build .
   [output omitted]
    => exporting to image                    0.0s
    => => exporting layers                   0.0s
    => => writing image sha256:[SOME SHA]    0.0s

ユーザーの AWS アカウントへの ECR リポジトリーの作成

aws ecr create-repository --repository-name my/test/quarkus-lambda

ECR の登録情報を使用したイメージへのタグ付け

docker tag [SOME SHA] [YOUR AWS ACCOUNT ID].dkr.ecr.[YOUR AWS ACCOUNT REGION].amazonaws.com/my/test/quarkus-lambda:v1

Docker を ECR レジストリーへの Docker のログインと Docker イメージのプッシュ

aws ecr get-login-password --region region | docker login --username AWS --password-stdin [YOUR AWS ACCOUNT ID].dkr.ecr.[YOUR AWS ACCOUNT REGION].amazonaws.com
docker push [YOUR AWS ACCOUNT ID].dkr.ecr.[YOUR AWS ACCOUNT REGION].amazonaws.com/my/test/quarkus-lambda:v1

AWS CLI ツールを使用した AWS ラムダ関数の作成

アップロードしておいたイメージを参照していることを確認してください (Lambda の実行に使用できるロールが存在することを前提としています)。JVM Lambda 関数の場合、デフォルトのメモリー制限である 128Mb が関数を実行するのに十分である可能性が高いことに注意してください。その場合は、aws lambda create-function コマンドに --memory-size 256 パラメーターを指定することで、関数を作成するときにメモリー制限を増やすことができます。関数を作成した後、AWS コンソールで関数を調整することもできます。

aws lambda create-function --function-name my-test-quarkus-lambda-function --package-type Image --code ImageUri=[YOUR AWS ACCOUNT ID].dkr.ecr.[YOUR AWS ACCOUNT REGION].amazonaws.com/my/test/quarkus-lambda:v1 --role arn:aws:iam::[YOUR AWS ACCOUNT ID]:role/[SOME ROLE]

これで、AWS コンソールを使用して、新しいラムダ関数を表示およびテストできます。

Amazon Alexa 統合

Quarkus ネイティブで Alexa を使用するには、 Quarkiverse Hub でホストされている Quarkus Amazon Alexa エクステンション を使用する必要があります。

<dependency>
    <groupId>io.quarkiverse.alexa</groupId>
    <artifactId>quarkus-amazon-alexa</artifactId>
    <version>${quarkus-amazon-alexa.version}</version> (1)
</dependency>
1 POM ファイルでエクステンションの最新バージョンを定義します。

通常通り、抽象クラス com.amazon.ask.SkillStreamHandler をサブクラス化して Alexa ハンドラーを作成し、リクエストハンドラーの実装を追加します。

それだけだよ!

SnapStart

アプリケーションをLambda SnapStartに最適化するには、 SnapStart構成ドキュメント を参照してください。

関連コンテンツ