Skip to content

Commit 9f05a1c

Browse files
authored
Merge pull request #5570 from evanchooly/lambda-sam
update amazon-lambda-archetype to provide SAM templates
2 parents 21bb451 + 57d3b2f commit 9f05a1c

File tree

14 files changed

+209
-167
lines changed

14 files changed

+209
-167
lines changed

docs/src/main/asciidoc/amazon-lambda.adoc

Lines changed: 72 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,10 @@ If you look at the two generated handler classes in the project, you'll see that
7474
----
7575
@Named("test")
7676
public class TestLambda implements RequestHandler<InputObject, OutputObject> {
77-
7877
}
7978
8079
@Named("unused")
8180
public class UnusedLambda implements RequestHandler<InputObject, OutputObject> {
82-
8381
}
8482
----
8583

@@ -88,7 +86,7 @@ The CDI name of the handler class must match the value specified within the `qua
8886

8987
== Deploy to AWS Lambda Java Runtime
9088

91-
There are a few steps to get your lambda running on AWS. The generated maven project contains some helpful scripts to
89+
There are a few steps to get your lambda running on AWS. The generated maven project contains a helpful script to
9290
create, update, delete, and invoke your lambdas for pure Java and native deployments.
9391

9492
== Build and Deploy
@@ -106,228 +104,144 @@ This will compile and package your code.
106104

107105
View the https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-awscli.html[Getting Started Guide] for deploying
108106
a lambda with AWS CLI. Specifically, make sure you have created an `Execution Role`. You will need to copy and
109-
paste the `Role Arn` into the scripts generated by the maven archetype.
107+
paste the `Role Arn` into the scripts generated by the maven archetype. To use the provided scripts, you will either
108+
need to define a `LAMBDA_ROLE_ARN` environment variable in your profile or define it prior to executing the scripts like
109+
this:
110110

111-
== Edit Script Files
112-
113-
Edit the `create.sh` and `create-native.sh` scripts included with the generated project. After the `--role` switch
114-
replace the dummy `Role Arn` with the Arn of the `Execution Role` you created in the Amazon IAM console.
111+
[source]
112+
----
113+
LAMBDA_ROLE_ARN="arn:aws:iam::1234567890:role/lambda-role"
114+
----
115115

116116
== Create the function
117117

118-
The `create.sh` script is for deploying your lambda using the AWS Lambda Java runtime.
118+
The `manage.sh` script is for managing your lambda using the AWS Lambda Java runtime. This script is provided only for
119+
your convenience. Should you choose to use Amazon provided tools, you can freely skip these sections and consult the
120+
appropriate Amazon documentation.
121+
122+
`manage.sh` supports four operation: `create`, `delete`, `update`, and `invoke`. You can create your function using
123+
the following command:
119124

120-
.create.sh
121125
[source, subs=attributes+]
122126
----
123-
aws lambda create-function --function-name my-function \
124-
--zip-file fileb://target/my-function-1.0-SNAPSHOT-runner.jar \
125-
--handler io.quarkus.amazon.lambda.runtime.QuarkusStreamHandler::handleRequest \
126-
--runtime java8 \
127-
--role arn:aws:iam::1234567:role/lambda-cli-role
127+
sh manage.sh create
128128
----
129129

130-
Don't forget to replace the `--role` flag with the Arn of your `Execution Role`.
130+
or if you do not have `LAMBDA_ROLE_ARN` already defined in this shell:
131+
132+
[source]
133+
----
134+
LAMBDA_ROLE_ARN="arn:aws:iam::1234567890:role/lambda-role" sh manage.sh create
135+
----
131136

132137
WARNING: Do not change the handler switch. This must be hardcoded to `io.quarkus.amazon.lambda.runtime.QuarkusStreamHandler::handleRequest`. This
133138
handler bootstraps Quarkus and wraps your actual handler so that injection can be performed.
134139

135-
If there are any problems creating the function, you must delete it with the `delete.sh` script before re-running
136-
the `create.sh` script.
137-
138-
== Invoke the Lambda
139-
140-
Use the `invoke.sh` script to invoke your function.
140+
If there are any problems creating the function, you must delete it with the `delete` function before re-running
141+
the `create` command.
141142

142-
.invoke.sh
143143
[source, subs=attributes+]
144144
----
145-
aws lambda invoke --function-name my-function
146-
--payload file://payload.json out
147-
--log-type Tail --query 'LogResult' --output text | base64 -d
145+
sh manage.sh delete
148146
----
149147

150-
The example lambda takes input passed in via the `--payload` switch which points to a json file
151-
in the root directory of the project. If you want to see the return output of the lambda, open the `out` file.
152-
This script will also write the log output to the console.
153-
154-
== Update the Lambda
155-
156-
You can update the Java code as you see fit. Once you've rebuilt, you can redeploy your lambda by executing the
157-
`update.sh` script.
158-
159-
.update.sh
148+
Commands may also be stacked:
160149
[source, subs=attributes+]
161150
----
162-
aws lambda update-function-code --function-name my-function \
163-
--zip-file fileb://target/my-function-1.0-SNAPSHOT-runner.jar
151+
sh manage.sh delete create
164152
----
165153

166-
== Deploy to AWS Lambda Custom (native) Runtime
167-
168-
If you want a lower memory footprint and faster initialization times for your lambda, you can compile your Java
169-
code to a native executable. Just make sure to rebuild your project with the `-Dnative` switch.
170-
171-
== Build and Deploy (native)
154+
== Invoke the Lambda
172155

173-
Build the native executable.
156+
Use the `invoke` command to invoke your function.
174157

175158
[source, subs=attributes+]
176159
----
177-
mvn clean install -Dnative
160+
sh manage.sh invoke
178161
----
179162

180-
This will compile and create a native executable image. It also generates a zip file `target/function.zip`.
181-
This zip file contains your native executable image renamed to `bootstrap`. This is a requirement of Amazon Lambda
182-
Custom Runtime.
183-
184-
185-
== Create an Execution Role
186-
187-
View the https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-awscli.html[Getting Started Guide] for deploying
188-
a lambda with AWS CLI. Specifically make sure you have created an `Execution Role`. You will need the `Role Arn` to copy/paste
189-
into the scripts generated by the maven archetype.
163+
The example lambda takes input passed in via the `--payload` switch which points to a json file
164+
in the root directory of the project. If you want to see the output of the lambda, open the `response.txt` file.
165+
The lambda can also be invoked locally like this:
190166

191-
== Edit native script files
167+
[source]
168+
----
169+
sam local invoke --template sam.jvm.yaml --event payload.json
170+
----
192171

193-
Edit the `create-native.sh` scripts included with the generated project. After the `--role` switch
194-
replace the dummy `Role Arn` with the Arn of the `Execution Role` you created in the Amazon IAM console.
172+
If you are working with your native image build, simply replace the template name above with the native version.
195173

196-
== Create the Native Lambda
174+
== Update the Lambda
197175

198-
The `create-native.sh` script is for deploying your lambda using the AWS Lambda Custom runtime.
176+
You can update the Java code as you see fit. Once you've rebuilt, you can redeploy your lambda by executing the
177+
`update` command.
199178

200-
.create-native.sh
201179
[source, subs=attributes+]
202180
----
203-
aws lambda create-function --function-name my-native-function \
204-
--zip-file fileb://target/function.zip --handler any.name.not.used \
205-
--runtime provided --role arn:aws:iam::1234567:role/lambda-cli-role \
206-
--environment Variables="{DISABLE_SIGNAL_HANDLERS=true}"
181+
sh manage.sh update
207182
----
208183

209-
Don't forget to replace the `--role` flag with the Arn of your `Execution Role`.
210-
211-
Notice that the `--zip-file` flag points to the `function.zip` file generated by the build.
212-
The handler switch is not used, but must be set. It can be any value. Finally, notice that an environment variable
213-
must be set: `DISABLE_SIGNAL_HANDLERS`. This resolves certain incompatibilities with the Amazon Lambda Custom Runtime container
214-
and Quarkus.
215-
216-
If there are any problems creating the function, you must delete it with the `delete-native.sh` script before re-running
217-
the `create-native.sh` script.
218-
219-
== Invoke the Native Lambda
184+
== Deploy to AWS Lambda Custom (native) Runtime
220185

221-
Use the `invoke-native.sh` script to invoke your function.
186+
If you want a lower memory footprint and faster initialization times for your lambda, you can compile your Java
187+
code to a native executable. Just make sure to rebuild your project with the `-Pnative` switch. If you are building
188+
on a non-linux system, you will need to also pass in a property instructing quarkus to use a docker build as Amazon
189+
Lambda requires linux binaries. You can do this by passing this property to your maven build:
190+
`-Dnative-image.docker-build=true`. This requires you to have docker installed locally, however.
222191

223-
.invoke-native.sh
224192
[source, subs=attributes+]
225193
----
226-
aws lambda invoke --function-name my-native-function
227-
--payload file://payload.json out
228-
--log-type Tail --query 'LogResult' --output text | base64 -d
194+
mvn clean install -Pnative -Dnative-image.docker-build=true
229195
----
230196

231-
The example lambda takes input. This input is passed in via the `--payload` switch which points to a json file
232-
in the root directory of the project. If you want to see the return output of the lambda, open the `out` file.
233-
This script will also write the log output to the console.
234-
235-
== Update the Native Lambda
197+
This will compile and create a native executable image. It also generates a zip file `target/function.zip`.
198+
This zip file contains your native executable image renamed to `bootstrap`. This is a requirement of Amazon Lambda
199+
Custom Runtime. If you are building on Linux, the `native-image.docker-build` property is mildly redundant but its primary
200+
cost is a slightly longer build cycle.
236201

237-
You can update the Java code as you see fit. Once you've rebuilt, you can redeploy your lambda by executing the
238-
`update-native.sh` script.
202+
The instructions here are exactly as above with one change: you'll need to add `native` as the first parameter to the
203+
`manage.sh` script:
239204

240-
.update-native.sh
241205
[source, subs=attributes+]
242206
----
243-
aws lambda update-function-code --function-name my-native-function \
244-
--zip-file fileb://target/function.zip
207+
sh manage.sh native create
245208
----
246209

210+
As above, commands can be stacked. The only requirement is that `native` be the first parameter should you wish
211+
to work with native image builds. The script will take care of the rest of the details necessary to manage your native
212+
image function deployments.
213+
247214
== Examine the POM
248215

249-
If you want to adapt an existing project to use Quarkus's Amazon Lambda extension, there's a couple
216+
If you want to adapt an existing project to use Quarkus's Amazon Lambda extension, there are a couple
250217
of things you need to do. Take a look at the generated example project to get an example of what you need to adapt.
251218

252219
1. Include the `quarkus-amazon-lambda` extension as a pom dependency
253220
2. Configure Quarkus to build an `uber-jar` (via quarkus.package.uber-jar=true in the application.properties)
254-
3. If you are doing a native image build, Amazon requires you to rename your executable to `bootstrap` and zip it up. Notice that the `pom.xml` uses the `maven-assembly-plugin` to perform this requirement.
221+
3. If you are doing a native image build, Amazon requires you to rename your executable to `bootstrap` and zip it up.
222+
Notice that the `pom.xml` uses the `maven-assembly-plugin` to perform this requirement.
255223

256224
NB: With gradle, to build the uber-jar execute: ./gradlew quarkusBuild --uber-jar
257225

258226
== Testing with the SAM CLI
259227

260-
The https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html[AWS SAM CLI] allows you to run your lambdas locally on your laptop in a simulated Lambda environment. This requires https://www.docker.com/products/docker-desktop[docker] to be installed.
228+
The https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html[AWS SAM CLI]
229+
allows you to run your lambdas locally on your laptop in a simulated Lambda environment. This requires
230+
https://www.docker.com/products/docker-desktop[docker] to be installed. This is an optional approach should you choose
231+
to take advantage of it. Otherwise, dev mode should be sufficient for most of your needs.
261232

262-
To execute your lambda function with the
263-
`java8` runtime, create a `sam.jvm.yaml` template as below:
264-
----
265-
AWSTemplateFormatVersion: '2010-09-09'
266-
Transform: AWS::Serverless-2016-10-31
267-
268-
Globals:
269-
Function:
270-
Timeout: 5
271-
Resources:
272-
QuarkusSam:
273-
Type: AWS::Serverless::Function
274-
Properties:
275-
Handler: io.quarkus.amazon.lambda.runtime.QuarkusStreamHandler::handleRequest
276-
Runtime: java8
277-
CodeUri: {path to *-runner.jar}
278-
MemorySize: 128
279-
Policies: AWSLambdaBasicExecutionRole
280-
----
281-
282-
Run the following SAM CLI command to test your lambda function with the `Java8` runtime and `sam.jvm.yaml` template:
283-
----
284-
sam local invoke --template sam.jvm.yaml --event {json test file}
285-
----
286-
287-
The native executable can be tested via the `provided` runtime defined in a `sam.native.yaml` template:
288-
----
289-
AWSTemplateFormatVersion: '2010-09-09'
290-
Transform: AWS::Serverless-2016-10-31
291-
292-
Globals:
293-
Function:
294-
Timeout: 5
295-
Resources:
296-
QuarkusSam:
297-
Type: AWS::Serverless::Function
298-
Properties:
299-
Handler: not.used.in.provided.runtimei
300-
Runtime: provided
301-
CodeUri: {path to function.zip}
302-
MemorySize: 128
303-
Policies: AWSLambdaBasicExecutionRole
304-
Timeout: 15
305-
Environment:
306-
Variables:
307-
DISABLE_SIGNAL_HANDLERS: true
308-
----
309-
310-
311-
When using the `provided` runtime, AWS requires a bootstrap script to trigger the native executable. Bundle the `bootstrap` script along with the *-runner executable.
233+
A starter template has been generated for both JVM and native execution modes.
312234

313-
i.e., create a zip file called `function.zip` with:
235+
Run the following SAM CLI command to locally test your lambda function:
314236

315-
* bootstrap
316-
* {projectname-version}-runner
317-
318-
Example `bootstrap` script to load the native executable:
237+
[source]
319238
----
320-
#!/usr/bin/env bash
321-
322-
RUNNER=$( find . -maxdepth 1 -name '*-runner' )
323-
if [[ ! -z "$RUNNER" ]]
324-
then
325-
$RUNNER
326-
fi
239+
sam local invoke --template sam.jvm.yaml --event {json test file}
327240
----
328241

329-
To invoke the native `provided` runtime with the `sam.native.yaml` template, use the following command:
242+
The native image can also be locally tested using the `sam.native.yaml` template:
330243

244+
[source]
331245
----
332246
sam local invoke --template sam.native.yaml --event {json test file}
333247
----

extensions/amazon-lambda/maven-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ under the License.
4646
<includes>
4747
<include>*.sh</include>
4848
<include>*.json</include>
49+
<include>sam.jvm.yaml</include>
50+
<include>sam.native.yaml</include>
4951
</includes>
5052
</fileSet>
5153
</fileSets>

extensions/amazon-lambda/maven-archetype/src/main/resources/archetype-resources/create-native.sh

Lines changed: 0 additions & 1 deletion
This file was deleted.

extensions/amazon-lambda/maven-archetype/src/main/resources/archetype-resources/create.sh

Lines changed: 0 additions & 1 deletion
This file was deleted.

extensions/amazon-lambda/maven-archetype/src/main/resources/archetype-resources/delete-native.sh

Lines changed: 0 additions & 1 deletion
This file was deleted.

extensions/amazon-lambda/maven-archetype/src/main/resources/archetype-resources/delete.sh

Lines changed: 0 additions & 1 deletion
This file was deleted.

extensions/amazon-lambda/maven-archetype/src/main/resources/archetype-resources/invoke-native.sh

Lines changed: 0 additions & 1 deletion
This file was deleted.

extensions/amazon-lambda/maven-archetype/src/main/resources/archetype-resources/invoke.sh

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
function cmd_create() {
2+
echo Creating function
3+
aws lambda create-function \
4+
--function-name ${FUNCTION_NAME} \
5+
--zip-file ${ZIP_FILE} \
6+
--handler ${HANDLER} \
7+
--runtime ${RUNTIME} \
8+
--role ${LAMBDA_ROLE_ARN} \
9+
${LAMBDA_META}
10+
}
11+
12+
function cmd_delete() {
13+
echo Deleting function
14+
aws lambda delete-function --function-name ${FUNCTION_NAME}
15+
}
16+
17+
function cmd_invoke() {
18+
echo Invoking function
19+
aws lambda invoke response.txt \
20+
--function-name ${FUNCTION_NAME} \
21+
--payload file://payload.json
22+
}
23+
24+
function cmd_update() {
25+
echo Updating function
26+
aws lambda update-function-code \
27+
--function-name ${FUNCTION_NAME} \
28+
--zip-file ${ZIP_FILE}
29+
}
30+
31+
FUNCTION_NAME=${resourceName}Function
32+
HANDLER=io.quarkus.amazon.lambda.runtime.QuarkusStreamHandler::handleRequest
33+
RUNTIME=java8
34+
ZIP_FILE=fileb://target/${artifactId}-${version}-runner.jar
35+
36+
if [ "$1" == "native" ]
37+
then
38+
RUNTIME=provided
39+
ZIP_FILE=fileb://target/function.zip
40+
FUNCTION_NAME=${resourceName}NativeFunction
41+
LAMBDA_META="--environment Variables={DISABLE_SIGNAL_HANDLERS=true}"
42+
shift
43+
fi
44+
45+
while [ "$1" ]
46+
do
47+
eval cmd_${1}
48+
shift
49+
done
50+

0 commit comments

Comments
 (0)