Skip to content

(aws-cdk-lib): Internal Lambda Handler Framework #27303

@MrArnoldPalmer

Description

@MrArnoldPalmer

Describe the feature

Design and implement a series of constructs, and potentially build tools, to standardize how we build and vend lambda handlers within the aws-cdk.

Use Case

aws-cdk-lib, and the alpha modules, contain a number of lambda handlers for various cases. Most of these are custom resource handlers that provision or mutate resources during cloudformation deploys, but some of them are handlers designed for various runtime integrations, for example, triggering an aws sdk call on an event bridge event.

All of these lambda handlers are deployed into user's accounts when they instantiate any of the constructs that rely on their specific functionality. Even though these handlers are deployed to customer accounts, how they perform their various responsibilities are implementation details that ideally, a user does not need to know about. However, there are certain details, mainly the runtime version that these lambda functions use, that should be updated as soon as possible to avoid customers having to deploy lambdas with out of date runtime versions into their own accounts. In order to be able to perform these upgrades more quickly and reliably, we should centralize how these handlers are instantiated and packaged.

Proposed Solution

Create a series of internal constructs, used only within the aws-cdk libraries, for vending lambda handlers that are deployed to user accounts that allow enforcing best practices. This would include a centralized definition of the "default runtime version". Ideally this default runtime version should be the latest version of NodeJS available across aws regions.

I see these constructs looking something like a CdkHandler construct, that essentially wraps lambda.Code, but has a few niceties built in. Mainly, it should handle building and packaging all of our lambda handlers including all of their dependencies. This will establish a standard for sharing code across handlers which today requires restructuring code if shared functionality is required. Also, all dependencies should be included by default, with only certain handlers excluding specific dependencies explicitly. Notably, AwsCustomResource and other handlers that can't list their dependencies very easily (because it's the entire list of @aws-sdk/* modules, or can't bundle them all because of size limitations. Additionally this construct should accept a compatibleRuntimes property that allows the explicit opting in of new runtime versions for each one. CdkHandler would also have a statically defined constant property defaultRuntime, which is used to find the intersection of the latest available default runtime, and the compatible runtimes listed for each handler. If a handler does not have the default runtime in its compatible list, it would use the latest defined in that list. Also, the build should break if the latest version in a handlers compatible runtimes list is marked as deprecated.

Additionally, some basic wrappers around lambda.SingletonFunction and lambda.Function may be required to accept this type as input, or we may be able to just make CdkHandler implement lambda.Code.

Example:

const myHandlerCode = new cdk.CdkHandler(this, 'InternalLambdaHandler', {
  compatibleRuntimes: [lambda.Runtime.NODEJS_16_X, lambda.Runtime.NODEJS_18_X],
  entrypoint: path.resolve(__dirname, 'path-to-my-handler.ts'),
});

Additionally, we should add linting to prohibit the usage of types such as lambda.Code, lambda.Runtime, and aws-cdk-lib.CustomResourceProviderRuntime` directly. This will force authors to use our standard tools for vending lambda handler code within the CDK.

Other Information

No response

Acknowledgements

  • I may be able to implement this feature request
  • This feature might incur a breaking change

CDK version used

2.97.0

Environment details (OS name and version, etc.)

MacOs

Metadata

Metadata

Assignees

No one assigned

    Labels

    effort/mediumMedium work item – several days of effortfeature-requestA feature should be added or improved.p1

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions