Skip to main content

Function

A construct for a Lambda Function that allows you to develop your it locally. Supports JS, TypeScript, Python, Golang, and C#. It also applies a couple of defaults:

  • Sets the default memory setting to 1024MB.
  • Sets the default Lambda function timeout to 10 seconds.
  • Enables AWS X-Ray by default so you can trace your serverless applications.
  • AWS_NODEJS_CONNECTION_REUSE_ENABLED is turned on. Meaning that the Lambda function will automatically reuse TCP connections when working with the AWS SDK. Read more about this here.
  • Sets the IS_LOCAL environment variable for the Lambda function when it is invoked locally through the sst start command.

Constructor

new Function(scope, id, props)

Parameters

Examples

Creating a Function

import { Function } from "@serverless-stack/resources";

new Function(stack, "MySnsLambda", {
handler: "src/sns/index.main",
});

Setting additional props

Use the cdk.lambda.FunctionOptions to set additional props.

new Function(stack, "MyApiLambda", {
handler: "src/api.main",
timeout: 10,
environment: {
TABLE_NAME: "notes",
},
});

Setting default props

If you have properties that need to be applied to all the functions in your app, they can be set on the App construct using the setDefaultFunctionProps method.

app.setDefaultFunctionProps({
timeout: 20,
memorySize: 512,
});

Similarly, you can apply properties to all the functions in a specific Stack.

stack.setDefaultFunctionProps({
timeout: 20,
memorySize: 512,
});

Using SSM values as environment variables

import { StringParameter } from "aws-cdk-lib/aws-ssm";

const apiKey = StringParameter.valueFromLookup(this, "my_api_key");

new Function(stack, "MyApiLambda", {
handler: "src/api.main",
environment: {
API_KEY: apiKey,
},
});

The API_KEY environment variable can be accessed as process.env.API_KEY within the Lambda function.

Using IS_LOCAL environment variable

export async function main(event) {
return {
statusCode: 200,
headers: { "Content-Type": "text/plain" },
body: `Hello, World! Are we running locally: ${!!process.env.IS_LOCAL}`,
};
}

Configuring Node.js runtime

handler

The handler property points to the path of the entry point and handler function. Uses the format, /path/to/file.function. Where the first part is the path to the file, followed by the name of the function that's exported in that file.

For example, if your handler file is in src/lambda.ts and it exported a function called main. The handler would be src/lambda.main.

SST checks for a file with a .ts, .tsx, .js, or .jsx extension.

If the srcPath is set, then the path to the handler is relative to it. So if the srcPath is set to src. Then lambda.main as the handler would mean that the file is in src/lambda.js (or the other extensions).

srcPath

The directory that needs to zipped up as the Lambda function package. Only applicable if the bundle option is set to false.

Note that for TypeScript functions, if the srcPath is not the project root, SST expects the tsconfig.json to be in this directory.

bundle

Bundles your Lambda functions with esbuild. Turn this off if you have npm packages that cannot be bundled. Currently bundle cannot be disabled if the srcPath is set to the project root. Read more about this here.

If you want to configure the bundling process, you can pass in the FunctionBundleNodejsProps.

Disabling bundling

new Function(stack, "MyLambda", {
bundle: false,
srcPath: "src",
handler: "lambda.main",
});

In this case, SST will zip the entire src/ directory for the Lambda function.

Configure bundling

new Function(stack, "MyLambda", {
bundle: {
externalModules: ["fsevents"],
nodeModules: ["uuid"],
format: "esm",
loader: {
".png": "dataurl",
},
copyFiles: [{ from: "public", to: "." }],
commandHooks: {
beforeBundling: (inputDir, outputDir) => {
return [ "echo beforeBundling" ];
},
beforeInstall: (inputDir, outputDir) => {
return [ "echo beforeInstall" ];
},
afterBundling: (inputDir, outputDir) => {
return [ "echo afterBundling" ];
},
},
},
handler: "src/lambda.main",
});

Configure esbuild plugins

To use an esbuild plugin, install the plugin npm package in your project. Then create a config file that exports the plugin.

config/esbuild.js
const { esbuildDecorators } = require("@anatine/esbuild-decorators");

module.exports = [
esbuildDecorators(),
];

You can now reference the config file in your functions.

stacks/MyStack.js
new Function(stack, "MyLambda", {
bundle: {
esbuildConfig: {
plugins: "config/esbuild.js",
},
},
handler: "src/lambda.main",
});

Configuring Python runtime

handler

Path to the entry point and handler function relative to the srcPath. Uses the format, path/to/file.function. Where the first part is the path to the file, followed by the name of the function that's exported in that file.

For example, if your srcPath is src/, your handler file is in src/lambda.py, and it exported a function called main. The handler would be lambda.main.

srcPath

For Python functions, srcPath is required. This is the directory where the requirements.txt, Pipfile, or poetry.lock is expected.

new Function(stack, "MyLambda", {
bundle: {
installCommands: [
"pip install --index-url https://domain.com/pypi/myprivatemodule/simple/ --extra-index-url https://pypi.org/simple"
],
},
srcPath: "src",
handler: "index.main",
runtime: "python3.7",
});

bundle

For Python functions, a dependency manager is used to install the packages. The dependency manager is selected based on which of the following files are found in the srcPath:

FileSteps
requirements.txtpip is used to run pip install
PipfilePipenv is used to generate a requirements.txt and then pip install is run
poetry.lockpoetry is used to generate a requirements.txt and then pip install is run

You can override this behavior by passing in the installCommands through the FunctionBundlePythonProps.

Note that for Python functions, you'll need to have Docker installed. When building and deploying, this construct will handle installing all the required modules in a Lambda compatible Docker container, based on the runtime. This ensures that the Python Lambda functions are compiled correctly.

Configuring Go runtime

handler

Path to the handler function. Uses the format, /path/to/file.go or just /path/to.

If the srcPath is set, then the path to the handler is relative to it. So if the srcPath is set to src. Then lambda.go as the handler would mean that the file is in src/lambda.go.

srcPath

The directory where go.mod is found.

bundle

Only supported for the Node.js and Python runtimes.

Configuring C#(.NET) runtime

handler

Path to the handler function. Uses the format, ASSEMBLY::TYPE::METHOD.

  • ASSEMBLY is the name of the .NET assembly file. If you haven't set the assembly name using the AssemblyName property in .csproj, the ASSEMBLY name will be the .csproj file name.
  • TYPE is the full name of the handler type. Consists of the Namespace and the ClassName.
  • METHOD is the name of the function handler.

Consider a project with MyApp.csproj and the following handler function:

namespace Example
{
public class Hello
{
public Stream MyHandler(Stream stream)
{
//function logic
}
}
}

The handler would be, MyApp::Example.Hello::MyHandler.

srcPath

The directory where .csproj is found.

bundle

Only supported for the Node.js and Python runtimes.

Configuring F#(.NET) runtime

handler

The handler function. Uses the format, ASSEMBLY::TYPE::METHOD.

  • ASSEMBLY is the name of the .NET assembly file. If you haven't set the assembly name using the AssemblyName property in .fsproj, the ASSEMBLY name will be the .fsproj file name.
  • TYPE is the full name of the handler type, which consists of the Namespace and the ClassName.
  • METHOD is the name of the function handler.

Consider a project with MyApp.fsproj and the following handler function:

namespace Example

module Hello =

let Handler(request:APIGatewayHttpApiV2ProxyRequest) =
//function logic

The handler would be: MyApp::Example.Hello::MyHandler.

srcPath

The directory where .fsproj is found.

bundle

Only supported for the Node.js and Python runtimes.

Advanced examples

Configuring a Dead Letter Queue

const queue = new Queue(this, "MyDLQ");

new Function(stack, "MyApiLambda", {
handler: "src/api.main",
deadLetterQueue: queue.cdk.queue,
});

Configuring Provisioned Concurrency

const fn = new Function(stack, "MyApiLambda", {
handler: "src/api.main",
currentVersionOptions: {
provisionedConcurrentExecutions: 5,
},
});

const version = fn.currentVersion;

Note that Provisioned Concurrency needs to be configured on a specific Function version. By default, versioning is not enabled, and setting currentVersionOptions has no effect. By accessing the currentVersion property, a version is automatically created with the provided options.

FunctionProps

architecture?

Type : "arm_64" | "x86_64"

Default : "x86_64"

The CPU architecture of the lambda function.

new Function(stack, "Function", {
architecture: "arm_64",
})

bundle?

Type : FunctionBundleNodejsProps | FunctionBundlePythonProps | boolean

Configure or disable bundling options

new Function(stack, "Function", {
bundle: {
copyFiles: [{ from: "src/index.js" }]
}
})

diskSize?

Type : number | ${number} MB | ${number} GB

Default : "512 MB"

The amount of disk storage in MB allocated.

new Function(stack, "Function", {
diskSize: "2 GB",
})

enableLiveDev?

Type : boolean

Default : true

Can be used to disable Live Lambda Development when using sst start. Useful for things like Custom Resources that need to execute during deployment.

new Function(stack, "Function", {
enableLiveDev: false
})

environment?

Type : Record<string, string>

Configure environment variables for the function

new Function(stack, "Function", {
environment: {
TABLE_NAME: table.tableName,
}
})

functionName?

Type : string | FunctionNameProps => string

Default : Auto-generated function name

By default, the name of the function is auto-generated by AWS. You can configure the name by providing a string.

new Function(stack, "Function", {
functionName: "my-function",
})

handler?

Type : string

Path to the entry point and handler function. Of the format: /path/to/file.function.

new Function(stack, "Function", {
handler: "src/function.handler",
})

layers?

Type : Array<string | ILayerVersion>

Default : no layers

A list of Layers to add to the function's execution environment. Note that, if a Layer is created in a stack (say stackA) and is referenced in another stack (say stackB), SST automatically creates an SSM parameter in stackA with the Layer's ARN. And in stackB, SST reads the ARN from the SSM parameter, and then imports the Layer.

This is to get around the limitation that a Lambda Layer ARN cannot be referenced across stacks via a stack export. The Layer ARN contains a version number that is incremented everytime the Layer is modified. When you refer to a Layer's ARN across stacks, a CloudFormation export is created. However, CloudFormation does not allow an exported value to be updated. Once exported, if you try to deploy the updated layer, the CloudFormation update will fail. You can read more about this issue here - https://github.com/serverless-stack/serverless-stack/issues/549.

new Function(stack, "Function", {
layers: ["arn:aws:lambda:us-east-1:764866452798:layer:chrome-aws-lambda:22", myLayer]
})

memorySize?

Type : number | ${number} MB | ${number} GB

Default : "1 GB"

The amount of memory in MB allocated.

new Function(stack, "Function", {
memorySize: "2 GB",
})

permissions?

Type : Permissions

Attaches the given list of permissions to the function. Configuring this property is equivalent to calling attachPermissions() after the function is created.

new Function(stack, "Function", {
permissions: ["ses", bucket]
})

runtime?

Type : "nodejs" | "nodejs4.3" | "nodejs6.10" | "nodejs8.10" | "nodejs10.x" | "nodejs12.x" | "nodejs14.x" | "nodejs16.x" | "python2.7" | "python3.6" | "python3.7" | "python3.8" | "python3.9" | "dotnetcore1.0" | "dotnetcore2.0" | "dotnetcore2.1" | "dotnetcore3.1" | "dotnet6" | "go1.x"

Default : "nodejs14.x"

The runtime environment. Only runtimes of the Node.js, Python, Go, and .NET (C# and F#) family are supported.

new Function(stack, "Function", {
runtime: "nodejs16.x",
})

srcPath?

Type : string

Default : Defaults to the same directory as sst.json

Root directory of the project, typically where package.json is located. Set if using a monorepo with multiple subpackages

new Function(stack, "Function", {
srcPath: "packages/backend",
handler: "function.handler",
})

timeout?

Type : number | ${number} second | ${number} seconds | ${number} minute | ${number} minutes | ${number} hour | ${number} hours | ${number} day | ${number} days

Default : "10 seconds"

The execution timeout in seconds.

new Function(stack, "Function", {
timeout: "30 seconds",
})

tracing?

Type : "active" | "pass_through" | "disabled"

Default : "active"

Enable AWS X-Ray Tracing.

new Function(stack, "Function", {
tracing: "pass_through",
})

Properties

An instance of Function has the following properties.

Methods

An instance of Function has the following methods.

attachPermissions

attachPermissions(permissions)

Parameters

Attaches additional permissions to function

fn.attachPermissions(["s3"]);

FunctionNameProps

functionProps

Type : FunctionProps

The function properties

stack

Type : Stack

The stack the function is being created in

FunctionHandlerProps

bundle

Type : FunctionBundleNodejsProps | FunctionBundlePythonProps | boolean

handler

Type : string

runtime

Type : string

srcPath

Type : string

FunctionBundleNodejsProps

Used to configure NodeJS bundling options

new Function(stack, "Function", {
bundle: {
format: "esm",
minify: false
}
})

commandHooks?

Type : ICommandHooks

Hooks to run at various stages of bundling

copyFiles?

Type : Array<FunctionBundleCopyFilesProps>

Used to configure additional files to copy into the function bundle

new Function(stack, "Function", {
bundle: {
copyFiles: [{ from: "src/index.js" }]
}
})

esbuildConfig.define?

Type : Record<string, string>

Replace global identifiers with constant expressions.

new Function(stack, "Function", {
bundle: {
esbuildConfig: {
define: {
str: "text"
}
}
}
})

esbuildConfig.keepNames?

Type : boolean

When minifying preserve names of functions and variables

new Function(stack, "Function", {
bundle: {
esbuildConfig: {
keepNames: true
}
}
})

esbuildConfig.plugins?

Type : string

Path to a file that returns an array of esbuild plugins

new Function(stack, "Function", {
bundle: {
esbuildConfig: {
plugins: "path/to/plugins.js"
}
}
})

Where path/to/plugins.js looks something like this:

const { esbuildDecorators } = require("@anatine/esbuild-decorators");

module.exports = [
esbuildDecorators(),
];

This allows you to customize esbuild config.

externalModules?

Type : Array<string>

Packages that will not be included in the bundle. Usually used to exclude dependencies that are provided in layers

new Function(stack, "Function", {
bundle: {
externalModules: ["prisma"]
}
})

format?

Type : "cjs" | "esm"

Default : "cjs"

Configure bundle format

new Function(stack, "Function", {
bundle: {
format: "esm"
}
})

loader?

Type : Record<string, Loader>

Configure additional esbuild loaders for other file extensions

new Function(stack, "Function", {
bundle: {
loader: {
".png": "file"
}
}
})

minify?

Type : boolean

Default : true

Enable or disable minification

new Function(stack, "Function", {
bundle: {
minify: false
}
})

nodeModules?

Type : Array<string>

Packages that will be excluded from the bundle and installed into node_modules instead. Useful for dependencies that cannot be bundled, like those with binary dependencies.

new Function(stack, "Function", {
bundle: {
nodeModules: ["pg"]
}
})

FunctionBundlePythonProps

Used to configure Python bundling options

new Function(stack, "Function", {
bundle: {
installCommands: [
'export VARNAME="my value"',
'pip install --index-url https://domain.com/pypi/myprivatemodule/simple/ --extra-index-url https://pypi.org/simple',
]
}
})

copyFiles?

Type : Array<FunctionBundleCopyFilesProps>

Used to configure additional files to copy into the function bundle

new Function(stack, "Function", {
bundle: {
copyFiles: [{ from: "src/index.js" }]
}
})

installCommands?

Type : Array<string>

Default : "[]"

A list of commands to override the default installing behavior for Python dependencies. Each string in the array is a command that'll be run. For example:

new Function(stack, "Function", {
bundle: {
installCommands: [
'export VARNAME="my value"',
'pip install --index-url https://domain.com/pypi/myprivatemodule/simple/ --extra-index-url https://pypi.org/simple',
]
}
})

FunctionBundleCopyFilesProps

Used to configure additional files to copy into the function bundle

new Function(stack, "Function", {
bundle: {
copyFiles: [{ from: "src/index.js" }]
}
})

from

Type : string

Source path relative to sst.json

to?

Type : string

Destination path relative to function root in bundle