-
Notifications
You must be signed in to change notification settings - Fork 4.5k
(aws-cdk-lib): Internal Lambda Handler Framework #27303
Description
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