Skip to content

Commit 3ce40b4

Browse files
authored
feat(s3-deployment): ephemeral storage size property for bucket deployment (#19958)
Closes #19947. Followed the same convention for `memoryLimit` property so that a new singleton lambda configuration will be created when bucket deployments are specified with different `ephemeralStorageSize` configurations. ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/master/CONTRIBUTING.md) ### Adding new Unconventional Dependencies: * [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/master/CONTRIBUTING.md/#adding-new-unconventional-dependencies) ### New Features * [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/master/INTEGRATION_TESTS.md)? * [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 2ca5050 commit 3ce40b4

File tree

4 files changed

+79
-18
lines changed

4 files changed

+79
-18
lines changed

packages/@aws-cdk/aws-lambda/lib/function.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ export interface FunctionOptions extends EventInvokeConfigOptions {
9696
readonly memorySize?: number;
9797

9898
/**
99-
* The size of the function’s /tmp directory in MB.
99+
* The size of the function’s /tmp directory in MiB.
100100
*
101101
* @default 512 MiB
102102
*/

packages/@aws-cdk/aws-s3-deployment/README.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ new s3deploy.BucketDeployment(this, 'DeployMeWithoutDeletingFilesOnDestination',
139139
});
140140
```
141141

142-
This option also enables you to specify multiple bucket deployments for the same destination bucket & prefix,
142+
This option also enables you to
143+
multiple bucket deployments for the same destination bucket & prefix,
143144
each with its own characteristics. For example, you can set different cache-control headers
144145
based on file extensions:
145146

@@ -259,14 +260,19 @@ new s3deploy.BucketDeployment(this, 'DeployWithInvalidation', {
259260
});
260261
```
261262

262-
## Memory Limit
263+
## Size Limits
263264

264265
The default memory limit for the deployment resource is 128MiB. If you need to
265-
copy larger files, you can use the `memoryLimit` configuration to specify the
266+
copy larger files, you can use the `memoryLimit` configuration to increase the
266267
size of the AWS Lambda resource handler.
267268

268-
> NOTE: a new AWS Lambda handler will be created in your stack for each memory
269-
> limit configuration.
269+
The default ephemeral storage size for the deployment resource is 512MiB. If you
270+
need to upload larger files, you may hit this limit. You can use the
271+
`ephemeralStorageSize` configuration to increase the storage size of the AWS Lambda
272+
resource handler.
273+
274+
> NOTE: a new AWS Lambda handler will be created in your stack for each combination
275+
> of memory and storage size.
270276
271277
## EFS Support
272278

packages/@aws-cdk/aws-s3-deployment/lib/bucket-deployment.ts

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,13 @@ export interface BucketDeploymentProps {
121121
*/
122122
readonly memoryLimit?: number;
123123

124+
/**
125+
* The size of the AWS Lambda function’s /tmp directory in MiB.
126+
*
127+
* @default 512 MiB
128+
*/
129+
readonly ephemeralStorageSize?: cdk.Size;
130+
124131
/**
125132
* Mount an EFS file system. Enable this if your assets are large and you encounter disk space errors.
126133
* Enabling this option will require a VPC to be specified.
@@ -292,7 +299,7 @@ export class BucketDeployment extends CoreConstruct {
292299

293300
const mountPath = `/mnt${accessPointPath}`;
294301
const handler = new lambda.SingletonFunction(this, 'CustomResourceHandler', {
295-
uuid: this.renderSingletonUuid(props.memoryLimit, props.vpc),
302+
uuid: this.renderSingletonUuid(props.memoryLimit, props.ephemeralStorageSize, props.vpc),
296303
code: lambda.Code.fromAsset(path.join(__dirname, 'lambda')),
297304
layers: [new AwsCliLayer(this, 'AwsCliLayer')],
298305
runtime: lambda.Runtime.PYTHON_3_7,
@@ -304,6 +311,7 @@ export class BucketDeployment extends CoreConstruct {
304311
timeout: cdk.Duration.minutes(15),
305312
role: props.role,
306313
memorySize: props.memoryLimit,
314+
ephemeralStorageSize: props.ephemeralStorageSize,
307315
vpc: props.vpc,
308316
vpcSubnets: props.vpcSubnets,
309317
filesystem: accessPoint ? lambda.FileSystem.fromEfsAccessPoint(
@@ -331,7 +339,7 @@ export class BucketDeployment extends CoreConstruct {
331339
// the sources actually has markers.
332340
const hasMarkers = sources.some(source => source.markers);
333341

334-
const crUniqueId = `CustomResource${this.renderUniqueId(props.memoryLimit, props.vpc)}`;
342+
const crUniqueId = `CustomResource${this.renderUniqueId(props.memoryLimit, props.ephemeralStorageSize, props.vpc)}`;
335343
this.cr = new cdk.CustomResource(this, crUniqueId, {
336344
serviceToken: handler.functionArn,
337345
resourceType: 'Custom::CDKBucketDeployment',
@@ -426,21 +434,32 @@ export class BucketDeployment extends CoreConstruct {
426434
return this._deployedBucket;
427435
}
428436

429-
private renderUniqueId(memoryLimit?: number, vpc?: ec2.IVpc) {
437+
private renderUniqueId(memoryLimit?: number, ephemeralStorageSize?: cdk.Size, vpc?: ec2.IVpc) {
430438
let uuid = '';
431439

432-
// if user specify a custom memory limit, define another singleton handler
440+
// if the user specifes a custom memory limit, we define another singleton handler
433441
// with this configuration. otherwise, it won't be possible to use multiple
434442
// configurations since we have a singleton.
435443
if (memoryLimit) {
436444
if (cdk.Token.isUnresolved(memoryLimit)) {
437-
throw new Error('Can\'t use tokens when specifying "memoryLimit" since we use it to identify the singleton custom resource handler');
445+
throw new Error("Can't use tokens when specifying 'memoryLimit' since we use it to identify the singleton custom resource handler.");
438446
}
439447

440448
uuid += `-${memoryLimit.toString()}MiB`;
441449
}
442450

443-
// if user specify to use VPC, define another singleton handler
451+
// if the user specifies a custom ephemeral storage size, we define another singleton handler
452+
// with this configuration. otherwise, it won't be possible to use multiple
453+
// configurations since we have a singleton.
454+
if (ephemeralStorageSize) {
455+
if (ephemeralStorageSize.isUnresolved()) {
456+
throw new Error("Can't use tokens when specifying 'ephemeralStorageSize' since we use it to identify the singleton custom resource handler.");
457+
}
458+
459+
uuid += `-${ephemeralStorageSize.toMebibytes().toString()}MiB`;
460+
}
461+
462+
// if the user specifies a VPC, we define another singleton handler
444463
// with this configuration. otherwise, it won't be possible to use multiple
445464
// configurations since we have a singleton.
446465
// A VPC is a must if EFS storage is used and that's why we are only using VPC in uuid.
@@ -451,10 +470,10 @@ export class BucketDeployment extends CoreConstruct {
451470
return uuid;
452471
}
453472

454-
private renderSingletonUuid(memoryLimit?: number, vpc?: ec2.IVpc) {
473+
private renderSingletonUuid(memoryLimit?: number, ephemeralStorageSize?: cdk.Size, vpc?: ec2.IVpc) {
455474
let uuid = '8693BB64-9689-44B6-9AAF-B0CC9EB8756C';
456475

457-
uuid += this.renderUniqueId(memoryLimit, vpc);
476+
uuid += this.renderUniqueId(memoryLimit, ephemeralStorageSize, vpc);
458477

459478
return uuid;
460479
}

packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.test.ts

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -714,9 +714,7 @@ test('memoryLimit can be used to specify the memory limit for the deployment res
714714
const bucket = new s3.Bucket(stack, 'Dest');
715715

716716
// WHEN
717-
718717
// we define 3 deployments with 2 different memory configurations
719-
720718
new s3deploy.BucketDeployment(stack, 'Deploy256-1', {
721719
sources: [s3deploy.Source.asset(path.join(__dirname, 'my-website'))],
722720
destinationBucket: bucket,
@@ -736,14 +734,52 @@ test('memoryLimit can be used to specify the memory limit for the deployment res
736734
});
737735

738736
// THEN
739-
740737
// we expect to find only two handlers, one for each configuration
741-
742738
Template.fromStack(stack).resourceCountIs('AWS::Lambda::Function', 2);
743739
Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { MemorySize: 256 });
744740
Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { MemorySize: 1024 });
745741
});
746742

743+
test('ephemeralStorageSize can be used to specify the storage size for the deployment resource handler', () => {
744+
// GIVEN
745+
const stack = new cdk.Stack();
746+
const bucket = new s3.Bucket(stack, 'Dest');
747+
748+
// WHEN
749+
// we define 3 deployments with 2 different memory configurations
750+
new s3deploy.BucketDeployment(stack, 'Deploy256-1', {
751+
sources: [s3deploy.Source.asset(path.join(__dirname, 'my-website'))],
752+
destinationBucket: bucket,
753+
ephemeralStorageSize: cdk.Size.mebibytes(512),
754+
});
755+
756+
new s3deploy.BucketDeployment(stack, 'Deploy256-2', {
757+
sources: [s3deploy.Source.asset(path.join(__dirname, 'my-website'))],
758+
destinationBucket: bucket,
759+
ephemeralStorageSize: cdk.Size.mebibytes(512),
760+
});
761+
762+
new s3deploy.BucketDeployment(stack, 'Deploy1024', {
763+
sources: [s3deploy.Source.asset(path.join(__dirname, 'my-website'))],
764+
destinationBucket: bucket,
765+
ephemeralStorageSize: cdk.Size.mebibytes(1024),
766+
});
767+
768+
// THEN
769+
// we expect to find only two handlers, one for each configuration
770+
Template.fromStack(stack).resourceCountIs('AWS::Lambda::Function', 2);
771+
Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', {
772+
EphemeralStorage: {
773+
Size: 512,
774+
},
775+
});
776+
Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', {
777+
EphemeralStorage: {
778+
Size: 1024,
779+
},
780+
});
781+
});
782+
747783
test('deployment allows custom role to be supplied', () => {
748784

749785
// GIVEN

0 commit comments

Comments
 (0)