Blank function sample application for Amazon Lambda - Amazon Lambda
Services or capabilities described in Amazon Web Services documentation might vary by Region. To see the differences applicable to the China Regions, see Getting Started with Amazon Web Services in China (PDF).

Blank function sample application for Amazon Lambda

The blank function sample application is a starter application that demonstrates common operations in Lambda with a function that calls the Lambda API. It shows the use of logging, environment variables, Amazon X-Ray tracing, layers, unit tests and the Amazon SDK. Explore this application to learn about building Lambda functions in your programming language, or use it as a starting point for your own projects.

Variants of this sample application are available for the following languages:

Variants

The examples in this topic highlight code from the Node.js version, but the details are generally applicable to all variants.

You can deploy the sample in a few minutes with the Amazon CLI and Amazon CloudFormation. Follow the instructions in the README to download, configure, and deploy it in your account.

Architecture and handler code

The sample application consists of function code, an Amazon CloudFormation template, and supporting resources. When you deploy the sample, you use the following Amazon services:

Standard charges apply for each service. For more information, see Amazon Pricing.

The function code shows a basic workflow for processing an event. The handler takes an Amazon Simple Queue Service (Amazon SQS) event as input and iterates through the records that it contains, logging the contents of each message. It logs the contents of the event, the context object, and environment variables. Then it makes a call with the Amazon SDK and passes the response back to the Lambda runtime.

Example blank-nodejs/function/index.js – Handler code
// Handler exports.handler = async function(event, context) { event.Records.forEach(record => { console.log(record.body) }) console.log('## ENVIRONMENT VARIABLES: ' + serialize(process.env)) console.log('## CONTEXT: ' + serialize(context)) console.log('## EVENT: ' + serialize(event)) return getAccountSettings() } // Use SDK client var getAccountSettings = function(){ return lambda.getAccountSettings().promise() } var serialize = function(object) { return JSON.stringify(object, null, 2) }

The input/output types for the handler and support for asynchronous programming vary per runtime. In this example, the handler method is async, so in Node.js this means that it must return a promise back to the runtime. The Lambda runtime waits for the promise to be resolved and returns the response to the invoker. If the function code or Amazon SDK client return an error, the runtime formats the error into a JSON document and returns that.

The sample application doesn't include an Amazon SQS queue to send events, but uses an event from Amazon SQS (event.json) to illustrate how events are processed. To add an Amazon SQS queue to your application, see Using Lambda with Amazon SQS.

Deployment automation with Amazon CloudFormation and the Amazon CLI

The sample application's resources are defined in an Amazon CloudFormation template and deployed with the Amazon CLI. The project includes simple shell scripts that automate the process of setting up, deploying, invoking, and tearing down the application.

The application template uses an Amazon Serverless Application Model (Amazon SAM) resource type to define the model. Amazon SAM simplifies template authoring for serverless applications by automating the definition of execution roles, APIs, and other resources.

The template defines the resources in the application stack. This includes the function, its execution role, and a Lambda layer that provides the function's library dependencies. The stack does not include the bucket that the Amazon CLI uses during deployment or the CloudWatch Logs log group.

Example blank-nodejs/template.yml – Serverless resources
AWSTemplateFormatVersion: '2010-09-09' Transform: 'AWS::Serverless-2016-10-31' Description: An Amazon Lambda application that calls the Lambda API. Resources: function: Type: AWS::Serverless::Function Properties: Handler: index.handler Runtime: nodejs16.x CodeUri: function/. Description: Call the Amazon Lambda API Timeout: 10 # Function's execution role Policies: - AWSLambdaBasicExecutionRole - AWSLambda_ReadOnlyAccess - AWSXrayWriteOnlyAccess Tracing: Active Layers: - !Ref libs libs: Type: AWS::Serverless::LayerVersion Properties: LayerName: blank-nodejs-lib Description: Dependencies for the blank sample app. ContentUri: lib/. CompatibleRuntimes: - nodejs16.x

When you deploy the application, Amazon CloudFormation applies the Amazon SAM transform to the template to generate an Amazon CloudFormation template with standard types such as AWS::Lambda::Function and AWS::IAM::Role.

Example processed template
{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "An Amazon Lambda application that calls the Lambda API.", "Resources": { "function": { "Type": "AWS::Lambda::Function", "Properties": { "Layers": [ { "Ref": "libs32xmpl61b2" } ], "TracingConfig": { "Mode": "Active" }, "Code": { "S3Bucket": "lambda-artifacts-6b000xmpl1e9bf2a", "S3Key": "3d3axmpl473d249d039d2d7a37512db3" }, "Description": "Call the Amazon Lambda API", "Tags": [ { "Value": "SAM", "Key": "lambda:createdBy" } ],

In this example, the Code property specifies an object in an Amazon S3 bucket. This corresponds to the local path in the CodeUri property in the project template:

CodeUri: function/.

To upload the project files to Amazon S3, the deployment script uses commands in the Amazon CLI. The cloudformation package command preprocesses the template, uploads artifacts, and replaces local paths with Amazon S3 object locations. The cloudformation deploy command deploys the processed template with a Amazon CloudFormation change set.

Example blank-nodejs/3-deploy.sh – Package and deploy
#!/bin/bash set -eo pipefail ARTIFACT_BUCKET=$(cat bucket-name.txt) aws cloudformation package --template-file template.yml --s3-bucket $ARTIFACT_BUCKET --output-template-file out.yml aws cloudformation deploy --template-file out.yml --stack-name blank-nodejs --capabilities CAPABILITY_NAMED_IAM

The first time you run this script, it creates a Amazon CloudFormation stack named blank-nodejs. If you make changes to the function code or template, you can run it again to update the stack.

The cleanup script (blank-nodejs/5-cleanup.sh) deletes the stack and optionally deletes the deployment bucket and function logs.

Instrumentation with the Amazon X-Ray

The sample function is configured for tracing with Amazon X-Ray. With the tracing mode set to active, Lambda records timing information for a subset of invocations and sends it to X-Ray. X-Ray processes the data to generate a service map that shows a client node and two service nodes.

The first service node (AWS::Lambda) represents the Lambda service, which validates the invocation request and sends it to the function. The second node, AWS::Lambda::Function, represents the function itself.

To record additional detail, the sample function uses the X-Ray SDK. With minimal changes to the function code, the X-Ray SDK records details about calls made with the Amazon SDK to Amazon services.

Example blank-nodejs/function/index.js – Instrumentation
const AWSXRay = require('aws-xray-sdk-core') const AWS = AWSXRay.captureAWS(require('aws-sdk')) // Create client outside of handler to reuse const lambda = new AWS.Lambda()

Instrumenting the Amazon SDK client adds an additional node to the service map and more detail in traces. In this example, the service map shows the sample function calling the Lambda API to get details about storage and concurrency usage in the current Region.

The trace shows timing details for the invocation, with subsegments for function initialization, invocation, and overhead. The invocation subsegment has a subsegment for the Amazon SDK call to the GetAccountSettings API operation.

You can include the X-Ray SDK and other libraries in your function's deployment package, or deploy them separately in a Lambda layer. For Node.js, Ruby, and Python, the Lambda runtime includes the Amazon SDK in the execution environment.

Dependency management with layers

You can install libraries locally and include them in the deployment package that you upload to Lambda, but this has its drawbacks. Larger file sizes cause increased deployment times and can prevent you from testing changes to your function code in the Lambda console. To keep the deployment package small and avoid uploading dependencies that haven't changed, the sample app creates a Lambda layer and associates it with the function.

Example blank-nodejs/template.yml – Dependency layer
Resources: function: Type: AWS::Serverless::Function Properties: Handler: index.handler Runtime: nodejs16.x CodeUri: function/. Description: Call the Amazon Lambda API Timeout: 10 # Function's execution role Policies: - AWSLambdaBasicExecutionRole - AWSLambda_ReadOnlyAccess - AWSXrayWriteOnlyAccess Tracing: Active Layers: - !Ref libs libs: Type: AWS::Serverless::LayerVersion Properties: LayerName: blank-nodejs-lib Description: Dependencies for the blank sample app. ContentUri: lib/. CompatibleRuntimes: - nodejs16.x

The 2-build-layer.sh script installs the function's dependencies with npm and places them in a folder with the structure required by the Lambda runtime.

Example 2-build-layer.sh – Preparing the layer
#!/bin/bash set -eo pipefail mkdir -p lib/nodejs rm -rf node_modules lib/nodejs/node_modules npm install --production mv node_modules lib/nodejs/

The first time that you deploy the sample application, the Amazon CLI packages the layer separately from the function code and deploys both. For subsequent deployments, the layer archive is only uploaded if the contents of the lib folder have changed.