Function
caution
This is the SST v0.x Constructs doc. SST v1 is now released. If you are using v1, see the v1 Constructs doc. If you are looking to upgrade to v1, check out the migration steps.
A replacement for the cdk.lambda.NodejsFunction
that allows you to develop your Lambda functions 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 thesst start
command.
Initializerβ
new Function(scope: Construct, id: string, props: FunctionProps)
Parameters
- scope
Construct
- id
string
- props
FunctionProps
Examplesβ
Creating a Functionβ
import { Function } from "@serverless-stack/resources";
new Function(this, "MySnsLambda", {
handler: "src/sns/index.main",
});
Configure Bundling a Node.js Functionβ
Disabling bundlingβ
new Function(this, "MySnsLambda", {
bundle: false,
srcPath: "src/",
handler: "sns/index.main",
});
In this case, SST will zip the entire src/
directory for the Lambda function.
Configure bundlingβ
new Function(this, "MySnsLambda", {
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/sns/index.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.
const { esbuildDecorators } = require("@anatine/esbuild-decorators");
module.exports = [
esbuildDecorators(),
];
You can now reference the config file in your functions.
new Function(this, "MySnsLambda", {
bundle: {
esbuildConfig: {
plugins: "config/esbuild.js",
},
},
handler: "src/sns/index.main",
});
Configure Bundling a Python Functionβ
new Function(this, "MySnsLambda", {
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",
});
Setting additional propsβ
Use the cdk.lambda.FunctionOptions
to set additional props.
new Function(this, "MyApiLambda", {
handler: "src/api.main",
timeout: 10,
environment: {
TABLE_NAME: "notes",
},
});
Configuring a Dead Letter Queueβ
const queue = new Queue(this, "MyDLQ");
new Function(this, "MyApiLambda", {
handler: "src/api.main",
deadLetterQueue: queue.sqsQueue,
});
Using SSM values as environment variablesβ
import { StringParameter } from "aws-cdk-lib/aws-ssm";
const apiKey = StringParameter.valueFromLookup(this, "my_api_key");
new Function(this, "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.
Configuring Provisioned Concurrencyβ
const fn = new Function(this, "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.
Use the 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}`,
};
}
Propertiesβ
Refer to the properties made available by cdk.lambda.Function
.
Default Propertiesβ
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.
Methodsβ
An instance of Function
contains the following methods.
attachPermissionsβ
attachPermissions(permissions: Permissions)
Parameters
- permissions
Permissions
Attaches the given list of permissions to the function. This method makes it easy to control the permissions you want the function to have access to. It can range from complete access to all AWS resources, all the way to a specific permission for a resource.
Head over to the Permissions
docs to read about this in detail.
FunctionPropsβ
Takes the following construct props in addition to the cdk.lambda.FunctionOptions
.
functionName?β
Type : string | ((props: FunctionNameProps) => string
, defaults to auto-generated function name
By default, functionName
is auto-generated by CloudFormation template. You can configure the name by providing a string
.
{
functionName: "my-function-name",
handler: "src/lambda.main",
}
Or if you need to access the function's props, you can pass in a callback. For example, you can generate the function name based on the handler file name.
{
functionName: ({ functionProps, stack }) => (
`${stack.stackName}-${path.parse(functionProps.handler).name}`
),
handler: "src/lambda.main",
}
handlerβ
Type : string
Node.js runtimeβ
Path to 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.js
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).
Python runtimeβ
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
.
Go runtimeβ
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
.
C# (.NET) runtimeβ
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 theAssemblyName
property in.csproj
, theASSEMBLY
name will be the.csproj
file name.TYPE
is the full name of the handler type. Consists of theNamespace
and theClassName
.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
.
F# (.NET) runtimeβ
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, theASSEMBLY
name will be the .fsproj file name.TYPE
is the full name of the handler type, which consists of theNamespace
and theClassName
.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
.
bundle?β
Type : boolean | FunctionBundleNodejsProps | FunctionBundlePythonProps
, defaults to true
Node.js runtimeβ
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.
Python runtimeβ
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
:
File | Steps |
---|---|
requirements.txt | pip is used to run pip install |
Pipfile | Pipenv is used to generate a requirements.txt and then pip install is run |
poetry.lock | poetry 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.
Go runtimeβ
Only supported for the Node.js and Python runtimes.
C# (.NET) runtimeβ
Only supported for the Node.js and Python runtimes.
F# (.NET) runtimeβ
Only supported for the Node.js and Python runtimes.
srcPath?β
Type : string
, defaults to the project root
Node.js runtimeβ
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.
Python runtimeβ
For Python functions, srcPath
is required. This is the directory where the requirements.txt
, Pipfile
, or poetry.lock
is expected.
Go runtimeβ
The directory where go.mod
is found.
C# (.NET) runtimeβ
The directory where .csproj
is found.
F# (.NET) runtimeβ
The directory where .fsproj
is found.
enableLiveDev?β
Type : boolean
, defaults to 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.
memorySize?β
Type : number
, defaults to 1024
The amount of memory in MB allocated to this function.
timeout?β
Type : number | cdk.core.Duration
, defaults to 10
The function execution timeout in seconds. You can pass in the timeout as a number
or as cdk.core.Duration
.
runtime?β
Type : string | cdk.lambda.Runtime
, defaults to nodejs12.x
The runtime environment. You can pass in the runtime as a string
or as cdk.lambda.Runtime
. Only runtimes of the Node.js, Python, Go, and .NET (C# and F#) family are supported.
tracing?β
Type : cdk.lambda.Tracing
, defaults to cdk.lambda.Tracing.ACTIVE
Turns on AWS X-RAY for the Lambda function, to enable tracing.
permissions?β
Type : Permissions
, defaults to []
Attaches the given list of permissions to the function. Configuring this property is equivalent to calling attachPermissions
after the function is created.
layers?β
Type : cdk.lambda.ILayerVersion[]
, defaults to 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.
FunctionDefinitionβ
Type : string | Function | FunctionProps
All the high-level SST constructs that create a function internally accepts this as a type. So you can define a function by passing in the handler as a string:
"src/create.main"
Or the FunctionProps
:
{
bundle: false,
srcPath: "src/",
handler: "sns/index.main",
}
Or an instance of the Function itself.
new Function(this, "Create", {
handler: "src/create.main",
});
FunctionNamePropsβ
functionPropsβ
Type : FunctionProps
The function props with all default function properties merged.
stackβ
Type : Stack
The Stack current function belongs to.
FunctionBundleNodejsPropsβ
loader?β
Type : { [string]: esbuild.Loader }
, defaults to {}
Use loaders to change how a given input file is interpreted. This prop is passed in to esbuild's Loader option.
It takes the extension of the file as the key and loader as the value. For example:
{
".svg": "text",
".png": "dataurl",
}
For more info, check out the list of built-in content types (and loaders) that esbuild supports.
externalModules?β
Type : string[]
, defaults to ["aws-sdk"]
A list of modules that should be considered as externals. An external is a module that will be externally available in the Lambda function.
For example, the aws-sdk
package is available in the Lambda runtime and does not have to be packaged with your function. Similarly, if you have a module that you are packaging as a Lambda Layer, you'll need to list that as an external.
nodeModules?β
Type : string[]
, defaults to all modules are bundled
A list of modules that should not be bundled but instead included in the node_modules
folder of the Lambda package. This is useful when working with native dependencies or when esbuild
fails to bundle a module.
For some background, esbuild will traverse through all the imported modules in your function and generate an optimal bundle. You can skip this process for some modules by passing them in as nodeModules
.
Note that the modules listed in nodeModules
must be present in the package.json
's dependencies. The same version will be used for installation. The lock file, yarn.lock
or package-lock.json
, will be used along with its respective installer, yarn or npm.
externalModules vs nodeModulesβ
The two props externalModules
and nodeModules
might seem similar but there is one critical difference.
The externalModules
are NOT included in your Lambda function package. It's expected that these are made available in the Lambda function environment. Typically meant for modules that are used as Lambda Layers.
The nodeModules
on the other hand are included in the Lambda function package. But they are simply zipped up directly in a node_modules/
directory. They are not bundled using esbuild. This is meant for modules that are not compatible with esbuild.
So for:
nodeModules: [ "uuid" ]
The Lambda function package will look like:
/
Β Β lambda.js
Β Β node_modules/
Β Β Β Β uuid/
Whereas with:
externalModules: [ "uuid" ]
The Lambda function package will look like:
/
Β Β lambda.js
The the uuid
package is not bundled in the lambda.js
. It is expected in the runtime as a Lambda Layer.
copyFiles?β
Type : FunctionBundleCopyFilesProps[]
, defaults to []
This allows you to specify a list of files that you want copied to the Lambda function package. Each item in the list contains a FunctionBundleCopyFilesProps
that includes the path in your local computer and the destination path in the Lambda function.
For example:
[
{ from: "frontend/public", to: "frontend" },
{ from: "templates", to: "html_templates" },
],
commandHooks?β
Type : cdk.aws-lambda-nodejs.ICommandHooks
, defaults to undefined
Configure a set commands to run during the bundling process. Takes a function for a given hook. For example:
{
beforeBundling: (inputDir, outputDir) => {
return [ "echo beforeBundling" ];
},
beforeInstall: (inputDir, outputDir) => {
return [ "echo beforeInstall" ];
},
afterBundling: (inputDir, outputDir) => {
return [ "echo afterBundling" ];
},
}
Read more over on the CDK docs.
format?β
Type : "esm" | "cjs", defaults to cjs
Controls the bundle format. To use ES Modules, set this as esm
. Defaults to cjs
or CommonJS.
{
format: "esm"
}
minify?β
Type : boolean, defaults to true
Controls whether output is minified.
{
minify: false
}
esbuildConfig?β
Type : FunctionBundleEsbuildConfig
, defaults to no custom esbuild config
This allows you to customize esbuild config.
FunctionBundlePythonPropsβ
installCommands?β
Type : string[]
, defaults to undefined
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:
[
'export VARNAME="my value"',
'pip install --index-url https://domain.com/pypi/myprivatemodule/simple/ --extra-index-url https://pypi.org/simple',
]
FunctionBundleCopyFilesPropsβ
fromβ
Type : string
The path to the file or folder relative to the srcPath
.
toβ
Type : string
The path in the Lambda function package the file or folder to be copied to.
FunctionBundleEsbuildConfigβ
define?β
Type : { [key: string]: string }
Configures Esbuild Define option.
keepNames?β
Type : boolean
Configures Esbuild Keep names option.
plugins?β
Type : string
, defaults to no custom esbuild config
Path to a file that returns a an array of esbuild plugins.
For example:
{
esbuildConfig: {
plugins: "config/esbuild.js"
},
}
Where config/esbuild.js
looks something like this:
const { esbuildDecorators } = require("@anatine/esbuild-decorators");
module.exports = [
esbuildDecorators(),
];
note
Only the "plugins" option in the esbuild config file is currently supported.