https://github.com/vertx-howtos/aws-native-image-lambda-howto
Deploying a Vert.x Native Image function with AWS Lambda
https://github.com/vertx-howtos/aws-native-image-lambda-howto
aws-lambda graal-native vertx
Last synced: 11 months ago
JSON representation
Deploying a Vert.x Native Image function with AWS Lambda
- Host: GitHub
- URL: https://github.com/vertx-howtos/aws-native-image-lambda-howto
- Owner: vertx-howtos
- License: apache-2.0
- Created: 2019-03-06T09:16:37.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2021-06-14T19:44:39.000Z (almost 5 years ago)
- Last Synced: 2025-03-31T01:23:13.808Z (12 months ago)
- Topics: aws-lambda, graal-native, vertx
- Language: Java
- Homepage: https://vertx-howtos.github.io/aws-native-image-lambda-howto/
- Size: 580 KB
- Stars: 6
- Watchers: 3
- Forks: 2
- Open Issues: 2
-
Metadata Files:
- Readme: README.adoc
- License: LICENSE
Awesome Lists containing this project
README
= Deploying a Vert.x Native function with AWS Lambda
:author: Paulo Lopes
:page-permalink: /
:page-github: vertx-howtos/aws-native-image-lambda-howto
This how-to shows you how to deploy a Vert.x-based native image _function_ served by https://aws.amazon.com/lambda/[AWS Lambda].
== What you will build
- You will write a function that accepts returns a Quote Of The Day (similar to the UNIX tool).
- This function will be written in Java.
- The code will be compiled to native with the help of http://www.graalvm.org/[GraalVM].
- A function will be created with https://aws.amazon.com/cli/[AWS Command Line Interface].
- This function will be deployed with https://aws.amazon.com/lambda/[AWS Lambda].
== What you need
- A text editor or IDE
- GraalVM (>= 1.0.0-rc13)
- Maven
- AWS CLI tools
- A AWS account to deploy your function.
== What is a AWS Lambda function and why is Vert.x a good match?
AWS Lambda is a service which takes care of computing your code without any knowledge on the server environment. It is said to be serverless compute. The code is executed based on the response of events in AWS services like adding /removing files in S3 bucket, updating Amazon DynamoDB tables, HTTP request from Amazon Api gateway etc.
AWS Lambda code can be written in Java using the Amazon SDK. However due to the nature of the JVM and typical Java frameworks startup time can become a huge bottleneck to the performance of the function. To workaround this usually Java functions would be run on a Java server container, waiting for requests (defeating the whole serverless aspect).
Enter Vert.x and GraalVM. Vert.x is ideal for writing functions on GraalVM native-images, because:
1. Vert.x applications start very fast since there is no magic happening at run time,
2. GraalVM is used compilation to further reduce the startup and memory footprint,
3. Vert.x applications are resource-efficient and remain responsive even under heavy load,
4. Vert.x offers a large ecosystem of reactive clients to other middlewares (databases, messaging, etc),
5. a single functional interface implementation suffices to bootstrap a Vert.x application!
== Create a project
Start by cloning the following github project: https://github.com/pmlopes/aws-lambda-native-vertx
After that let's walk over the important parts of the project. Here is the content of the `pom.xml` file that you should be using:
[source,xml,role="collapsed"]
----
include::aws-lambda-vertx-runtime/pom.xml[]
----
<1> We need `svm-driver` to handle code incompatibilities with substrateVM.
<2> We need `vertx-webclient` to interact with the lambda environment.
<3> GraalVM configuration to produce an image.
== Writing the function
The function receives the incoming HTTP headers and the HTTP body.
A random QOTD is selected.
For each request, the random quote is sent:
[source,java]
----
include::aws-lambda-vertx-runtime/src/main/java/lambda/QOTDLambda.java[]
----
<1> We declare a array of quotes.
<2> Implement the `Lambda` interface which returns a `Future` to allow asynchronous processing.
<3> The implementation receives the current `Vertx` instance and the request headers and body.
<4> For each request we return a resolved future with a random quote.
== Testing the function
[source,java]
----
include::aws-lambda-vertx-runtime/src/test/java/lambda/QOTDLambdaTest.java[]
----
<1> Call the function with empty headers and body.
<2> Fail the test if the call fails.
<3> Verify that there's a quote.
<4> Terminate the test.
We can easily test that the function works:
. from your IDE, run the `junit` test, or
. with Maven: `mvn test`.
== Preparing your AWS dev environment
=== Create a Lambda role
Bofore being able to deploy to AWS you need to have a role capable of accessing the service. In order to do this create a temp json file (`/tmp/trust-policy.json`) with:
[source,json]
----
include::trust-policy.json[]
----
And deploy it with:
----
$ aws iam create-role \
--role-name lambda-role \
--path "/service-role/" \
--assume-role-policy-document file:///tmp/trust-policy.json
----
== Building your function
Building the function is running the usual maven command:
----
$ mvn clean package
$ zip -r function.zip bootstrap target/lambda
----
The final zip is the base layer used by the functions.
== Deploying the runtime layer
This layer will be installed on top of the Amazon Linux in the `/opt` directory.
----
$ aws lambda publish-layer-version \
--layer-name vertx-native-example \
--zip-file fileb://function.zip
----
This will install the lambda entrypoint `/opt/bootstrap` and the native image ELF containing all the functions.
== Deploying the function
You will need to provide a function zip file, in our case this is not useful as all code lives in the base layer so we can upload "again" the same zip or upload an empty file.
----
$ aws lambda create-function --function-name vertxNativeTester \
--zip-file fileb://function.zip --handler lambda.EchoLambda --runtime provided \
--role arn:aws:iam:::role/service-role/lambda-role
----
This could be useful if your function requires file resources. In this case you could package the resources for each function on a separate zip file.
Since the deployment was done with a custom runtime we need to link the 2:
----
$ aws lambda update-function-configuration --function-name vertxNativeTester \
--layers arn:aws:lambda:eu-central-1::layer:vertx-native-example:1
----
== Testing the function
Congratulations you just published your first native function. In order to quickly test it use the toolkit:
----
$ aws lambda invoke --function-name vertxNativeTester \
--payload '{"message":"Hello World"}' \
--log-type Tail response.txt | grep "LogResult" | awk -F'"' '{print $4}' | base64 --decode
----
== Summary
- We wrote a native function with Vert.x that returns a QOTD.
- We built a AWS lambda package.
- We deployed this function with AWS CLI.
== See also
- https://vertx.io/docs/vertx-web-client/java/[Vert.x web-client APIs]