diff --git a/spring-boot-modules/spring-boot-aws/README.md b/spring-boot-modules/spring-boot-aws/README.md
new file mode 100644
index 0000000000..7d843af9ea
--- /dev/null
+++ b/spring-boot-modules/spring-boot-aws/README.md
@@ -0,0 +1 @@
+### Relevant Articles:
diff --git a/spring-boot-modules/spring-boot-aws/pom.xml b/spring-boot-modules/spring-boot-aws/pom.xml
new file mode 100644
index 0000000000..bdb23f9fe2
--- /dev/null
+++ b/spring-boot-modules/spring-boot-aws/pom.xml
@@ -0,0 +1,77 @@
+
+
+ 4.0.0
+ com.baeldung
+ spring-boot-aws
+ 0.0.1-SNAPSHOT
+ spring-boot-data-3
+ spring-boot-boot
+
+
+ com.baeldung.spring-boot-modules
+ spring-boot-modules
+ 1.0.0-SNAPSHOT
+
+
+ 1.9.1
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ com.amazonaws.serverless
+ aws-serverless-java-container-springboot2
+ ${springboot2.aws.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.2.4
+
+ false
+
+
+
+ package
+
+ shade
+
+
+
+
+ org.apache.tomcat.embed:*
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 11
+ 11
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-aws/src/main/java/com/baeldung/aws/Application.java b/spring-boot-modules/spring-boot-aws/src/main/java/com/baeldung/aws/Application.java
new file mode 100644
index 0000000000..da3fe275b5
--- /dev/null
+++ b/spring-boot-modules/spring-boot-aws/src/main/java/com/baeldung/aws/Application.java
@@ -0,0 +1,12 @@
+package com.baeldung.aws;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+}
diff --git a/spring-boot-modules/spring-boot-aws/src/main/java/com/baeldung/aws/controller/ProfileController.java b/spring-boot-modules/spring-boot-aws/src/main/java/com/baeldung/aws/controller/ProfileController.java
new file mode 100644
index 0000000000..674c4827ba
--- /dev/null
+++ b/spring-boot-modules/spring-boot-aws/src/main/java/com/baeldung/aws/controller/ProfileController.java
@@ -0,0 +1,21 @@
+package com.baeldung.aws.controller;
+
+import java.util.List;
+
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.baeldung.aws.data.User;
+
+@RestController
+@RequestMapping("/api/v1/")
+public class ProfileController {
+
+ @GetMapping(value = "users", produces = MediaType.APPLICATION_JSON_VALUE)
+ public List getUser() {
+ return List.of(new User("John", "Doe", "john.doe@baeldung.com"), new User("John", "Doe", "john.doe-2@baeldung.com"));
+ }
+
+}
diff --git a/spring-boot-modules/spring-boot-aws/src/main/java/com/baeldung/aws/data/User.java b/spring-boot-modules/spring-boot-aws/src/main/java/com/baeldung/aws/data/User.java
new file mode 100644
index 0000000000..c5ebd1251f
--- /dev/null
+++ b/spring-boot-modules/spring-boot-aws/src/main/java/com/baeldung/aws/data/User.java
@@ -0,0 +1,38 @@
+package com.baeldung.aws.data;
+
+public class User {
+
+ private String name;
+ private String surname;
+ private String emailAddress;
+
+ public User(String name, String surname, String emailAddress) {
+ this.name = name;
+ this.surname = surname;
+ this.emailAddress = emailAddress;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getSurname() {
+ return surname;
+ }
+
+ public void setSurname(String surname) {
+ this.surname = surname;
+ }
+
+ public String getEmailAddress() {
+ return emailAddress;
+ }
+
+ public void setEmailAddress(String emailAddress) {
+ this.emailAddress = emailAddress;
+ }
+}
diff --git a/spring-boot-modules/spring-boot-aws/src/main/java/com/baeldung/aws/handler/AsynchronousLambdaHandler.java b/spring-boot-modules/spring-boot-aws/src/main/java/com/baeldung/aws/handler/AsynchronousLambdaHandler.java
new file mode 100644
index 0000000000..30ffd2b17f
--- /dev/null
+++ b/spring-boot-modules/spring-boot-aws/src/main/java/com/baeldung/aws/handler/AsynchronousLambdaHandler.java
@@ -0,0 +1,25 @@
+package com.baeldung.aws.handler;
+
+import com.amazonaws.serverless.exceptions.ContainerInitializationException;
+import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
+import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
+import com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler;
+import com.amazonaws.serverless.proxy.spring.SpringBootProxyHandlerBuilder;
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.RequestHandler;
+import com.baeldung.aws.Application;
+
+public class AsynchronousLambdaHandler implements RequestHandler {
+ private SpringBootLambdaContainerHandler handler;
+
+ public AsynchronousLambdaHandler() throws ContainerInitializationException {
+ handler = (SpringBootLambdaContainerHandler) new SpringBootProxyHandlerBuilder().springBootApplication(Application.class)
+ .asyncInit()
+ .buildAndInitialize();
+ }
+
+ @Override
+ public AwsProxyResponse handleRequest(AwsProxyRequest input, Context context) {
+ return handler.proxy(input, context);
+ }
+}
diff --git a/spring-boot-modules/spring-boot-aws/src/main/java/com/baeldung/aws/handler/HttpV2LambdaHandler.java b/spring-boot-modules/spring-boot-aws/src/main/java/com/baeldung/aws/handler/HttpV2LambdaHandler.java
new file mode 100644
index 0000000000..a6fbe29695
--- /dev/null
+++ b/spring-boot-modules/spring-boot-aws/src/main/java/com/baeldung/aws/handler/HttpV2LambdaHandler.java
@@ -0,0 +1,26 @@
+package com.baeldung.aws.handler;
+
+import com.amazonaws.serverless.exceptions.ContainerInitializationException;
+import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
+import com.amazonaws.serverless.proxy.model.HttpApiV2ProxyRequest;
+import com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler;
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.RequestHandler;
+import com.baeldung.aws.Application;
+
+public class HttpV2LambdaHandler implements RequestHandler {
+ private static SpringBootLambdaContainerHandler handler;
+
+ static {
+ try {
+ handler = SpringBootLambdaContainerHandler.getHttpApiV2ProxyHandler(Application.class);
+ } catch (ContainerInitializationException ex) {
+ throw new RuntimeException("Unable to load spring boot application", ex);
+ }
+ }
+
+ @Override
+ public AwsProxyResponse handleRequest(HttpApiV2ProxyRequest input, Context context) {
+ return handler.proxy(input, context);
+ }
+}
diff --git a/spring-boot-modules/spring-boot-aws/src/main/java/com/baeldung/aws/handler/LambdaHandler.java b/spring-boot-modules/spring-boot-aws/src/main/java/com/baeldung/aws/handler/LambdaHandler.java
new file mode 100644
index 0000000000..887cbd3a26
--- /dev/null
+++ b/spring-boot-modules/spring-boot-aws/src/main/java/com/baeldung/aws/handler/LambdaHandler.java
@@ -0,0 +1,26 @@
+package com.baeldung.aws.handler;
+
+import com.amazonaws.serverless.exceptions.ContainerInitializationException;
+import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
+import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
+import com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler;
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.RequestHandler;
+import com.baeldung.aws.Application;
+
+public class LambdaHandler implements RequestHandler {
+ private static SpringBootLambdaContainerHandler handler;
+
+ static {
+ try {
+ handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(Application.class);
+ } catch (ContainerInitializationException ex) {
+ throw new RuntimeException("Unable to load spring boot application", ex);
+ }
+ }
+
+ @Override
+ public AwsProxyResponse handleRequest(AwsProxyRequest input, Context context) {
+ return handler.proxy(input, context);
+ }
+}
diff --git a/spring-boot-modules/spring-boot-aws/src/main/resources/application.properties b/spring-boot-modules/spring-boot-aws/src/main/resources/application.properties
new file mode 100644
index 0000000000..b7e7157b35
--- /dev/null
+++ b/spring-boot-modules/spring-boot-aws/src/main/resources/application.properties
@@ -0,0 +1,3 @@
+spring.datasource.url=jdbc:mysql://localhost:3306/mydatabase
+spring.datasource.username=myusername
+spring.datasource.password=mypassword
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-aws/src/test/java/com/baeldung/ProfileIntegrationTest.java b/spring-boot-modules/spring-boot-aws/src/test/java/com/baeldung/ProfileIntegrationTest.java
new file mode 100644
index 0000000000..adab61e916
--- /dev/null
+++ b/spring-boot-modules/spring-boot-aws/src/test/java/com/baeldung/ProfileIntegrationTest.java
@@ -0,0 +1,36 @@
+package com.baeldung;
+
+import java.io.IOException;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+import com.amazonaws.serverless.proxy.internal.testutils.AwsProxyRequestBuilder;
+import com.amazonaws.serverless.proxy.internal.testutils.MockLambdaContext;
+import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
+import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
+import com.baeldung.aws.handler.LambdaHandler;
+
+@SpringBootApplication
+public class ProfileIntegrationTest {
+
+ MockLambdaContext lambdaContext = new MockLambdaContext();
+
+ @Test
+ void whenTheUsersPathIsInvokedViaLambda_thenShouldReturnAList() throws IOException {
+ LambdaHandler lambdaHandler = new LambdaHandler();
+ AwsProxyRequest req = new AwsProxyRequestBuilder("/api/v1/users", "GET").build();
+ AwsProxyResponse resp = lambdaHandler.handleRequest(req, lambdaContext);
+ Assertions.assertNotNull(resp.getBody());
+ Assertions.assertEquals(200, resp.getStatusCode());
+ }
+
+ @Test
+ void whenWrongPathPathIsInvokedViaLambda_thenShouldNotFound() throws IOException {
+ LambdaHandler lambdaHandler = new LambdaHandler();
+ AwsProxyRequest req = new AwsProxyRequestBuilder("/api/v1/users/plus-one-level", "GET").build();
+ AwsProxyResponse resp = lambdaHandler.handleRequest(req, lambdaContext);
+ Assertions.assertEquals(404, resp.getStatusCode());
+ }
+}
diff --git a/spring-boot-modules/spring-boot-aws/template.yaml b/spring-boot-modules/spring-boot-aws/template.yaml
new file mode 100644
index 0000000000..09880594c8
--- /dev/null
+++ b/spring-boot-modules/spring-boot-aws/template.yaml
@@ -0,0 +1,32 @@
+AWSTemplateFormatVersion: '2010-09-09'
+Transform: AWS::Serverless-2016-10-31
+
+Globals:
+ Function:
+ Timeout: 30
+
+Resources:
+ ProfileApiFunction:
+ Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
+ Properties:
+ CodeUri: .
+ Handler: com.baeldung.aws.handler.LambdaHandler::handleRequest
+ Runtime: java11
+ AutoPublishAlias: production
+ SnapStart:
+ ApplyOn: PublishedVersions
+ Architectures:
+ - x86_64
+ MemorySize: 2048
+ Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object
+ Variables:
+ JAVA_TOOL_OPTIONS: -XX:+TieredCompilation -XX:TieredStopAtLevel=1 # More info about tiered compilation https://aws.amazon.com/blogs/compute/optimizing-aws-lambda-function-performance-for-java/
+ Policies:
+ - AWSSecretsManagerGetSecretValuePolicy:
+ SecretArn: !Sub arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:${DatabaseSecretName}
+ Events:
+ HelloWorld:
+ Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
+ Properties:
+ Path: /{proxy+}
+ Method: ANY
\ No newline at end of file