Spring Boot Rest API deployed in AWS Lambda (Serverless) Git lab CI/CD

Spring Boot Rest API deployed in AWS Lambda (Serverless) Git lab CI/CD

Just to begin AWS Lambda is server less architecture, which allows you to run the code without managing the server and cost is pay per use, usually its based on number of invocation and execution time.

Usually  lambda  is preferred for small task or to have platform specific trigger. But when we need to maintain the entire application it becomes tedious, For example if we do it  via console, First we need to create the function and upload the code to S3, and set up the HTTP gateway trigger. so each time when you update the code it becomes very difficult and time consuming,  just imagine for 50 URLs of a project. so when we are starting with lambda Function or any server less design, it better to start with  Automated deployment  as bare minimum instead of   spending most of the time  in deploying or playing inside the Cloud console.

So when develop any hobby project, minimum CI & CD pipelines is mandatory for me. And I prefer GitLab as my CI tool. So this preference led  me to find easier ways to deploy the the java application in to AWS lambda. So found these tools Micronaut as web framework, server less Framework for managing deployment and GitLab for CI & CD.

I am an spring boot advocate, I use spring boot in most of my applications, so this example is from on of my  experiments so lets begin this  example

I have used few additional tools to make my life easier to manage my lambda function Those are

  1. Serverless framework is Open Source, lets you develop and deploy serverless applications to AWS, Azure, GCP & more. and it has very good documentation to understand  to begin with.
  2. GIT Lab CI/CD  As this is integrated with my repo provider so I did not to use another CI tool.
  3. And used this dependency in my pom

Step 1: Create the Dummy controller or two in Spring boot (Latest version this was working is 2.2.6.RELEASE)

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

public class HealthController {

    public HealthTO main() {
        return new HealthTO();


Step 2 : Lets us create Entry point which can handle the request from AWS lambda This is main Application Class.

public class EntryPoint  implements RequestStreamHandler {

    private static final SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler;

    static {
        try {
            handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(EntryPoint.class);
        } catch (ContainerInitializationException e) {
            // if we fail here. We re-throw the exception to force another cold start
            throw new RuntimeException("Could not initialize Spring Boot application", e);

    public static void main(String[] args) {
        SpringApplication.run(EntryPoint.class, args);

    public HandlerMapping handlerMapping() {
        return new RequestMappingHandlerMapping();

     * Create required HandlerAdapter, to avoid several default HandlerAdapter instances being created
    public HandlerAdapter handlerAdapter() {
        return new RequestMappingHandlerAdapter();

    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
        handler.proxyStream(inputStream, outputStream, context);

To optimise the cold start up time by manually using ComponentScan annotations for required components. and also using `@import` instead of `Autowired`

Step 3 Changing Build mechanism

Here i have attached the pom, instead of using spring boot maven plugin, we are using shade plugin to remove tomcat from the dependency

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
		<relativePath/> <!-- lookup parent from repository -->
	<description>Handels gooles auth</description>





And package the application as jar upload the jar in AWS lambda manually or use serverless to manage the lambda and create the API gateway.

Step 4: Setting up Serverless Framework

Installing  the serverless (on ubuntu)

sudo apt install nodejs
sudo apt install npm
sudo npm install -g serverless

Preparing serverless.yaml

This is yaml file  more  or like steps and rules for the deployment. create in the root of the project, or the place where ever the artifacts are accessible.

service: <project-name> # provide the project name
  name: aws
  runtime: java8

  artifact: <path of the jar file> # provide path of the jar file

    handler: <package-name>.EntryPoint
    - http:
        path: health/check
        method: GET # Http metodod [GET,POST,etc]
        cors: true # allows cors

Adding Aws Credentials to system environment  variable

export AWS_SECRET_ACCESS_KEY=<****************>

Make sure the AWs use has these permission policy IAMFullAccess, AmazonS3FullAccess, CloudWatchLogsFullAccess , AmazonAPIGatewayAdministrator, AWSCloudFormationFullAccess, AWSLambda_FullAccess.

CI & CD : I am using the the GitLab CI, instead u can use any CI tool. For build pipeline use `mvn clean package shade:shade` to generate the artifact. to deploy deploy u can use `serverless deploy --stage production --verbose`.

Git lab CI & CD example

image: node:latest

  - package
  - deploy

  stage: package
  image: maven:3-jdk-11
  script: "mvn package shade:shade"
      - target/<jarname>.jar
  stage: deploy
    - npm config set prefix /usr/local
    - npm install -g serverless
    - serverless deploy --stage production --verbose
  environment: production

Also :

AWS Lambda APIs using Micronaut along with basic CI & CD (Gitlab CI) steps.
This article is about writing AWS lambda function using the Micronaut Java framework and deploying it as an AWS lambda function with help of the GitLab CI.