Skip to content

Commit 01da2c9

Browse files
authored
chore(lambda): handle Runtime.ALL correctly in LayerVersion compatibleRuntimes (#35351)
### Issue # (if applicable) Closes #35348. ### Reason for this change `Runtime.ALL` contains 43+ runtime entries (including deprecated ones), but AWS Lambda limits `compatibleRuntimes` to maximum 15 entries and only accepts currently supported runtimes. When users specify `compatibleRuntimes: Runtime.ALL` for Lambda layers, deployment fails with CloudFormation validation errors: - "Member must have length less than or equal to 15" - "Member must satisfy enum value set" for supported runtimes only This breaks existing user code that relies on the documented `Runtime.ALL` constant for Lambda layers. ### Description of changes Modified the LayerVersion constructor to detect when `compatibleRuntimes` is set to `Runtime.ALL` and treat it as `undefined`, allowing AWS to use its default "all supported runtimes" behavior: - Added conditional logic in `CfnLayerVersion` resource creation to check for `Runtime.ALL` via reference equality - When `Runtime.ALL` is detected, `compatibleRuntimes` is set to `undefined` in the CloudFormation template - When `undefined`, AWS Lambda defaults to supporting all currently supported runtimes (the intended behavior) - All other behavior remains unchanged - specific runtime arrays and `undefined` work as before - Updated documentation to clarify that `Runtime.ALL` is equivalent to `undefined` **Technical Implementation**: ```typescript compatibleRuntimes: (props.compatibleRuntimes === Runtime.ALL) ? undefined : props.compatibleRuntimes?.map(r => r.name), ``` ### Describe any new or updated permissions being added N/A - No IAM permissions or resource access changes. ### Description of how you validated changes - **Unit tests**: Added comprehensive test cases using `test.each` to verify that both `Runtime.ALL` and `undefined` result in omitting `CompatibleRuntimes` from the CloudFormation template. This eliminates code duplication and follows Jest best practices. All existing layer tests continue to pass (7/7). - **Integration tests**: No additional integration tests required as this change leverages existing AWS Lambda service behavior when `CompatibleRuntimes` is omitted from the CloudFormation template. The AWS service automatically applies compatibility with all currently supported runtimes, which is the intended behavior for `Runtime.ALL`. **Test Coverage**: - ✅ `Runtime.ALL` produces `undefined` in CloudFormation template - ✅ `undefined` compatibleRuntimes produces `undefined` in CloudFormation template - ✅ Specific runtime arrays work unchanged - ✅ Empty runtime array validation still throws error - ✅ All existing layer functionality preserved - ✅ Refactored tests using `test.each` to eliminate duplication ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent cecbabf commit 01da2c9

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

packages/aws-cdk-lib/aws-lambda/lib/layers.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export interface ILayerVersion extends IResource, ILayerVersionRef {
7979
/**
8080
* The runtimes compatible with this Layer.
8181
*
82-
* @default Runtime.All
82+
* @default - All supported runtimes. Setting this to Runtime.ALL is equivalent to leaving it undefined.
8383
*/
8484
readonly compatibleRuntimes?: Runtime[];
8585

@@ -219,7 +219,9 @@ export class LayerVersion extends LayerVersionBase {
219219
}
220220

221221
const resource: CfnLayerVersion = new CfnLayerVersion(this, 'Resource', {
222-
compatibleRuntimes: props.compatibleRuntimes && props.compatibleRuntimes.map(r => r.name),
222+
compatibleRuntimes: (props.compatibleRuntimes === Runtime.ALL)
223+
? undefined
224+
: props.compatibleRuntimes?.map(r => r.name),
223225
compatibleArchitectures: props.compatibleArchitectures?.map(a => a.name),
224226
content: {
225227
s3Bucket: code.s3Location.bucketName,

packages/aws-cdk-lib/aws-lambda/test/layers.test.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,34 @@ describe('layers', () => {
122122
CompatibleArchitectures: ['arm64'],
123123
});
124124
});
125+
126+
test.each([
127+
['Runtime.ALL is handled correctly', { compatibleRuntimes: lambda.Runtime.ALL }],
128+
['undefined compatibleRuntimes is handled correctly', {}],
129+
])('%s by omitting compatibleRuntimes', (_, props) => {
130+
// GIVEN
131+
const stack = new cdk.Stack();
132+
const bucket = new s3.Bucket(stack, 'Bucket');
133+
const code = new lambda.S3Code(bucket, 'ObjectKey');
134+
135+
// WHEN
136+
new lambda.LayerVersion(stack, 'LayerVersion', {
137+
code,
138+
...props,
139+
});
140+
141+
// THEN - CompatibleRuntimes should be omitted from CloudFormation template
142+
const template = Template.fromStack(stack);
143+
template.hasResourceProperties('AWS::Lambda::LayerVersion', {
144+
Content: {
145+
S3Bucket: stack.resolve(bucket.bucketName),
146+
S3Key: 'ObjectKey',
147+
},
148+
});
149+
150+
// Verify that CompatibleRuntimes is NOT present in the template
151+
const resources = template.findResources('AWS::Lambda::LayerVersion');
152+
const layerResource = Object.values(resources)[0];
153+
expect(layerResource.Properties).not.toHaveProperty('CompatibleRuntimes');
154+
});
125155
});

0 commit comments

Comments
 (0)