CDK Docker Build
I imagine many developers use a Mac. If you use native-image to create a native binary, this binary won’t work on AWS Lambda (Amazon Linux 2). To solve this problem you can build the binary with a docker file, using Amazon Linux 2 (AL2) as the base.
I’ve built and published my own on dockerhub marksailes/al2graalvm.
The Dockerfile is available on GitHub marksailes/al2-graalvm, and I’d be very happy to receive pull requests. Docker isn’t something I’m particular deep with.
This image uses AL2 as the base and then adds GraalVM, native-image and maven.
The functionality within CDK is called BundlingOptions. CDK puts our code into /asset-input and
expects the output in /asset-output. We change directory to our products folder and run our
normal mvn clean install with our native-image profile.
Bundling options allows us to specify the image, which can be for a public repo like dockerhub.
We mount our local ~/.m2 folder to speed up builds.
List<String> functionOnePackagingInstructions = Arrays.asList(
        "-c",
        "cd products " +
                "&& mvn clean install -P native-image "
               + "&& cp /asset-input/products/target/function.zip /asset-output/"
);
BundlingOptions.Builder builderOptions = BundlingOptions.builder()
        .command(functionOnePackagingInstructions)
        .image(DockerImage.fromRegistry("marksailes/al2-graalvm"))
        .volumes(singletonList(
                DockerVolume.builder()
                        .hostPath(System.getProperty("user.home") + "/.m2/")
                        .containerPath("/root/.m2/")
                        .build()
        ))
        .user("root")
        .outputType(ARCHIVED);
Our function changes in a number of ways. We move from a JAVA_11 runtime to PROVIDED_AL2.
The code come from the docker output, and we can reduce the memory size.
Function productFunction = new Function(this, "ProductFunction", FunctionProps.builder()
        .runtime(Runtime.PROVIDED_AL2)
        .code(Code.fromAsset("../software/", AssetOptions.builder()
                .bundling(builderOptions.build())
                .build()))
        .handler("com.graalvmonlambda.product.ProductRequestHandler")
        .memorySize(256)
        .logRetention(RetentionDays.ONE_WEEK)
        .build());
Now when we do cdk deploy, CDK will run our maven project within our docker image
produce a zip file with the bootstrap and native binary, then push this all to AWS.
 GraalVM on Lambda
                GraalVM on Lambda