aws / aws/aws-cdk

feat(lambda): add s3ObjectStorageMode (Self-managed S3 code storage) support to L2 constructs

Open
#38,260 1 comment 0 reactions 0 assignees View on GitHub
@aws-cdk/aws-lambda effort/small feature-request mixins p2
Dominant language
TypeScript
Stars
12.9k
Forks
4.6k
Avg merge
2d 3h
Merged PRs (30d)
83

Description

### Describe the feature

AWS Lambda now supports self-managed S3 code storage via the `S3ObjectStorageMode` property. This allows Lambda functions to reference deployment packages directly from customer-owned S3 buckets without copying the package into Lambda-managed storage, helping customers bypass the default 300 GB per-region storage quota.

While the L1 constructs (`CfnFunction.CodeProperty.s3ObjectStorageMode` and `CfnLayerVersion.ContentProperty.s3ObjectStorageMode`) already support this property, the high-level L2 constructs (like `lambda.Function`, `lambda.LayerVersion`, and `lambda.Code`) do not currently expose it natively.

[Self-managed S3 code storage - AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/configuration-self-managed-storage.html)

### Use Case

Customers deploying many Lambda functions or very large deployment packages can easily exceed the default 300 GB Lambda-managed storage quota per region.

Using the `s3ObjectStorageMode` set to `REFERENCE` allows them to reference deployment packages directly from their own S3 bucket, effectively bypassing this quota limit. Currently, configuring this in CDK requires customers to use escape hatches / raw overrides on the underlying L1 resources, which degrades the developer experience.

### Proposed Solution

Add a new `S3ObjectStorageMode` enum and add `s3ObjectStorageMode` to `BucketOptions` (used by `lambda.Code.fromBucketV2`):

```typescript
export enum S3ObjectStorageMode {
/**
* Lambda copies the deployment package from your specified S3 bucket into its own Lambda-managed storage.
*/
COPY = 'COPY',

/**
* Lambda references your code directly from your S3 bucket (self-managed S3 code storage).
*/
REFERENCE = 'REFERENCE',
}

export interface BucketOptions {
/**
* The version of the S3 object to use.
*/
readonly objectVersion?: string;

/**
* The KMS key to use for decrypting the code.
*/
readonly sourceKMSKey?: kms.IKey;

/**
* How Lambda manages the storage of your code package.
*
* @default S3ObjectStorageMode.COPY
*/
readonly s3ObjectStorageMode?: S3ObjectStorageMode;
}
```

When building/binding `S3CodeV2`, this option should be mapped to the generated CloudFormation properties:
* `CfnFunction.CodeProperty.s3ObjectStorageMode`
* `CfnLayerVersion.ContentProperty.s3ObjectStorageMode`

#### Example L2 Usage:

**Lambda Function:**
```typescript
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as s3 from 'aws-cdk-lib/aws-s3';

const bucket = s3.Bucket.fromBucketName(this, 'MyBucket', 'my-code-bucket');

new lambda.Function(this, 'MyFunction', {
runtime: lambda.Runtime.NODEJS_20_X,
handler: 'index.handler',
code: lambda.Code.fromBucketV2(bucket, 'my-function.zip', {
s3ObjectStorageMode: lambda.S3ObjectStorageMode.REFERENCE,
}),
});
```

**Lambda LayerVersion:**
```typescript
new lambda.LayerVersion(this, 'MyLayer', {
code: lambda.Code.fromBucketV2(bucket, 'my-layer.zip', {
s3ObjectStorageMode: lambda.S3ObjectStorageMode.REFERENCE,
}),
});
```

### Other Information

#### Temporary Escape Hatch Workaround:

**Lambda Function:**
```typescript
const fn = new lambda.Function(this, 'MyFunction', {
runtime: lambda.Runtime.NODEJS_20_X,
handler: 'index.handler',
code: lambda.Code.fromBucket(bucket, 'my-function.zip'),
});

const cfnFn = fn.node.defaultChild as lambda.CfnFunction;
cfnFn.addPropertyOverride('Code.S3ObjectStorageMode', 'REFERENCE');
```

**Lambda LayerVersion:**
```typescript
const layer = new lambda.LayerVersion(this, 'MyLayer', {
code: lambda.Code.fromBucket(bucket, 'my-layer.zip'),
});

const cfnLayer = layer.node.defaultChild as lambda.CfnLayerVersion;
cfnLayer.addPropertyOverride('Content.S3ObjectStorageMode', 'REFERENCE');
```

### Acknowledgements

- [x] I may be able to implement this feature request
- [ ] This feature might incur a breaking change

Contributor guide

Open the contributing guide

Research direction

Start by tracing lambda.Code.fromBucketV2, BucketOptions, and S3CodeV2 through the L2 constructs, then inspect how CfnFunction.CodeProperty and CfnLayerVersion.ContentProperty are populated. Add the S3ObjectStorageMode enum and option, map it to both generated properties, and verify synthesized function and layer resources contain the selected mode while the default remains COPY.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, typescript
Domain
cloud
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.