serverless icon indicating copy to clipboard operation
serverless copied to clipboard

S3 existing bucket additional lambda nodejs runtime is deprecated by AWS

Open ethan-fitsense opened this issue 2 years ago • 20 comments

Is there an existing issue for this?

  • [X] I have searched existing issues, it hasn't been reported yet

Use case description

Based on the doc: https://www.serverless.com/framework/docs/providers/aws/events/s3#using-existing-buckets, when using existing S3 bucket, an additional lambda will be created. However its runtime is Nodejs 12, and cannot be specified. AWS has deprecated nodejs 12 runtime, so it's going to be a problem.

Proposed solution (optional)

No response

ethan-fitsense avatar Aug 15 '22 06:08 ethan-fitsense

Duplicate https://github.com/serverless/serverless/issues/11400

icholy avatar Oct 03 '22 21:10 icholy

We are using v1 and have addressed this issue by adding the following Service local plugin. Fortunately, the lambda source code seems to work on node14.x. In any case, it looks like we should update to v3...

path: .serverless_plugins/lambda-update-deprecated-runtime/index.js

'use strict';

class LambdaUpdateDeprecatedRuntime {

  constructor(serverless, options) {
    this.serverless = serverless;
    this.options = options;
    this.provider = 'aws';

    this.hooks = {
      'after:deploy:compileEvents': this.afterCompileEvents.bind(this),
    };
  }

  afterCompileEvents() {
    let key = 'CustomDashresourceDashexistingDashs3LambdaFunction'
    let resources = this.serverless.service.provider.compiledCloudFormationTemplate.Resources;
    if (key in resources && resources[key].Properties.Runtime == 'nodejs12.x') {
      this.serverless.cli.log("Fixed CustomDashresourceDashexistingDashs3LambdaFunction runtime from `nodejs12.x` to `nodejs14.x`");
      resources[key].Properties.Runtime = 'nodejs14.x'
    }
  }
}

module.exports = LambdaUpdateDeprecatedRuntime;

mokamoto12 avatar Nov 01 '22 04:11 mokamoto12

Hi @all

Is there an option to control the node version of the lambda created using the node version we specify in the serverless?

tharivignesh avatar Aug 10 '23 11:08 tharivignesh

Is there an option to control the node version of the lambda created using the node version we specify in the serverless?

The LambdaUpdateDeprecatedRuntime service plugin by mokamoto12 does exactly this, and it fixed the issues for me.

Just copy paste it in your project source code and reference it from serverless.yml file

plugins:
  - ./.serverless_plugins/lambda-update-deprecated-runtime.js

danmana avatar Aug 14 '23 12:08 danmana

Thanks a lot @mokamoto12!

We are using v1 and have addressed this issue by adding the following Service local plugin. Fortunately, the lambda source code seems to work on node14.x. In any case, it looks like we should update to v3...

path: .serverless_plugins/lambda-update-deprecated-runtime/index.js

For everyone who still runs into issues with autogenerated Lambdas being v12, the following modification will change any 'node v12' lambda automatically to v14 (or v16)

'use strict'

class LambdaUpdateDeprecatedRuntime {
  constructor(serverless, options) {
    this.serverless = serverless
    this.options = options
    this.provider = 'aws'

    this.hooks = {
      'after:deploy:compileEvents': this.afterCompileEvents.bind(this),
    }
  }

  afterCompileEvents() {
    let resources = this.serverless.service.provider
      .compiledCloudFormationTemplate.Resources

    Object.keys(resources).forEach((resourceKey) => {
      if (resources[resourceKey].Properties.Runtime == 'nodejs12.x') {
        resources[resourceKey].Properties.Runtime = 'nodejs14.x' // or: 'nodejs16.x'
      }
    })
  }
}

module.exports = LambdaUpdateDeprecatedRuntime

LaszloDev avatar Nov 15 '23 17:11 LaszloDev

@mokamoto12 @LaszloDev any chance you can publish that plugin officially?

bitsofinfo avatar Dec 19 '23 19:12 bitsofinfo

@mokamoto12 @LaszloDev any chance you can publish that plugin officially?

Do you need help installing/using it? I'm not sure if it makes sense to publish it. You can reach out for help to me on X @laszloschuerg

LaszloDev avatar Dec 19 '23 20:12 LaszloDev

@LaszloDev Hi, any chance you'd know how to make this work for Serverless v3 please? I've been trying to get it to work but no luck so far

MarcEspiard avatar Dec 21 '23 23:12 MarcEspiard

nodejs16.x is nearing end of support on Lambda. The same issue happens when setting the runtime to nodejs20.x: in that case the "custom-resource-existing-s3" function will still use nodejs16.x.

snabela avatar Dec 29 '23 09:12 snabela

what @snabela wrote. From the email from AWS: We are ending support for Node.js 16 in Lambda on June 12, 2024. We recommend that you upgrade your existing Node.js 16 functions to Node.js 20 before June 12, 2024.

We're using 18.x right now, so it seems like it's just hardcoded to v16? Why does the S3 shizzle use a different node version than the provider: runtime: nodejs18.x setting in the first place?

tom2strobl avatar Jan 15 '24 08:01 tom2strobl

I've to update my lambda to node v20 as I've update aws sdk from v2 to v3 I've added the file as indicated by @laszloschuerg and added the plugin but for me during deployment cloud formation is failing with exception.

changes in serverless.yml

plugins:
  - serverless-domain-manager
  - serverless-plugin-aws-alerts
  - serverless-step-functions
  - serverless-kms-grants
  - ./serverless-plugins/lambda-update-deprecated-runtime.js
  - serverless-newrelic-lambda-layers

exception is

Error:
CREATE_FAILED: CustomDashresourceDashexistingDashs3LambdaFunction (AWS::Lambda::Function)
Resource handler returned message: "The runtime parameter of nodejs14.x is no longer supported for creating or updating AWS Lambda functions. We recommend you use the new runtime (nodejs20.x) while creating or updating functions. (Service: Lambda, Status Code: 400, Request ID: 793e3941-3991-479b-aa7b-41c81dfa24f9)" (RequestToken: 806c4a93-b669-b4be-e5ce-e8cc14fad21b, HandlerErrorCode: InvalidRequest)

I urgently need this lambda to use node20.x

noumanbhatti avatar Feb 22 '24 05:02 noumanbhatti

@noumanbhatti I happened to see a comment, but are you still having trouble? Perhaps modifying the following line in ./serverless-plugins/lambda-update-deprecated-runtime.js:

resources[key].Properties.Runtime = 'nodejs14.x'

to:

resources[key].Properties.Runtime = 'nodejs20.x'

work properly?

mokamoto12 avatar Feb 27 '24 13:02 mokamoto12

@noumanbhatti I happened to see a comment, but are you still having trouble? Perhaps modifying the following line in ./serverless-plugins/lambda-update-deprecated-runtime.js:

resources[key].Properties.Runtime = 'nodejs14.x'

to:

resources[key].Properties.Runtime = 'nodejs20.x'

work properly?

In my case I also used similar approach that worked for me without any issue (I updated to node20 from node16 simply overriding in Resources runtime value for this function (as it was already existing and previously created by sls) # override sls managed custom existingS3lambda runtime CustomDashresourceDashexistingDashs3LambdaFunction: Type: AWS::Lambda::Function Properties: Runtime: 'nodejs20.x'

Sunac avatar Apr 08 '24 14:04 Sunac

Using sls version 3.38.0 a slight change to the script above seems to be successfully upgrading from 16 to 20.

'use strict';

class LambdaUpdateDeprecatedRuntime {

    constructor(serverless, options) {
        this.serverless = serverless;
        this.options = options;
        this.provider = 'aws';

        this.hooks = {
            'after:package:compileEvents': this.afterCompileEvents.bind(this),
        };
    }

    afterCompileEvents() {
        let key = 'CustomDashresourceDashexistingDashs3LambdaFunction'
        let resources = this.serverless.service.provider.compiledCloudFormationTemplate.Resources;
        if (key in resources && resources[key].Properties.Runtime === 'nodejs16.x') {
            this.serverless.cli.log("Fixed CustomDashresourceDashexistingDashs3LambdaFunction runtime from `nodejs16.x` to `nodejs20.x`");
            resources[key].Properties.Runtime = 'nodejs20.x'
        }
    }
}

module.exports = LambdaUpdateDeprecatedRuntime;

martinash78 avatar Apr 11 '24 15:04 martinash78

thank you all, @martinash78 snippet worked all i had to change was the key to CustomDashresourceDashapigwDashcwDashroleLambdaFunction and nodejs16.x to nodejs12.x

iamtekeste avatar May 15 '24 03:05 iamtekeste

Thanks a lot @mokamoto12, the snipped worked. For whom the plugin does not run, I changed the hook from 'after:deploy:compileEvents': this.afterCompileEvents.bind(this) to 'before:deploy:deploy': () => this.afterCompileEvents(). Seems like the naming for the lifecycle events changed in serverless 🤷

rurouni-najeeb avatar May 27 '24 15:05 rurouni-najeeb

Hello!

I am running into the same issue here. However it appears the custom resource lambda that is auto-generated by the 'existing: true' flag on an S3 event is using AWS SDK v2 during its deployment step.

This means if you have it appropriately configured to be Node v20 like you all have figured out, on deployments this will fail in CloudFormation when it attempts to pull in 'aws-sdk'.

This is fine if it you don't plan on touching this event notification configuration, but the moment you do, or if you need to perform a fresh deployment, your deployment will fail.

I can't find any guidance from serverless related to this issue, it seems like our only options would be to somehow override that custom resource lambda with code that uses AWS SDK v3, or hope a new version of serverless v3 comes out that upgrades this.

What do you think?

georgesglynn avatar Jun 12 '24 16:06 georgesglynn

Adding this to serverless.yml is working in serverless v3.x for me:

resources:
  - extensions:
      CustomDashresourceDashexistingDashs3LambdaFunction:
        Properties:
          Runtime: nodejs20.x

tyingq avatar Jun 18 '24 16:06 tyingq

Hello!

I am running into the same issue here. However it appears the custom resource lambda that is auto-generated by the 'existing: true' flag on an S3 event is using AWS SDK v2 during its deployment step.

This means if you have it appropriately configured to be Node v20 like you all have figured out, on deployments this will fail in CloudFormation when it attempts to pull in 'aws-sdk'.

This is fine if it you don't plan on touching this event notification configuration, but the moment you do, or if you need to perform a fresh deployment, your deployment will fail.

I can't find any guidance from serverless related to this issue, it seems like our only options would be to somehow override that custom resource lambda with code that uses AWS SDK v3, or hope a new version of serverless v3 comes out that upgrades this.

What do you think?

Learned today that this was fixed in a later version of serverless very recently. Updating to serverless version 3.39.0 has resolved this issue (you can see in the changelog that they converted this custom resource code to AWS SDK v3!) Woo!

georgesglynn avatar Jun 18 '24 17:06 georgesglynn