Skip to content

Commit 1e608cf

Browse files
authored
feat(infra): Expose BucketDeploymentProps.retainOnDelete [CLK-255746] (#8)
* feat(infra): Expose retainOnDelete property from BucketDeploymentProps [CLK-255746] * chore(infra): Add UTs [CLK-255746]
1 parent ed8be49 commit 1e608cf

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed

docs/interfaces/UploadProps.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
- [fileName](UploadProps.md#filename)
1111
- [path](UploadProps.md#path)
1212
- [prune](UploadProps.md#prune)
13+
- [retainOnDelete](UploadProps.md#retainondelete)
1314
- [role](UploadProps.md#role)
1415

1516
## Properties
@@ -54,6 +55,25 @@ false
5455

5556
___
5657

58+
### retainOnDelete
59+
60+
`Optional` `Readonly` **retainOnDelete**: `boolean`
61+
62+
Whether or not to delete the objects from the bucket when this resource
63+
is deleted/updated from the stack.
64+
65+
NOTE: Changing the logical ID of the `BucketDeployment` construct, without changing the destination
66+
(for example due to refactoring, or intentional ID change) **will result in the deletion of the objects**.
67+
This is because CloudFormation will first create the new resource, which will have no affect,
68+
followed by a deletion of the old resource, which will cause a deletion of the objects,
69+
since the destination hasn't changed, and `retainOnDelete` is `false`.
70+
71+
**`Default`**
72+
73+
true
74+
75+
___
76+
5777
### role
5878

5979
`Optional` `Readonly` **role**: `IRole`

src/generator.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,19 @@ export interface UploadProps {
3535
* @default false
3636
*/
3737
readonly prune?: boolean;
38+
/**
39+
* Whether or not to delete the objects from the bucket when this resource
40+
* is deleted/updated from the stack.
41+
*
42+
* NOTE: Changing the logical ID of the `BucketDeployment` construct, without changing the destination
43+
* (for example due to refactoring, or intentional ID change) **will result in the deletion of the objects**.
44+
* This is because CloudFormation will first create the new resource, which will have no affect,
45+
* followed by a deletion of the old resource, which will cause a deletion of the objects,
46+
* since the destination hasn't changed, and `retainOnDelete` is `false`.
47+
*
48+
* @default true
49+
*/
50+
readonly retainOnDelete?: boolean;
3851
/**
3952
* Used as the Lambda Execution Role for the BucketDeployment.
4053
* @default - role is created automatically by the Construct
@@ -163,6 +176,7 @@ export class Generator extends Construct {
163176
destinationKeyPrefix: this._uploadProps.path,
164177
sources: [Source.jsonData(this._uploadProps.fileName, contents)],
165178
prune: this._uploadProps.prune ?? false,
179+
retainOnDelete: this._uploadProps.retainOnDelete,
166180
role: this._uploadProps.role,
167181
});
168182
}

test/generator.test.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint-disable dot-notation */
22
// ^ Helps us test private properties like functions and fields
33
import { App, CfnElement, Stack } from 'aws-cdk-lib';
4-
import { Template } from 'aws-cdk-lib/assertions';
4+
import { Match, Template } from 'aws-cdk-lib/assertions';
55
import { Role, ServicePrincipal } from 'aws-cdk-lib/aws-iam';
66
import { schema } from './resources/test.schema';
77
import { Generator, GeneratorFileType, GeneratorProps } from '../src';
@@ -90,6 +90,32 @@ describe('Generator', () => {
9090
});
9191
});
9292

93+
it('retains objects by default', () => {
94+
new Generator(stack, 'Generator', actualProps);
95+
const template = Template.fromStack(stack);
96+
template.hasResourceProperties('Custom::CDKBucketDeployment', {
97+
DestinationBucketKeyPrefix: actualProps.upload.path,
98+
DestinationBucketName: actualProps.upload.bucketArn.split(':').pop(),
99+
RetainOnDelete: Match.absent(),
100+
});
101+
});
102+
103+
it('does not retain objects when told not to', () => {
104+
new Generator(stack, 'Generator', {
105+
...actualProps,
106+
upload: {
107+
...actualProps.upload,
108+
retainOnDelete: false,
109+
},
110+
});
111+
const template = Template.fromStack(stack);
112+
template.hasResourceProperties('Custom::CDKBucketDeployment', {
113+
DestinationBucketKeyPrefix: actualProps.upload.path,
114+
DestinationBucketName: actualProps.upload.bucketArn.split(':').pop(),
115+
RetainOnDelete: false,
116+
});
117+
});
118+
93119
it('uses custom Lambda execution role when set', () => {
94120
const testRole = new Role(stack, 'TestExecutionRole', { assumedBy: new ServicePrincipal('test.amazonaws.com') });
95121
new Generator(stack, 'Generator', {

0 commit comments

Comments
 (0)