Test your Ballerina Function written for AWS Lambda
This article explains how we can locally test AWS Lambda function written in Ballerina.
Implementing your Lambda function in Ballerina
Lets create a Ballerina file named hello_world.bal
. In that create a function with @awslambda:Function
annotations that returns “Hello World!” as follows:
Now lets build our Ballerina file using the ballerina build
command. I am using Ballerina version 1.1.3 here. You should get an output like this when building with the @awslambda:Function
annotation.
$> ballerina build hello_world.bal
Compiling source
hello_world.balGenerating executables
hello_world.jar
@awslambda:Function: sayHelloRun the following commands to deploy each Ballerina AWS Lambda function: aws lambda create-function --function-name <FUNCTION_NAME> --zip-file fileb://aws-ballerina-lambda-functions.zip --handler hello_world.<FUNCTION_NAME> --runtime provided --role <LAMBDA_ROLE_ARN> --timeout 10 --memory-size 1024 aws lambda update-function-configuration --function-name <FUNCTION_NAME> --layers arn:aws:lambda:<REGION_ID>:141896495686:layer:ballerina:2Run the following command to re-deploy an updated Ballerina AWS Lambda function:
aws lambda update-function-code --function-name <FUNCTION_NAME> --zip-file fileb://aws-ballerina-lambda-functions.zip
You should see a zip file generated having the name “aws-ballerina-lambda-functions.zip”. Make note of the layer name arn:aws:lambda:<REGION_ID>:141896495686:layer:ballerina:2
mentioned in the output logs as well.
We have now generated the artifacts to deploy the function in AWS Lambda. But we going to test it locally first.
Testing your Lambda Function Locally
Following tasks/requirements are needed to test our AWS Lambda function locally.
- AWS CLI command configured to an account. This is to download the layers locally.
- Docker is up and running.
- Install
sam
command. - Write a AWS SAM specification yaml file.
Installing sam
command
sam
is a CLI command used in creating and managing serverless applications. You can refer the official documentation on how to install it at https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html.
I used Homebrew since I am on MacOS.
$> brew tap aws/tap
$> brew install aws-sam-cli
$> sam --version
SAM CLI, version 0.41.0
Write a AWS SAM specification yaml file.
The AWS SAM specification file defines resources types, resource properties and etc for our serverless application.
You can find the official documentation of the specification yaml file at https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification.html.
Now lets write a template.yml
specification file to specify where our function code can be found and the necessary runtime and layers to execute the function.
In the template.yml
we’ll define an AWS::Serverless::Function
resource with name “HelloWorldFunction”. In that resource specify the following properties:
- Set
Runtime
field asprovided
because we will be using a layer which has the runtime dependencies. - Set
CodeUri
to theaws-ballerina-lambda-functions.zip
file which was generated from theballerina build
command. - Set
Handler
ashello_world.sayHello
.hello_world
is the name of the Ballerina file andsayHello
is the name of the Ballerina function in the Ballerina file. - Set
Layer
asarn:aws:lambda:us-east-1:141896495686:layer:ballerina:2
. This is the same layer that was shown fromballerina build
command. Here we useus-east-1
as the<REGION_ID>
.
Now lets test function with debug logs enabled by executing the following command. HelloWorldFunction
is the resource name we provided in the template.yml.
$> sam local invoke “HelloWorldFunction” --debug
Telemetry endpoint configured to be https://aws-serverless-tools-telemetry.us-west-2.amazonaws.com/metrics
local invoke command is called
No Parameters detected in the template
1 resources found in the template
Found Serverless function with name='HelloWorldFunction' and CodeUri='aws-ballerina-lambda-functions.zip'
Found one Lambda function with name 'HelloWorldFunction'
Invoking hello_world.sayHello (provided)
No environment variables found for function 'HelloWorldFunction'
Environment variables overrides data is standard format
Loading AWS credentials from session with profile 'None'
Resolving code path. Cwd=/private/tmp/hello_world_lambda, CodeUri=aws-ballerina-lambda-functions.zip
Resolved absolute path to code is /private/tmp/hello_world_lambda/aws-ballerina-lambda-functions.zip
Decompressing /private/tmp/hello_world_lambda/aws-ballerina-lambda-functions.zip
File hello_world.jar in zipfile does not have permission information
File functions.jar in zipfile does not have permission information
arn:aws:lambda:us-east-1:141896495686:layer:ballerina:2 is already cached. Skipping download
Image was not found.
Building image...
Requested to skip pulling images ...Mounting /private/var/folders/0j/kf99jpqj0zs_26zw7vygjgc00000gn/T/tmp04blut77 as /var/task:ro,delegated inside runtime container
Starting a timer for 10 seconds for function 'HelloWorldFunction'
START Ballerina
START RequestId: c04371a4-da9d-1359-31b7-448940edce98 Version: $LATEST
END RequestId: c04371a4-da9d-1359-31b7-448940edce98
REPORT RequestId: c04371a4-da9d-1359-31b7-448940edce98 Init Duration: 3070.89 ms Duration: 126.78 ms Billed Duration: 200 ms Memory Size: 128 MB Max Memory Used: 76 MB
Sending Telemetry: {'metrics': [{'commandRun': {'awsProfileProvided': False, 'debugFlagProvided': True, 'region': '', 'commandName': 'sam local invoke', 'duration': 15941, 'exitReason': 'success', 'exitCode': 0, 'requestId': 'fc2eb900-21b4-471c-9c82-396a7e187999', 'installationId': 'cea54d15-ca1e-429d-a9f1-e801086e0349', 'sessionId': 'b5b1b6bc-a206-4094-af98-1ede605618d1', 'executionEnvironment': 'CLI', 'pyversion': '3.7.6', 'samcliVersion': '0.41.0'}}]}
HTTPSConnectionPool(host='aws-serverless-tools-telemetry.us-west-2.amazonaws.com', port=443): Read timed out. (read timeout=0.1)"Hello World!"
From the output we can see that “Hello World” has been logged. So our function has successfully run locally!.
In the above logs it can be seen that it says “Building image…”. This is a docker image that has been pulled by the CLI to to run the lambda function locally. You can see this image by running docker images
.
By default the SAM CLI collects telemetry. More information on this behaviour can be found at https://github.com/awslabs/aws-sam-cli/issues/1525. You can disable telemetry by setting the following environment variable.
export SAM_CLI_TELEMETRY=0