- Notifications
You must be signed in to change notification settings - Fork 4.4k
Description
Describe the bug
The built-in ADOT abstractions behind the adotInstrumentation property still reflect the legacy ADOT Lambda approach, where the instrumentation and the collector are bundled together in a single layer. These abstractions include:
In my case, using:
AdotLayerVersion.fromJavaScriptSdkLayerVersion(AdotLambdaLayerJavaScriptSdkVersion.LATEST)AdotLambdaExecWrapper.REGULAR_HANDLER
resolved to:
arn:aws:lambda:<region>:901920570463:layer:aws-otel-nodejs-<architecture>-ver-1-30-2:1(the legacy ADOT Lambda layer)/opt/otel-handler(the legacy execution wrapper)
That does not match the current ADOT Lambda overview, which documents the newer optimized ADOT Lambda layers for the standard CloudWatch Application Signals and CloudWatch path. The same ADOT page also has a not-recommended section for the legacy embedded-collector layers.
The mismatch seems to be that CDK still assumes the old bundled model, while the newer optimized model uses the AWSOpenTelemetryDistro* layer families and AWS_LAMBDA_EXEC_WRAPPER=/opt/otel-instrument for the standard CloudWatch path.
This issue is broader than one JavaScript enum. The current AdotLayerVersion API already exposes generic, Java, Java auto-instrumentation, JavaScript, and Python ADOT layer families, so the underlying ADOT abstraction in CDK appears to still be aligned with the legacy model.
Regression Issue
- Select this option if this issue appears to be a regression.
Last Known Working CDK Library Version
No response
Expected Behavior
CDK should distinguish between:
- legacy embedded-collector ADOT Lambda layers
- optimized ADOT Lambda layers
The recommended or LATEST path should resolve to the optimized layer family where applicable, not the legacy embedded-collector family.
For the JavaScript case specifically, I would expect CDK to resolve to the AWSOpenTelemetryDistroJs family and to configure AWS_LAMBDA_EXEC_WRAPPER=/opt/otel-instrument, which is the model described by the current ADOT Lambda overview.
If CDK wants to keep the legacy path for compatibility, it should be modeled explicitly as legacy and not be what LATEST or the recommended path resolves to.
Current Behavior
I deployed the stack below to eu-central-1, and the resulting Lambda function received this layer:
arn:aws:lambda:eu-central-1:901920570463:layer:aws-otel-nodejs-amd64-ver-1-30-1:1 The function configuration also follows the old wrapper model:
AWS_LAMBDA_EXEC_WRAPPER=/opt/otel-handler That matches the legacy ADOT Lambda JavaScript page, which documents the older JavaScript layer family and the /opt/otel-handler wrapper.
By contrast, the current ADOT Lambda overview documents optimized layers with support for CloudWatch Application Signals, and its AWS CDK example uses LayerVersion.fromLayerVersionArn(...) together with AWS_LAMBDA_EXEC_WRAPPER=/opt/otel-instrument.
The optimized JavaScript family is published as AWSOpenTelemetryDistroJs in the aws-otel-js-instrumentation releases, which is a different layer family and execution model from what the current CDK helper resolves to.
So the problem is not just that CDK points to an older version. The problem is that the built-in ADOT helper still resolves to the legacy embedded-collector layer family, even though the current ADOT Lambda docs describe that path as legacy and not recommended.
Reproduction Steps
- Create a Lambda using
aws-cdk-lib/aws-lambdawith ADOT enabled:
import { Stack, StackProps, aws_lambda as lambda } from "aws-cdk-lib"; import { Construct } from "constructs"; export class TrivialLambdaStack extends Stack { constructor(scope: Construct, id: string, props: StackProps = {}) { super(scope, id, props); new lambda.Function(this, "TrivialFunction", { runtime: lambda.Runtime.NODEJS_24_X, handler: "index.handler", code: lambda.Code.fromInline(` exports.handler = async function handler() { return { statusCode: 200, body: JSON.stringify({ message: "hello from lambda" }), }; }; `.trim()), adotInstrumentation: { layerVersion: lambda.AdotLayerVersion.fromJavaScriptSdkLayerVersion( lambda.AdotLambdaLayerJavaScriptSdkVersion.LATEST, ), execWrapper: lambda.AdotLambdaExecWrapper.REGULAR_HANDLER, }, }); } }- Deploy the stack.
- Open the function in the AWS Lambda console.
- Inspect the attached layer ARN and the resulting
AWS_LAMBDA_EXEC_WRAPPER. - Observe that CDK resolves to the legacy embedded-collector Node.js layer family and
/opt/otel-handler, rather than the optimized ADOT Lambda JavaScript layer family and/opt/otel-instrument.
Possible Solution
Update the ADOT Lambda references and/or API model in CDK so that optimized ADOT Lambda layers are first-class options.
Possible approaches:
- keep the current embedded-collector behavior, but model it explicitly as legacy
- add first-class support for the optimized ADOT Lambda layer families
- make
LATESTresolve to the optimized layer family where applicable - update CDK docs and examples so they do not steer users toward the legacy embedded-collector model
At minimum, the current built-in ADOT helpers should not make the legacy embedded-collector path look like the default or recommended configuration when the current ADOT Lambda docs treat it as the legacy/not-recommended path for the standard CloudWatch flow.
Additional Information/Context
I think this is related to #36190, which asks for better Lambda support for CloudWatch Application Signals. Based on the current ADOT Lambda overview, the optimized ADOT Lambda layers already support that use case.
If CDK is updated here to expose the optimized ADOT Lambda layers correctly, that issue may become partially or fully superseded and may even be closable depending on what remains after this is fixed.
AWS CDK Library version (aws-cdk-lib)
2.241.0
AWS CDK CLI version
2.1109.0
Node.js Version
24.14.0
OS
Ubuntu 24.04
Language
TypeScript
Language Version
5.9.3
Other information
No response