From f23c54ca00d24a77beb139f8de4044a687d7a1b3 Mon Sep 17 00:00:00 2001 From: Ava Silver Date: Fri, 21 Aug 2026 16:50:19 -0400 Subject: [PATCH 1/4] reconcile lambda runtime support --- serverless/src/lambda/layer-catalog.ts | 24 -------- serverless/test/index.spec.ts | 2 +- serverless/test/lambda/env.spec.ts | 48 ++++++++-------- serverless/test/lambda/lambda.spec.ts | 6 +- serverless/test/lambda/layer.spec.ts | 76 ++++++++++++++------------ 5 files changed, 68 insertions(+), 88 deletions(-) diff --git a/serverless/src/lambda/layer-catalog.ts b/serverless/src/lambda/layer-catalog.ts index a925aadd..c17db8a5 100644 --- a/serverless/src/lambda/layer-catalog.ts +++ b/serverless/src/lambda/layer-catalog.ts @@ -54,18 +54,6 @@ export const lambdaLayerCatalog = { runtimeType: "JAVA", tracerLayerNames: { x86_64: "dd-trace-java", arm64: "dd-trace-java" }, }, - "nodejs12.x": { - runtimeType: "NODE", - tracerLayerNames: { x86_64: "Datadog-Node12-x", arm64: "Datadog-Node12-x" }, - }, - "nodejs14.x": { - runtimeType: "NODE", - tracerLayerNames: { x86_64: "Datadog-Node14-x", arm64: "Datadog-Node14-x" }, - }, - "nodejs16.x": { - runtimeType: "NODE", - tracerLayerNames: { x86_64: "Datadog-Node16-x", arm64: "Datadog-Node16-x" }, - }, "nodejs18.x": { runtimeType: "NODE", tracerLayerNames: { x86_64: "Datadog-Node18-x", arm64: "Datadog-Node18-x" }, @@ -90,18 +78,6 @@ export const lambdaLayerCatalog = { runtimeType: "CUSTOM", tracerLayerNames: { x86_64: null, arm64: null }, }, - "python2.7": { - runtimeType: "PYTHON", - tracerLayerNames: { x86_64: "Datadog-Python27", arm64: null }, - }, - "python3.6": { - runtimeType: "PYTHON", - tracerLayerNames: { x86_64: "Datadog-Python36", arm64: null }, - }, - "python3.7": { - runtimeType: "PYTHON", - tracerLayerNames: { x86_64: "Datadog-Python37", arm64: null }, - }, "python3.8": { runtimeType: "PYTHON", tracerLayerNames: { x86_64: "Datadog-Python38", arm64: "Datadog-Python38-ARM" }, diff --git a/serverless/test/index.spec.ts b/serverless/test/index.spec.ts index 4def0e4e..ad90e441 100644 --- a/serverless/test/index.spec.ts +++ b/serverless/test/index.spec.ts @@ -47,7 +47,7 @@ export function mockInputEvent( Role: { "Fn::GetAtt": ["HelloWorldFunctionRole", "Arn"], }, - Runtime: "nodejs12.x", + Runtime: "nodejs18.x", }, }, }, diff --git a/serverless/test/lambda/env.spec.ts b/serverless/test/lambda/env.spec.ts index 0a300643..990e5e7d 100644 --- a/serverless/test/lambda/env.spec.ts +++ b/serverless/test/lambda/env.spec.ts @@ -162,13 +162,13 @@ describe("setEnvConfiguration", () => { const lambda: LambdaFunction = { properties: { Handler: "app.handler", - Runtime: "python2.7", + Runtime: "python3.8", Role: "role-arn", Code: {}, }, key: "FunctionKey", runtimeType: RuntimeType.PYTHON, - runtime: "python2.7", + runtime: "python3.8", architecture: "x86_64", architectureType: ArchitectureType.x86_64, }; @@ -204,13 +204,13 @@ describe("setEnvConfiguration", () => { const lambda: LambdaFunction = { properties: { Handler: "app.handler", - Runtime: "python2.7", + Runtime: "python3.8", Role: "role-arn", Code: {}, }, key: "FunctionKey", runtimeType: RuntimeType.PYTHON, - runtime: "python2.7", + runtime: "python3.8", architecture: "x86_64", architectureType: ArchitectureType.x86_64, }; @@ -244,13 +244,13 @@ describe("setEnvConfiguration", () => { const lambda: LambdaFunction = { properties: { Handler: "app.handler", - Runtime: "python2.7", + Runtime: "python3.8", Role: "role-arn", Code: {}, }, key: "FunctionKey", runtimeType: RuntimeType.PYTHON, - runtime: "python2.7", + runtime: "python3.8", architecture: "x86_64", architectureType: ArchitectureType.x86_64, }; @@ -318,13 +318,13 @@ describe("setEnvConfiguration", () => { const lambda: LambdaFunction = { properties: { Handler: "app.handler", - Runtime: "python2.7", + Runtime: "python3.8", Role: "role-arn", Code: {}, }, key: "FunctionKey", runtimeType: RuntimeType.PYTHON, - runtime: "python2.7", + runtime: "python3.8", architecture: "x86_64", architectureType: ArchitectureType.x86_64, }; @@ -405,14 +405,14 @@ describe("setEnvConfiguration", () => { const lambda: LambdaFunction = { properties: { Handler: "app.handler", - Runtime: "python2.7", + Runtime: "python3.8", Role: "role-arn", Code: {}, Environment: { Variables: originalEnvVars }, }, key: "FunctionKey", runtimeType: RuntimeType.PYTHON, - runtime: "python2.7", + runtime: "python3.8", architecture: "x86_64", architectureType: ArchitectureType.x86_64, }; @@ -453,13 +453,13 @@ describe("setEnvConfiguration", () => { const lambda: LambdaFunction = { properties: { Handler: "app.handler", - Runtime: "python2.7", + Runtime: "python3.8", Role: "role-arn", Code: {}, }, key: "FunctionKey", runtimeType: RuntimeType.PYTHON, - runtime: "python2.7", + runtime: "python3.8", architecture: "x86_64", architectureType: ArchitectureType.x86_64, }; @@ -497,13 +497,13 @@ describe("setEnvConfiguration", () => { const lambda: LambdaFunction = { properties: { Handler: "app.handler", - Runtime: "python2.7", + Runtime: "python3.8", Role: "role-arn", Code: {}, }, key: "FunctionKey", runtimeType: RuntimeType.PYTHON, - runtime: "python2.7", + runtime: "python3.8", architecture: "x86_64", architectureType: ArchitectureType.x86_64, }; @@ -542,13 +542,13 @@ describe("setEnvConfiguration", () => { const lambda: LambdaFunction = { properties: { Handler: "app.handler", - Runtime: "python2.7", + Runtime: "python3.8", Role: "role-arn", Code: {}, }, key: "FunctionKey", runtimeType: RuntimeType.PYTHON, - runtime: "python2.7", + runtime: "python3.8", architecture: "x86_64", architectureType: ArchitectureType.x86_64, }; @@ -582,13 +582,13 @@ describe("setEnvConfiguration", () => { const lambda: LambdaFunction = { properties: { Handler: "app.handler", - Runtime: "python2.7", + Runtime: "python3.8", Role: "role-arn", Code: {}, }, key: "FunctionKey", runtimeType: RuntimeType.PYTHON, - runtime: "python2.7", + runtime: "python3.8", architecture: "x86_64", architectureType: ArchitectureType.x86_64, }; @@ -622,13 +622,13 @@ describe("setEnvConfiguration", () => { const lambda: LambdaFunction = { properties: { Handler: "app.handler", - Runtime: "python2.7", + Runtime: "python3.8", Role: "role-arn", Code: {}, }, key: "FunctionKey", runtimeType: RuntimeType.PYTHON, - runtime: "python2.7", + runtime: "python3.8", architecture: "x86_64", architectureType: ArchitectureType.x86_64, }; @@ -695,13 +695,13 @@ describe("setEnvConfiguration", () => { properties: { FunctionName: "my-function", Handler: "app.handler", - Runtime: "nodejs12.x", + Runtime: "nodejs18.x", Role: "role-arn", Code: {}, }, key: "FunctionKey", runtimeType: RuntimeType.NODE, - runtime: "nodejs12.x", + runtime: "nodejs18.x", architecture: "x86_64", architectureType: ArchitectureType.x86_64, }; @@ -776,13 +776,13 @@ describe("setEnvConfiguration", () => { properties: { FunctionName: "my-function", Handler: "app.handler", - Runtime: "nodejs12.x", + Runtime: "nodejs18.x", Role: "role-arn", Code: {}, }, key: "FunctionKey", runtimeType: RuntimeType.NODE, - runtime: "nodejs12.x", + runtime: "nodejs18.x", architecture: "x86_64", architectureType: ArchitectureType.x86_64, }; diff --git a/serverless/test/lambda/lambda.spec.ts b/serverless/test/lambda/lambda.spec.ts index 8f709cb3..6da8c4ad 100644 --- a/serverless/test/lambda/lambda.spec.ts +++ b/serverless/test/lambda/lambda.spec.ts @@ -43,9 +43,9 @@ describe("Lambda", () => { const output = await handler(inputEvent, {}); const lambdaProperties: FunctionProperties = output.fragment.Resources[LAMBDA_KEY].Properties; - // Mocked Lambda has runtime nodejs12.x, so layer name is Datadog-Node12-x, with provided version number (25) at end + // Mocked Lambda has runtime nodejs18.x, so layer name is Datadog-Node18-x, with provided version number (25) at end expect(lambdaProperties.Layers).toEqual([ - expect.stringMatching(/arn:aws:lambda:us-east-1:.*:layer:Datadog-Node12-x:25/), + expect.stringMatching(/arn:aws:lambda:us-east-1:.*:layer:Datadog-Node18-x:25/), ]); }); @@ -98,7 +98,7 @@ describe("Lambda", () => { const lambdaProperties: FunctionProperties = output.fragment.Resources[LAMBDA_KEY].Properties; expect(lambdaProperties.Layers).toEqual([ - expect.stringMatching(/arn:aws-us-gov:lambda:us-gov-east-1:002406178527:layer:Datadog-Node12-x:25/), + expect.stringMatching(/arn:aws-us-gov:lambda:us-gov-east-1:002406178527:layer:Datadog-Node18-x:25/), ]); }); diff --git a/serverless/test/lambda/layer.spec.ts b/serverless/test/lambda/layer.spec.ts index e9d200ec..f33dcce1 100644 --- a/serverless/test/lambda/layer.spec.ts +++ b/serverless/test/lambda/layer.spec.ts @@ -61,18 +61,12 @@ describe("findLambdas", () => { Java25Function: mockFunctionResource("java25", ["x86_64"]), Java8Function: mockFunctionResource("java8", ["x86_64"]), Java8al2Function: mockFunctionResource("java8.al2", ["x86_64"]), - Node12Function: mockFunctionResource("nodejs12.x", ["x86_64"]), - Node14Function: mockFunctionResource("nodejs14.x", ["x86_64"]), - Node16Function: mockFunctionResource("nodejs16.x", ["x86_64"]), Node18Function: mockFunctionResource("nodejs18.x", ["x86_64"]), Node20Function: mockFunctionResource("nodejs20.x", ["x86_64"]), Node22Function: mockFunctionResource("nodejs22.x", ["x86_64"]), Node24Function: mockFunctionResource("nodejs24.x", ["x86_64"]), ProvidedAl2Function: mockFunctionResource("provided.al2", ["x86_64"]), ProvidedAl2023Function: mockFunctionResource("provided.al2023", ["x86_64"]), - Python27Function: mockFunctionResource("python2.7", ["x86_64"]), - Python36Function: mockFunctionResource("python3.6", ["x86_64"]), - Python37Function: mockFunctionResource("python3.7", ["x86_64"]), Python38Function: mockFunctionResource("python3.8", ["x86_64"]), Python39Function: mockFunctionResource("python3.9", ["x86_64"]), Python310Function: mockFunctionResource("python3.10", ["x86_64"]), @@ -87,7 +81,7 @@ describe("findLambdas", () => { GoFunction: mockFunctionResource("go1.10", ["x86_64"]), RefFunction: mockFunctionResource({ Ref: "ValueRef" }, ["arm64"]), }; - const lambdas = findLambdas(resources, { ValueRef: "nodejs14.x" }); + const lambdas = findLambdas(resources, { ValueRef: "nodejs18.x" }); expect(lambdas).toEqual([ mockLambdaFunction("Dotnet6Function", "dotnet6", RuntimeType.DOTNET, "x86_64", ArchitectureType.x86_64), @@ -99,9 +93,6 @@ describe("findLambdas", () => { mockLambdaFunction("Java25Function", "java25", RuntimeType.JAVA, "x86_64", ArchitectureType.x86_64), mockLambdaFunction("Java8Function", "java8", RuntimeType.JAVA, "x86_64", ArchitectureType.x86_64), mockLambdaFunction("Java8al2Function", "java8.al2", RuntimeType.JAVA, "x86_64", ArchitectureType.x86_64), - mockLambdaFunction("Node12Function", "nodejs12.x", RuntimeType.NODE, "x86_64", ArchitectureType.x86_64), - mockLambdaFunction("Node14Function", "nodejs14.x", RuntimeType.NODE, "x86_64", ArchitectureType.x86_64), - mockLambdaFunction("Node16Function", "nodejs16.x", RuntimeType.NODE, "x86_64", ArchitectureType.x86_64), mockLambdaFunction("Node18Function", "nodejs18.x", RuntimeType.NODE, "x86_64", ArchitectureType.x86_64), mockLambdaFunction("Node20Function", "nodejs20.x", RuntimeType.NODE, "x86_64", ArchitectureType.x86_64), mockLambdaFunction("Node22Function", "nodejs22.x", RuntimeType.NODE, "x86_64", ArchitectureType.x86_64), @@ -114,9 +105,6 @@ describe("findLambdas", () => { "x86_64", ArchitectureType.x86_64, ), - mockLambdaFunction("Python27Function", "python2.7", RuntimeType.PYTHON, "x86_64", ArchitectureType.x86_64), - mockLambdaFunction("Python36Function", "python3.6", RuntimeType.PYTHON, "x86_64", ArchitectureType.x86_64), - mockLambdaFunction("Python37Function", "python3.7", RuntimeType.PYTHON, "x86_64", ArchitectureType.x86_64), mockLambdaFunction("Python38Function", "python3.8", RuntimeType.PYTHON, "x86_64", ArchitectureType.x86_64), mockLambdaFunction("Python39Function", "python3.9", RuntimeType.PYTHON, "x86_64", ArchitectureType.x86_64), mockLambdaFunction("Python310Function", "python3.10", RuntimeType.PYTHON, "x86_64", ArchitectureType.x86_64), @@ -129,12 +117,28 @@ describe("findLambdas", () => { mockLambdaFunction("Ruby34Function", "ruby3.4", RuntimeType.RUBY, "x86_64", ArchitectureType.x86_64), mockLambdaFunction("Ruby40Function", "ruby4.0", RuntimeType.RUBY, "x86_64", ArchitectureType.x86_64), mockLambdaFunction("GoFunction", "go1.10", RuntimeType.UNSUPPORTED, "x86_64", ArchitectureType.x86_64), - mockLambdaFunction("RefFunction", "nodejs14.x", RuntimeType.NODE, "arm64", ArchitectureType.ARM64, { + mockLambdaFunction("RefFunction", "nodejs18.x", RuntimeType.NODE, "arm64", ArchitectureType.ARM64, { Ref: "ValueRef", }), ]); }); + it("marks removed runtimes unsupported while preserving supported neighbors", () => { + const resources = { + RemovedNodeFunction: mockFunctionResource("nodejs16.x", ["x86_64"]), + SupportedNodeFunction: mockFunctionResource("nodejs18.x", ["x86_64"]), + RemovedPythonFunction: mockFunctionResource("python3.7", ["x86_64"]), + SupportedPythonFunction: mockFunctionResource("python3.8", ["x86_64"]), + }; + + expect(findLambdas(resources, {})).toEqual([ + mockLambdaFunction("RemovedNodeFunction", "nodejs16.x", RuntimeType.UNSUPPORTED, "x86_64"), + mockLambdaFunction("SupportedNodeFunction", "nodejs18.x", RuntimeType.NODE, "x86_64"), + mockLambdaFunction("RemovedPythonFunction", "python3.7", RuntimeType.UNSUPPORTED, "x86_64"), + mockLambdaFunction("SupportedPythonFunction", "python3.8", RuntimeType.PYTHON, "x86_64"), + ]); + }); + it("skips lambdas that are image based", () => { const resources = { Python39Function: mockFunctionResource("python3.9", ["x86_64"]), @@ -149,19 +153,19 @@ describe("findLambdas", () => { describe("applyLayers", () => { it("adds a layer array if none are present", () => { - const lambda = mockLambdaFunction("FunctionKey", "nodejs12.x", RuntimeType.NODE, "x86_64"); + const lambda = mockLambdaFunction("FunctionKey", "nodejs18.x", RuntimeType.NODE, "x86_64"); const region = "us-east-1"; const nodeLayerVersion = 25; const errors = applyLayers(region, [lambda], undefined, nodeLayerVersion); expect(errors.length).toEqual(0); expect(lambda.properties.Layers).toEqual([ - `arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:Datadog-Node12-x:${nodeLayerVersion}`, + `arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:Datadog-Node18-x:${nodeLayerVersion}`, ]); }); it("appends to the layer array if already present", () => { - const lambda = mockLambdaFunction("FunctionKey", "nodejs12.x", RuntimeType.NODE, "x86_64"); + const lambda = mockLambdaFunction("FunctionKey", "nodejs18.x", RuntimeType.NODE, "x86_64"); lambda.properties.Layers = ["node:2"]; const region = "us-east-1"; @@ -171,15 +175,15 @@ describe("applyLayers", () => { expect(errors.length).toEqual(0); expect(lambda.properties.Layers).toEqual([ "node:2", - `arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:Datadog-Node12-x:${nodeLayerVersion}`, + `arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:Datadog-Node18-x:${nodeLayerVersion}`, ]); }); it("doesn't add duplicate layers", () => { - const lambda = mockLambdaFunction("FunctionKey", "nodejs12.x", RuntimeType.NODE, "x86_64"); + const lambda = mockLambdaFunction("FunctionKey", "nodejs18.x", RuntimeType.NODE, "x86_64"); const region = "us-east-1"; const nodeLayerVersion = 25; - const layerArn = `arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:Datadog-Node12-x:${nodeLayerVersion}`; + const layerArn = `arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:Datadog-Node18-x:${nodeLayerVersion}`; lambda.properties.Layers = [layerArn]; const errors = applyLayers(region, [lambda], undefined, nodeLayerVersion); @@ -196,8 +200,8 @@ describe("applyLayers", () => { }); it("returns errors if layer versions are not provided for corresponding Lambda runtimes", () => { - const pythonLambda = mockLambdaFunction("PythonFunctionKey", "python2.7", RuntimeType.PYTHON, "x86_64"); - const nodeLambda = mockLambdaFunction("NodeFunctionKey", "nodejs12.x", RuntimeType.NODE, "x86_64"); + const pythonLambda = mockLambdaFunction("PythonFunctionKey", "python3.8", RuntimeType.PYTHON, "x86_64"); + const nodeLambda = mockLambdaFunction("NodeFunctionKey", "nodejs18.x", RuntimeType.NODE, "x86_64"); const errors = applyLayers("us-east-1", [pythonLambda, nodeLambda]); expect(errors).toEqual([ @@ -446,7 +450,7 @@ describe("getNewLayers", () => { describe("isGovCloud", () => { it("applies the GovCloud layer", () => { const pythonLambda = mockLambdaFunction("PythonFunctionKey", "python3.8", RuntimeType.PYTHON, "x86_64"); - const nodeLambda = mockLambdaFunction("NodeFunctionKey", "nodejs16.x", RuntimeType.NODE, "x86_64"); + const nodeLambda = mockLambdaFunction("NodeFunctionKey", "nodejs18.x", RuntimeType.NODE, "x86_64"); const errors = applyLayers("us-gov-east-1", [pythonLambda, nodeLambda], 21, 30); expect(errors.length).toEqual(0); @@ -454,25 +458,25 @@ describe("isGovCloud", () => { `arn:aws-us-gov:lambda:us-gov-east-1:${DD_GOV_ACCOUNT_ID}:layer:Datadog-Python38:21`, ]); expect(nodeLambda.properties.Layers).toEqual([ - `arn:aws-us-gov:lambda:us-gov-east-1:${DD_GOV_ACCOUNT_ID}:layer:Datadog-Node16-x:30`, + `arn:aws-us-gov:lambda:us-gov-east-1:${DD_GOV_ACCOUNT_ID}:layer:Datadog-Node18-x:30`, ]); }); }); describe("getLambdaLibraryLayerArn", () => { - it("gets the us-east-1 layer arn for the Datadog Node16 Lambda Library", () => { + it("gets the us-east-1 layer arn for the Datadog Node18 Lambda Library", () => { const region = "us-east-1"; const version = 22; - const runtime = "nodejs16.x"; + const runtime = "nodejs18.x"; const layerArn = getLambdaLibraryLayerArn(region, version, runtime, "x86_64"); - expect(layerArn).toEqual(`arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:Datadog-Node16-x:${version}`); + expect(layerArn).toEqual(`arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:Datadog-Node18-x:${version}`); }); - it("gets the us-east-1 layer arn for the Datadog Python36 Lambda Library", () => { + it("gets the us-east-1 layer arn for the Datadog Python38 Lambda Library", () => { const region = "us-east-1"; const version = 22; - const runtime = "python3.6"; + const runtime = "python3.8"; const layerArn = getLambdaLibraryLayerArn(region, version, runtime, "x86_64"); - expect(layerArn).toEqual(`arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:Datadog-Python36:${version}`); + expect(layerArn).toEqual(`arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:Datadog-Python38:${version}`); }); it("gets the us-east-1 ARM layer arn for the Datadog Python38 Lambda Library", () => { const region = "us-east-1"; @@ -481,12 +485,12 @@ describe("getLambdaLibraryLayerArn", () => { const layerArn = getLambdaLibraryLayerArn(region, version, runtime, "arm64"); expect(layerArn).toEqual(`arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:Datadog-Python38-ARM:${version}`); }); - it("gets the us-gov-east-1 layer arn for the Datadog Python36 Lambda Library", () => { + it("gets the us-gov-east-1 layer arn for the Datadog Python38 Lambda Library", () => { const region = "us-gov-east-1"; const version = 22; - const runtime = "python3.6"; + const runtime = "python3.8"; const layerArn = getLambdaLibraryLayerArn(region, version, runtime, "x86_64"); - expect(layerArn).toEqual(`arn:aws-us-gov:lambda:${region}:${DD_GOV_ACCOUNT_ID}:layer:Datadog-Python36:${version}`); + expect(layerArn).toEqual(`arn:aws-us-gov:lambda:${region}:${DD_GOV_ACCOUNT_ID}:layer:Datadog-Python38:${version}`); }); it("gets the us-gov-east-1 ARM layer arn for the Datadog Python39 Lambda Library", () => { const region = "us-gov-east-1"; @@ -497,12 +501,12 @@ describe("getLambdaLibraryLayerArn", () => { `arn:aws-us-gov:lambda:${region}:${DD_GOV_ACCOUNT_ID}:layer:Datadog-Python39-ARM:${version}`, ); }); - it("gets the us-gov-east-1 layer arn for the Datadog Node16 Lambda Library", () => { + it("gets the us-gov-east-1 layer arn for the Datadog Node18 Lambda Library", () => { const region = "us-gov-east-1"; const version = 22; - const runtime = "nodejs16.x"; + const runtime = "nodejs18.x"; const layerArn = getLambdaLibraryLayerArn(region, version, runtime, "x86_64"); - expect(layerArn).toEqual(`arn:aws-us-gov:lambda:${region}:${DD_GOV_ACCOUNT_ID}:layer:Datadog-Node16-x:${version}`); + expect(layerArn).toEqual(`arn:aws-us-gov:lambda:${region}:${DD_GOV_ACCOUNT_ID}:layer:Datadog-Node18-x:${version}`); }); }); From ee2520f9d9e95d09ceca5e80ce50230ae7015ed2 Mon Sep 17 00:00:00 2001 From: Ava Silver Date: Tue, 25 Aug 2026 13:56:43 -0400 Subject: [PATCH 2/4] restore node 16 --- serverless/src/lambda/layer-catalog.ts | 4 ++++ serverless/test/lambda/layer.spec.ts | 22 +++------------------- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/serverless/src/lambda/layer-catalog.ts b/serverless/src/lambda/layer-catalog.ts index c17db8a5..751c429c 100644 --- a/serverless/src/lambda/layer-catalog.ts +++ b/serverless/src/lambda/layer-catalog.ts @@ -54,6 +54,10 @@ export const lambdaLayerCatalog = { runtimeType: "JAVA", tracerLayerNames: { x86_64: "dd-trace-java", arm64: "dd-trace-java" }, }, + "nodejs16.x": { + runtimeType: "NODE", + tracerLayerNames: { x86_64: "Datadog-Node16-x", arm64: "Datadog-Node16-x" }, + }, "nodejs18.x": { runtimeType: "NODE", tracerLayerNames: { x86_64: "Datadog-Node18-x", arm64: "Datadog-Node18-x" }, diff --git a/serverless/test/lambda/layer.spec.ts b/serverless/test/lambda/layer.spec.ts index f33dcce1..78eb4317 100644 --- a/serverless/test/lambda/layer.spec.ts +++ b/serverless/test/lambda/layer.spec.ts @@ -123,22 +123,6 @@ describe("findLambdas", () => { ]); }); - it("marks removed runtimes unsupported while preserving supported neighbors", () => { - const resources = { - RemovedNodeFunction: mockFunctionResource("nodejs16.x", ["x86_64"]), - SupportedNodeFunction: mockFunctionResource("nodejs18.x", ["x86_64"]), - RemovedPythonFunction: mockFunctionResource("python3.7", ["x86_64"]), - SupportedPythonFunction: mockFunctionResource("python3.8", ["x86_64"]), - }; - - expect(findLambdas(resources, {})).toEqual([ - mockLambdaFunction("RemovedNodeFunction", "nodejs16.x", RuntimeType.UNSUPPORTED, "x86_64"), - mockLambdaFunction("SupportedNodeFunction", "nodejs18.x", RuntimeType.NODE, "x86_64"), - mockLambdaFunction("RemovedPythonFunction", "python3.7", RuntimeType.UNSUPPORTED, "x86_64"), - mockLambdaFunction("SupportedPythonFunction", "python3.8", RuntimeType.PYTHON, "x86_64"), - ]); - }); - it("skips lambdas that are image based", () => { const resources = { Python39Function: mockFunctionResource("python3.9", ["x86_64"]), @@ -501,12 +485,12 @@ describe("getLambdaLibraryLayerArn", () => { `arn:aws-us-gov:lambda:${region}:${DD_GOV_ACCOUNT_ID}:layer:Datadog-Python39-ARM:${version}`, ); }); - it("gets the us-gov-east-1 layer arn for the Datadog Node18 Lambda Library", () => { + it("gets the us-gov-east-1 layer arn for the Datadog Node16 Lambda Library", () => { const region = "us-gov-east-1"; const version = 22; - const runtime = "nodejs18.x"; + const runtime = "nodejs16.x"; const layerArn = getLambdaLibraryLayerArn(region, version, runtime, "x86_64"); - expect(layerArn).toEqual(`arn:aws-us-gov:lambda:${region}:${DD_GOV_ACCOUNT_ID}:layer:Datadog-Node18-x:${version}`); + expect(layerArn).toEqual(`arn:aws-us-gov:lambda:${region}:${DD_GOV_ACCOUNT_ID}:layer:Datadog-Node16-x:${version}`); }); }); From 5f02e100da260e15c560444cd34c19aef3fa7cf7 Mon Sep 17 00:00:00 2001 From: Ava Silver Date: Tue, 25 Aug 2026 14:01:53 -0400 Subject: [PATCH 3/4] restore node 14 and python 3.7 --- serverless/src/lambda/layer-catalog.ts | 8 ++++++++ serverless/test/lambda/layer.spec.ts | 10 ++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/serverless/src/lambda/layer-catalog.ts b/serverless/src/lambda/layer-catalog.ts index 751c429c..456019b6 100644 --- a/serverless/src/lambda/layer-catalog.ts +++ b/serverless/src/lambda/layer-catalog.ts @@ -54,6 +54,10 @@ export const lambdaLayerCatalog = { runtimeType: "JAVA", tracerLayerNames: { x86_64: "dd-trace-java", arm64: "dd-trace-java" }, }, + "nodejs14.x": { + runtimeType: "NODE", + tracerLayerNames: { x86_64: "Datadog-Node14-x", arm64: "Datadog-Node14-x" }, + }, "nodejs16.x": { runtimeType: "NODE", tracerLayerNames: { x86_64: "Datadog-Node16-x", arm64: "Datadog-Node16-x" }, @@ -82,6 +86,10 @@ export const lambdaLayerCatalog = { runtimeType: "CUSTOM", tracerLayerNames: { x86_64: null, arm64: null }, }, + "python3.7": { + runtimeType: "PYTHON", + tracerLayerNames: { x86_64: "Datadog-Python37", arm64: null }, + }, "python3.8": { runtimeType: "PYTHON", tracerLayerNames: { x86_64: "Datadog-Python38", arm64: "Datadog-Python38-ARM" }, diff --git a/serverless/test/lambda/layer.spec.ts b/serverless/test/lambda/layer.spec.ts index 78eb4317..6c800cf4 100644 --- a/serverless/test/lambda/layer.spec.ts +++ b/serverless/test/lambda/layer.spec.ts @@ -61,12 +61,15 @@ describe("findLambdas", () => { Java25Function: mockFunctionResource("java25", ["x86_64"]), Java8Function: mockFunctionResource("java8", ["x86_64"]), Java8al2Function: mockFunctionResource("java8.al2", ["x86_64"]), + Node14Function: mockFunctionResource("nodejs14.x", ["x86_64"]), + Node16Function: mockFunctionResource("nodejs16.x", ["x86_64"]), Node18Function: mockFunctionResource("nodejs18.x", ["x86_64"]), Node20Function: mockFunctionResource("nodejs20.x", ["x86_64"]), Node22Function: mockFunctionResource("nodejs22.x", ["x86_64"]), Node24Function: mockFunctionResource("nodejs24.x", ["x86_64"]), ProvidedAl2Function: mockFunctionResource("provided.al2", ["x86_64"]), ProvidedAl2023Function: mockFunctionResource("provided.al2023", ["x86_64"]), + Python37Function: mockFunctionResource("python3.7", ["x86_64"]), Python38Function: mockFunctionResource("python3.8", ["x86_64"]), Python39Function: mockFunctionResource("python3.9", ["x86_64"]), Python310Function: mockFunctionResource("python3.10", ["x86_64"]), @@ -81,7 +84,7 @@ describe("findLambdas", () => { GoFunction: mockFunctionResource("go1.10", ["x86_64"]), RefFunction: mockFunctionResource({ Ref: "ValueRef" }, ["arm64"]), }; - const lambdas = findLambdas(resources, { ValueRef: "nodejs18.x" }); + const lambdas = findLambdas(resources, { ValueRef: "nodejs14.x" }); expect(lambdas).toEqual([ mockLambdaFunction("Dotnet6Function", "dotnet6", RuntimeType.DOTNET, "x86_64", ArchitectureType.x86_64), @@ -93,6 +96,8 @@ describe("findLambdas", () => { mockLambdaFunction("Java25Function", "java25", RuntimeType.JAVA, "x86_64", ArchitectureType.x86_64), mockLambdaFunction("Java8Function", "java8", RuntimeType.JAVA, "x86_64", ArchitectureType.x86_64), mockLambdaFunction("Java8al2Function", "java8.al2", RuntimeType.JAVA, "x86_64", ArchitectureType.x86_64), + mockLambdaFunction("Node14Function", "nodejs14.x", RuntimeType.NODE, "x86_64", ArchitectureType.x86_64), + mockLambdaFunction("Node16Function", "nodejs16.x", RuntimeType.NODE, "x86_64", ArchitectureType.x86_64), mockLambdaFunction("Node18Function", "nodejs18.x", RuntimeType.NODE, "x86_64", ArchitectureType.x86_64), mockLambdaFunction("Node20Function", "nodejs20.x", RuntimeType.NODE, "x86_64", ArchitectureType.x86_64), mockLambdaFunction("Node22Function", "nodejs22.x", RuntimeType.NODE, "x86_64", ArchitectureType.x86_64), @@ -105,6 +110,7 @@ describe("findLambdas", () => { "x86_64", ArchitectureType.x86_64, ), + mockLambdaFunction("Python37Function", "python3.7", RuntimeType.PYTHON, "x86_64", ArchitectureType.x86_64), mockLambdaFunction("Python38Function", "python3.8", RuntimeType.PYTHON, "x86_64", ArchitectureType.x86_64), mockLambdaFunction("Python39Function", "python3.9", RuntimeType.PYTHON, "x86_64", ArchitectureType.x86_64), mockLambdaFunction("Python310Function", "python3.10", RuntimeType.PYTHON, "x86_64", ArchitectureType.x86_64), @@ -117,7 +123,7 @@ describe("findLambdas", () => { mockLambdaFunction("Ruby34Function", "ruby3.4", RuntimeType.RUBY, "x86_64", ArchitectureType.x86_64), mockLambdaFunction("Ruby40Function", "ruby4.0", RuntimeType.RUBY, "x86_64", ArchitectureType.x86_64), mockLambdaFunction("GoFunction", "go1.10", RuntimeType.UNSUPPORTED, "x86_64", ArchitectureType.x86_64), - mockLambdaFunction("RefFunction", "nodejs18.x", RuntimeType.NODE, "arm64", ArchitectureType.ARM64, { + mockLambdaFunction("RefFunction", "nodejs14.x", RuntimeType.NODE, "arm64", ArchitectureType.ARM64, { Ref: "ValueRef", }), ]); From a58bdf1ffefb218bdd656512b67d490e85eae2b4 Mon Sep 17 00:00:00 2001 From: Ava Silver Date: Tue, 25 Aug 2026 14:06:47 -0400 Subject: [PATCH 4/4] update default versions across the board --- serverless/test/index.spec.ts | 2 +- serverless/test/lambda/env.spec.ts | 48 +++++++++++++-------------- serverless/test/lambda/lambda.spec.ts | 6 ++-- serverless/test/lambda/layer.spec.ts | 32 +++++++++--------- 4 files changed, 44 insertions(+), 44 deletions(-) diff --git a/serverless/test/index.spec.ts b/serverless/test/index.spec.ts index ad90e441..027921f7 100644 --- a/serverless/test/index.spec.ts +++ b/serverless/test/index.spec.ts @@ -47,7 +47,7 @@ export function mockInputEvent( Role: { "Fn::GetAtt": ["HelloWorldFunctionRole", "Arn"], }, - Runtime: "nodejs18.x", + Runtime: "nodejs24.x", }, }, }, diff --git a/serverless/test/lambda/env.spec.ts b/serverless/test/lambda/env.spec.ts index 990e5e7d..5e33cc0e 100644 --- a/serverless/test/lambda/env.spec.ts +++ b/serverless/test/lambda/env.spec.ts @@ -162,13 +162,13 @@ describe("setEnvConfiguration", () => { const lambda: LambdaFunction = { properties: { Handler: "app.handler", - Runtime: "python3.8", + Runtime: "python3.14", Role: "role-arn", Code: {}, }, key: "FunctionKey", runtimeType: RuntimeType.PYTHON, - runtime: "python3.8", + runtime: "python3.14", architecture: "x86_64", architectureType: ArchitectureType.x86_64, }; @@ -204,13 +204,13 @@ describe("setEnvConfiguration", () => { const lambda: LambdaFunction = { properties: { Handler: "app.handler", - Runtime: "python3.8", + Runtime: "python3.14", Role: "role-arn", Code: {}, }, key: "FunctionKey", runtimeType: RuntimeType.PYTHON, - runtime: "python3.8", + runtime: "python3.14", architecture: "x86_64", architectureType: ArchitectureType.x86_64, }; @@ -244,13 +244,13 @@ describe("setEnvConfiguration", () => { const lambda: LambdaFunction = { properties: { Handler: "app.handler", - Runtime: "python3.8", + Runtime: "python3.14", Role: "role-arn", Code: {}, }, key: "FunctionKey", runtimeType: RuntimeType.PYTHON, - runtime: "python3.8", + runtime: "python3.14", architecture: "x86_64", architectureType: ArchitectureType.x86_64, }; @@ -318,13 +318,13 @@ describe("setEnvConfiguration", () => { const lambda: LambdaFunction = { properties: { Handler: "app.handler", - Runtime: "python3.8", + Runtime: "python3.14", Role: "role-arn", Code: {}, }, key: "FunctionKey", runtimeType: RuntimeType.PYTHON, - runtime: "python3.8", + runtime: "python3.14", architecture: "x86_64", architectureType: ArchitectureType.x86_64, }; @@ -405,14 +405,14 @@ describe("setEnvConfiguration", () => { const lambda: LambdaFunction = { properties: { Handler: "app.handler", - Runtime: "python3.8", + Runtime: "python3.14", Role: "role-arn", Code: {}, Environment: { Variables: originalEnvVars }, }, key: "FunctionKey", runtimeType: RuntimeType.PYTHON, - runtime: "python3.8", + runtime: "python3.14", architecture: "x86_64", architectureType: ArchitectureType.x86_64, }; @@ -453,13 +453,13 @@ describe("setEnvConfiguration", () => { const lambda: LambdaFunction = { properties: { Handler: "app.handler", - Runtime: "python3.8", + Runtime: "python3.14", Role: "role-arn", Code: {}, }, key: "FunctionKey", runtimeType: RuntimeType.PYTHON, - runtime: "python3.8", + runtime: "python3.14", architecture: "x86_64", architectureType: ArchitectureType.x86_64, }; @@ -497,13 +497,13 @@ describe("setEnvConfiguration", () => { const lambda: LambdaFunction = { properties: { Handler: "app.handler", - Runtime: "python3.8", + Runtime: "python3.14", Role: "role-arn", Code: {}, }, key: "FunctionKey", runtimeType: RuntimeType.PYTHON, - runtime: "python3.8", + runtime: "python3.14", architecture: "x86_64", architectureType: ArchitectureType.x86_64, }; @@ -542,13 +542,13 @@ describe("setEnvConfiguration", () => { const lambda: LambdaFunction = { properties: { Handler: "app.handler", - Runtime: "python3.8", + Runtime: "python3.14", Role: "role-arn", Code: {}, }, key: "FunctionKey", runtimeType: RuntimeType.PYTHON, - runtime: "python3.8", + runtime: "python3.14", architecture: "x86_64", architectureType: ArchitectureType.x86_64, }; @@ -582,13 +582,13 @@ describe("setEnvConfiguration", () => { const lambda: LambdaFunction = { properties: { Handler: "app.handler", - Runtime: "python3.8", + Runtime: "python3.14", Role: "role-arn", Code: {}, }, key: "FunctionKey", runtimeType: RuntimeType.PYTHON, - runtime: "python3.8", + runtime: "python3.14", architecture: "x86_64", architectureType: ArchitectureType.x86_64, }; @@ -622,13 +622,13 @@ describe("setEnvConfiguration", () => { const lambda: LambdaFunction = { properties: { Handler: "app.handler", - Runtime: "python3.8", + Runtime: "python3.14", Role: "role-arn", Code: {}, }, key: "FunctionKey", runtimeType: RuntimeType.PYTHON, - runtime: "python3.8", + runtime: "python3.14", architecture: "x86_64", architectureType: ArchitectureType.x86_64, }; @@ -695,13 +695,13 @@ describe("setEnvConfiguration", () => { properties: { FunctionName: "my-function", Handler: "app.handler", - Runtime: "nodejs18.x", + Runtime: "nodejs24.x", Role: "role-arn", Code: {}, }, key: "FunctionKey", runtimeType: RuntimeType.NODE, - runtime: "nodejs18.x", + runtime: "nodejs24.x", architecture: "x86_64", architectureType: ArchitectureType.x86_64, }; @@ -776,13 +776,13 @@ describe("setEnvConfiguration", () => { properties: { FunctionName: "my-function", Handler: "app.handler", - Runtime: "nodejs18.x", + Runtime: "nodejs24.x", Role: "role-arn", Code: {}, }, key: "FunctionKey", runtimeType: RuntimeType.NODE, - runtime: "nodejs18.x", + runtime: "nodejs24.x", architecture: "x86_64", architectureType: ArchitectureType.x86_64, }; diff --git a/serverless/test/lambda/lambda.spec.ts b/serverless/test/lambda/lambda.spec.ts index 6da8c4ad..c4604f67 100644 --- a/serverless/test/lambda/lambda.spec.ts +++ b/serverless/test/lambda/lambda.spec.ts @@ -43,9 +43,9 @@ describe("Lambda", () => { const output = await handler(inputEvent, {}); const lambdaProperties: FunctionProperties = output.fragment.Resources[LAMBDA_KEY].Properties; - // Mocked Lambda has runtime nodejs18.x, so layer name is Datadog-Node18-x, with provided version number (25) at end + // Mocked Lambda has runtime nodejs24.x, so layer name is Datadog-Node24-x, with provided version number (25) at end expect(lambdaProperties.Layers).toEqual([ - expect.stringMatching(/arn:aws:lambda:us-east-1:.*:layer:Datadog-Node18-x:25/), + expect.stringMatching(/arn:aws:lambda:us-east-1:.*:layer:Datadog-Node24-x:25/), ]); }); @@ -98,7 +98,7 @@ describe("Lambda", () => { const lambdaProperties: FunctionProperties = output.fragment.Resources[LAMBDA_KEY].Properties; expect(lambdaProperties.Layers).toEqual([ - expect.stringMatching(/arn:aws-us-gov:lambda:us-gov-east-1:002406178527:layer:Datadog-Node18-x:25/), + expect.stringMatching(/arn:aws-us-gov:lambda:us-gov-east-1:002406178527:layer:Datadog-Node24-x:25/), ]); }); diff --git a/serverless/test/lambda/layer.spec.ts b/serverless/test/lambda/layer.spec.ts index 6c800cf4..1f5bb332 100644 --- a/serverless/test/lambda/layer.spec.ts +++ b/serverless/test/lambda/layer.spec.ts @@ -143,19 +143,19 @@ describe("findLambdas", () => { describe("applyLayers", () => { it("adds a layer array if none are present", () => { - const lambda = mockLambdaFunction("FunctionKey", "nodejs18.x", RuntimeType.NODE, "x86_64"); + const lambda = mockLambdaFunction("FunctionKey", "nodejs24.x", RuntimeType.NODE, "x86_64"); const region = "us-east-1"; const nodeLayerVersion = 25; const errors = applyLayers(region, [lambda], undefined, nodeLayerVersion); expect(errors.length).toEqual(0); expect(lambda.properties.Layers).toEqual([ - `arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:Datadog-Node18-x:${nodeLayerVersion}`, + `arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:Datadog-Node24-x:${nodeLayerVersion}`, ]); }); it("appends to the layer array if already present", () => { - const lambda = mockLambdaFunction("FunctionKey", "nodejs18.x", RuntimeType.NODE, "x86_64"); + const lambda = mockLambdaFunction("FunctionKey", "nodejs24.x", RuntimeType.NODE, "x86_64"); lambda.properties.Layers = ["node:2"]; const region = "us-east-1"; @@ -165,15 +165,15 @@ describe("applyLayers", () => { expect(errors.length).toEqual(0); expect(lambda.properties.Layers).toEqual([ "node:2", - `arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:Datadog-Node18-x:${nodeLayerVersion}`, + `arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:Datadog-Node24-x:${nodeLayerVersion}`, ]); }); it("doesn't add duplicate layers", () => { - const lambda = mockLambdaFunction("FunctionKey", "nodejs18.x", RuntimeType.NODE, "x86_64"); + const lambda = mockLambdaFunction("FunctionKey", "nodejs24.x", RuntimeType.NODE, "x86_64"); const region = "us-east-1"; const nodeLayerVersion = 25; - const layerArn = `arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:Datadog-Node18-x:${nodeLayerVersion}`; + const layerArn = `arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:Datadog-Node24-x:${nodeLayerVersion}`; lambda.properties.Layers = [layerArn]; const errors = applyLayers(region, [lambda], undefined, nodeLayerVersion); @@ -190,8 +190,8 @@ describe("applyLayers", () => { }); it("returns errors if layer versions are not provided for corresponding Lambda runtimes", () => { - const pythonLambda = mockLambdaFunction("PythonFunctionKey", "python3.8", RuntimeType.PYTHON, "x86_64"); - const nodeLambda = mockLambdaFunction("NodeFunctionKey", "nodejs18.x", RuntimeType.NODE, "x86_64"); + const pythonLambda = mockLambdaFunction("PythonFunctionKey", "python3.14", RuntimeType.PYTHON, "x86_64"); + const nodeLambda = mockLambdaFunction("NodeFunctionKey", "nodejs24.x", RuntimeType.NODE, "x86_64"); const errors = applyLayers("us-east-1", [pythonLambda, nodeLambda]); expect(errors).toEqual([ @@ -440,7 +440,7 @@ describe("getNewLayers", () => { describe("isGovCloud", () => { it("applies the GovCloud layer", () => { const pythonLambda = mockLambdaFunction("PythonFunctionKey", "python3.8", RuntimeType.PYTHON, "x86_64"); - const nodeLambda = mockLambdaFunction("NodeFunctionKey", "nodejs18.x", RuntimeType.NODE, "x86_64"); + const nodeLambda = mockLambdaFunction("NodeFunctionKey", "nodejs24.x", RuntimeType.NODE, "x86_64"); const errors = applyLayers("us-gov-east-1", [pythonLambda, nodeLambda], 21, 30); expect(errors.length).toEqual(0); @@ -448,25 +448,25 @@ describe("isGovCloud", () => { `arn:aws-us-gov:lambda:us-gov-east-1:${DD_GOV_ACCOUNT_ID}:layer:Datadog-Python38:21`, ]); expect(nodeLambda.properties.Layers).toEqual([ - `arn:aws-us-gov:lambda:us-gov-east-1:${DD_GOV_ACCOUNT_ID}:layer:Datadog-Node18-x:30`, + `arn:aws-us-gov:lambda:us-gov-east-1:${DD_GOV_ACCOUNT_ID}:layer:Datadog-Node24-x:30`, ]); }); }); describe("getLambdaLibraryLayerArn", () => { - it("gets the us-east-1 layer arn for the Datadog Node18 Lambda Library", () => { + it("gets the us-east-1 layer arn for the Datadog Node24 Lambda Library", () => { const region = "us-east-1"; const version = 22; - const runtime = "nodejs18.x"; + const runtime = "nodejs24.x"; const layerArn = getLambdaLibraryLayerArn(region, version, runtime, "x86_64"); - expect(layerArn).toEqual(`arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:Datadog-Node18-x:${version}`); + expect(layerArn).toEqual(`arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:Datadog-Node24-x:${version}`); }); - it("gets the us-east-1 layer arn for the Datadog Python38 Lambda Library", () => { + it("gets the us-east-1 layer arn for the Datadog Python314 Lambda Library", () => { const region = "us-east-1"; const version = 22; - const runtime = "python3.8"; + const runtime = "python3.14"; const layerArn = getLambdaLibraryLayerArn(region, version, runtime, "x86_64"); - expect(layerArn).toEqual(`arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:Datadog-Python38:${version}`); + expect(layerArn).toEqual(`arn:aws:lambda:${region}:${DD_ACCOUNT_ID}:layer:Datadog-Python314:${version}`); }); it("gets the us-east-1 ARM layer arn for the Datadog Python38 Lambda Library", () => { const region = "us-east-1";