aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.47k stars 3.83k forks source link

Lambda: Support SnapStart #23153

Closed bpenwell-amazon closed 1 year ago

bpenwell-amazon commented 1 year ago

Describe the feature

https://techcrunch.com/2022/11/28/aws-makes-lambda-cold-start-latency-a-thing-of-the-past-with-snapstart/

Currently SnapStart is only supported with existing lambdas, and currently there is no mention in the AWS Docs of this feature being supported.

Use Case

As an internal team to Amazon, we want to use SnapStart to eliminate coldstart on our Java lambdas.

Proposed Solution

Put a boolean into the Lambda construct to enable SnapStart.

Other Information

No response

Acknowledgements

CDK version used

Any

Environment details (OS name and version, etc.)

Any

pahud commented 1 year ago

It is possible for AWS CDK to enable this feature starting from v2.53.0.

Before we have L2 support, you should be able to enable this feature like this:

    const fn = new lambda.Function(this, 'Func', {
      runtime: lambda.Runtime.JAVA_11,
      handler: 'example.Handler',
      code: lambda.Code.fromAsset(path.join(__dirname, '../../lambda/example.jar')),
      memorySize: 256,

    });

    (fn.node.defaultChild as lambda.CfnFunction).addPropertyOverride('SnapStart', {
      ApplyOn: 'PublishedVersions',
    });

    // publish a version
    new lambda.Version(this, 'MyVersion', { 
      lambda: fn,
    });

I believe it is not difficult to add this property for the L2 construct. Any community PRs would be highly welcome!

bpenwell-amazon commented 1 year ago

Thank you for this. I've noted this down, and we will unblock ourselves from experimenting with this new, exciting feature!

I'd still like to leave this feature request open so customer-facing CDK code can be written to improve the dev experience on enabling this feature.

DeerajTheepshi commented 1 year ago

@pahud I have tried to provide a L2 construct support for the same. Could you please have a look at it whenever possible ?

pahud commented 1 year ago

Yes #23196 LGTM now! But we need the core team maintainer to take another look.

adamsar commented 1 year ago

Is there any update on this? Looks like it's about to merge - still waiting on that maintainer to review it?

madhead commented 1 year ago

It is possible for AWS CDK to enable this feature starting from v2.53.0.

Before we have L2 support, you should be able to enable this feature like this:

    const fn = new lambda.Function(this, 'Func', {
      runtime: lambda.Runtime.JAVA_11,
      handler: 'example.Handler',
      code: lambda.Code.fromAsset(path.join(__dirname, '../../lambda/example.jar')),
      memorySize: 256,

    });

    (fn.node.defaultChild as lambda.CfnFunction).addPropertyOverride('SnapStart', {
      ApplyOn: 'PublishedVersions',
    });

    // publish a version
    new lambda.Version(this, 'MyVersion', { 
      lambda: fn,
    });

I believe it is not difficult to add this property for the L2 construct. Any community PRs would be highly welcome!

I'd like to add that if you use API Gateway it's not enough. You have to ensure that API Gateway is configured to use this published version, instead of the default $LATEST.

Here is how I did that, with the help of the original advice:

const fn = new lambda.Function(this, 'fn', {
    // …
});

(fn.node.defaultChild as lambda.CfnFunction).snapStart = {
    applyOn: 'PublishedVersions'
};

const api = new apigateway.RestApi(this, 'api', {
    // …
});

api.root
    .addResource('resource')
    // .addMethod('POST', new apigateway.LambdaIntegration(fn)); // Not like this! But like this 👇
    .addMethod('POST', new apigateway.LambdaIntegration(fn.currentVersion));

Although I hope that this issue will be closed in one of the upcoming releases, but ensuring the correct version being used in other places is important anyway. Otherwise, the magic of SnapStart just won't work.

humanzz commented 1 year ago

The discussion - on the now closed https://github.com/aws/aws-cdk/pull/23196 so I cannot comment there - is quite interesting and I saw that it ended with needing to have more information from the Lambda team to ensure getting the right interface that aligns with where this feature will be going. With some previous interactions with the Lambda team, I got the impression that

  1. The feature will be expanded to cover additional runtimes (not just Java 11) though not all
  2. The feature might be expanded so that it's possible to enable it on the function level, not just versions
  3. Limitations around XRay and Graviton are being worked on

All that, makes me learning towards - at least ultimately - snapStart being a constructor prop with enum-like values to match CloudFormation's value of None | PublishedVersions. With Enum-like SnapStart class, maybe it can be modelled in such a way that exposes constants e.g. None and ApplyOnPublishedVersions and those instances should have properties that control the checks that the function makes... and a factory method to allow creating new values overriding the checks i.e. those SnapStart instances can declare supported runtimes, supported xray configs, supported architectures, etc.

I'm pro a construct prop, as having multiple functions, I tend to have a constant with a set of props with base settings for all functions I use in my CDK app e.g. const baseFunctionProps = {...}; which I can later use across all my functions e.g. new lambda.Function(scope, 'Function', {...baseFunctionProps, <more props related to each function>})

DeerajTheepshi commented 1 year ago

@humanzz , thanks for the updates. From the 3 points you had mentioned, I would align towards a constructor prop as well. Should we re-open the CR with modifications ? Do we know that if there are any L2 construct support planned for snapStart ?

johncurrier commented 1 year ago

I've seen examples of how to tie a the most recently deployed version of a lambda / alias to API Gateway, but I still haven't figured out how to do that when running under a load balancer.

During deployment the load balancer seems to invoke a specific version of the lambda, but when it gets hit externally it always invokes $LATEST. As a result each cold start goes through the INIT_START phase, resulting in excessive startup times.

humanzz commented 1 year ago

X-ray support has just been released for SnapStart https://aws.amazon.com/blogs/compute/debugging-snapstart-enabled-lambda-functions-made-easy-with-aws-x-ray/

Are there any updates on when L2 construct support might be added?

github-actions[bot] commented 1 year ago

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.