serverless
serverless copied to clipboard
S3 existing bucket additional lambda nodejs runtime is deprecated by AWS
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
Duplicate https://github.com/serverless/serverless/issues/11400
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;
Hi @all
Is there an option to control the node version of the lambda created using the node version we specify in the serverless?
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
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
@mokamoto12 @LaszloDev any chance you can publish that plugin officially?
@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 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
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.
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?
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 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?
@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'
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;
thank you all, @martinash78 snippet worked all i had to change was the key
to CustomDashresourceDashapigwDashcwDashroleLambdaFunction
and nodejs16.x
to nodejs12.x
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 🤷
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?
Adding this to serverless.yml is working in serverless v3.x for me:
resources:
- extensions:
CustomDashresourceDashexistingDashs3LambdaFunction:
Properties:
Runtime: nodejs20.x
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!