Quarkus - Amazon Lambda with RESTEasy, Undertow, or Vert.x Web

    You can deploy your Lambda as a pure Java jar, or you can compile your project to a native image and deploy that for a smaller memory footprint and startup time.

    To complete this guide, you need:

    Getting Started

    This guide walks you through generating an example Java project via a maven archetype. Later on it walks through the structure of the project so you can adapt any existing projects you have to use Amazon Lambda.

    Installing AWS bits

    Installing all the AWS bits is probably the most difficult thing about this guide. Make sure that you follow all the steps for installing AWS SAM CLI.

    Create the Quarkus AWS Lambda maven project using our Maven Archetype.

    Build and Deploy

    Build the project using maven.

    1. ./mvnw clean install

    If you want to build for native too, make sure you have GraalVM installed correctly and just add a native property to the build

    1. ./mvnw clean install -Dnative
    1. ./mvnw clean install -Dnative -Dnative-image.docker-build=true

    Extra Build Generated Files

    After you run the build, there are a few extra files generated by the quarkus-amazon-lambda extension. These files are in the the build directory: target/ for maven, build/ for gradle.

    • function.zip - lambda deployment file

    • sam.jvm.yaml - sam cli deployment script

    • sam.native.yaml - sam cli deployment script for native

    The AWS SAM CLI allows you to run your lambda’s locally on your laptop in a simulated Lambda environment. This requires docker to be installed (see their install docs). After you have built your maven project, execute this command

    1. sam local start-api --template target/sam.jvm.yaml

    This will start a docker container that mimics Amazon’s Lambda’s deployment environment. Once the environment is started you can invoke the example lambda in your browser by going to

    In the console you’ll see startup messages from the lambda. This particular deployment starts a JVM and loads your lambda as pure Java.

    If you want to deploy a native executable of your lambda, use a different yaml template that is provided in your generated project:

    Deploy to AWS

    There are a few steps to get your lambda running on AWS.

    1. sam package --template-file target/sam.jvm.yaml --output-template-file packaged.yaml --s3-bucket <YOUR_S3_BUCKET>

    Type the simple name of your S3 bucket you created during. If you’ve built a native executable, replace sam.jvm.yaml with sam.native.yaml.

    1. sam deploy --template-file packaged.yaml --capabilities CAPABILITY_IAM --stack-name <YOUR_STACK_NAME>

    The stack name can be anything you want.

    If sam deploy, run the describe-stack-events command to get information about your deployment and what happened.

    1. aws cloudformation describe-stack-events --stack-name <YOUR_STACK_NAME>
    1. The authorization header is malformed; the region 'us-east-1' is wrong; expecting 'us-east-2'
    2. (Service: AWSLambdaInternal; Status Code: 400; Error Code: InvalidParameterValueException;
    3. Request ID: aefcf978-ad2a-4b53-9ffe-cea3fcd0f868)

    The above error is stating that my S3 bucket should be in us-east-2, not us-east-1. To fix this error you’ll need to create an S3 bucket in that region and redo steps 1 and 2 from above.

    Another annoying this is that if there is an error in deployment, you also have to completely delete it before trying to deploy again:

    Execute your REST Lambda on AWS

    To get the root URL for your service, type the following command and see the following output:

    1. aws cloudformation describe-stacks --stack-name <YOUR_STACK_NAME>

    It should give you something like the following output:

    1. {
    2. "Stacks": [
    3. {
    4. "StackId": "arn:aws:cloudformation:us-east-1:502833056128:stack/QuarkusNativeRestExample2/b35b0200-f685-11e9-aaa0-0e8cd4caae34",
    5. "StackDriftStatus": "NOT_CHECKED"
    6. },
    7. "Description": "AWS Serverless Quarkus HTTP - io.demo::rest-example",
    8. "Tags": [],
    9. "Outputs": [
    10. {
    11. "Description": "URL for application",
    12. "ExportName": "RestExampleNativeApi",
    13. "OutputKey": "RestExampleNativeApi",
    14. "OutputValue": "https://234234234.execute-api.us-east-1.amazonaws.com/Prod/"
    15. ],

    The OutputValue attribute is the root URL for your lambda. Copy it to your browser and add hello at the end.

    There is nothing special about the POM other than the inclusion of the quarkus-amazon-lambda-http extension as a dependencies. The extension automatically generates everything you might need for your lambda deployment.

    Also, at least in the generated maven archetype pom.xml, the quarkus-resteasy, quarkus-vertx-web, and quarkus-underdow dependencies are all optional. Pick which http framework(s) you want to use (JAX-RS, Vertx Web, and/or Servlet) and remove the other dependencies to shrink your deployment.

    The sam.yaml syntax is beyond the scope of this document. There’s a couple of things to note though that are particular to the quarkus-amazon-lambda-http extension.

    Amazon’s API Gateway assumes that HTTP response bodies are text unless you explicitly tell it which media types are binary through configuration. To make things easier, the Quarkus extension forces a binary (base 64) encoding of all HTTP response messages and the sam.yaml file must configure the API Gateway to assume all media types are binary:

    1. Globals:
    2. Api:
    3. EndpointConfiguration: REGIONAL
    4. BinaryMediaTypes:
    5. - "*/*"

    Another thing to note is that for pure Java lambda deployments, do not change the Lambda handler name.

    1. Properties:
    2. Handler: io.quarkus.amazon.lambda.runtime.QuarkusStreamHandler::handleRequest

    This particular handler handles all the intricacies of integrating with the Quarkus runtime. So you must use that handler.

    Finally, there’s an environment variable that must be set for native GraalVM deployments. If you look at sam.native.yaml you’ll see this:

    This environment variable resolves some incompatibilities between Quarkus and the Amazon Lambda Custom Runtime environment.

    Tracing with AWS XRay and GraalVM

    If you are building native images, and want to use with your lambda you will need to include as a dependency in your pom. The AWS X-Ray library is not fully compatible with GraalVM so we had to do some integration work to make this work.