Skip to content

Commit e3d9a72

Browse files
Merge branch 'master' into issue_8277
2 parents 855c765 + 46a1eaa commit e3d9a72

12 files changed

+85
-66
lines changed

CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
44

5+
## [1.42.1](https://github.com/aws/aws-cdk/compare/v1.42.0...v1.42.1) (2020-06-01)
6+
7+
8+
### Bug Fixes
9+
10+
* **lambda:** `SingletonFunction.grantInvoke()` API fails with error 'No child with id' ([#8296](https://github.com/aws/aws-cdk/issues/8296)) ([b4e264c](https://github.com/aws/aws-cdk/commit/b4e264c024bc58053412be1343bed6458628f7cb)), closes [#8240](https://github.com/aws/aws-cdk/issues/8240)
11+
512
## [1.42.0](https://github.com/aws/aws-cdk/compare/v1.41.0...v1.42.0) (2020-05-27)
613

714

lerna.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@
1010
"tools/*"
1111
],
1212
"rejectCycles": "true",
13-
"version": "1.42.0"
13+
"version": "1.42.1"
1414
}

packages/@aws-cdk/aws-rds/lib/cluster.ts

+20-9
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { IRole, ManagedPolicy, Role, ServicePrincipal } from '@aws-cdk/aws-iam';
33
import * as kms from '@aws-cdk/aws-kms';
44
import * as s3 from '@aws-cdk/aws-s3';
55
import * as secretsmanager from '@aws-cdk/aws-secretsmanager';
6-
import { Construct, Duration, RemovalPolicy, Resource, Token } from '@aws-cdk/core';
6+
import { CfnDeletionPolicy, Construct, Duration, RemovalPolicy, Resource, Token } from '@aws-cdk/core';
77
import { DatabaseClusterAttributes, IDatabaseCluster } from './cluster-ref';
88
import { DatabaseSecret } from './database-secret';
99
import { Endpoint } from './endpoint';
@@ -124,9 +124,9 @@ export interface DatabaseClusterProps {
124124
* The removal policy to apply when the cluster and its instances are removed
125125
* from the stack or replaced during an update.
126126
*
127-
* @default - Retain cluster.
127+
* @default - RemovalPolicy.SNAPSHOT (remove the cluster and instances, but retain a snapshot of the data)
128128
*/
129-
readonly removalPolicy?: RemovalPolicy
129+
readonly removalPolicy?: RemovalPolicy;
130130

131131
/**
132132
* The interval, in seconds, between points when Amazon RDS collects enhanced
@@ -461,9 +461,16 @@ export class DatabaseCluster extends DatabaseClusterBase {
461461
storageEncrypted: props.kmsKey ? true : props.storageEncrypted,
462462
});
463463

464-
cluster.applyRemovalPolicy(props.removalPolicy, {
465-
applyToUpdateReplacePolicy: true,
466-
});
464+
// if removalPolicy was not specified,
465+
// leave it as the default, which is Snapshot
466+
if (props.removalPolicy) {
467+
cluster.applyRemovalPolicy(props.removalPolicy);
468+
} else {
469+
// The CFN default makes sense for DeletionPolicy,
470+
// but doesn't cover UpdateReplacePolicy.
471+
// Fix that here.
472+
cluster.cfnOptions.updateReplacePolicy = CfnDeletionPolicy.SNAPSHOT;
473+
}
467474

468475
this.clusterIdentifier = cluster.ref;
469476

@@ -519,9 +526,13 @@ export class DatabaseCluster extends DatabaseClusterBase {
519526
monitoringRoleArn: monitoringRole && monitoringRole.roleArn,
520527
});
521528

522-
instance.applyRemovalPolicy(props.removalPolicy, {
523-
applyToUpdateReplacePolicy: true,
524-
});
529+
// If removalPolicy isn't explicitly set,
530+
// it's Snapshot for Cluster.
531+
// Because of that, in this case,
532+
// we can safely use the CFN default of Delete for DbInstances with dbClusterIdentifier set.
533+
if (props.removalPolicy) {
534+
instance.applyRemovalPolicy(props.removalPolicy);
535+
}
525536

526537
// We must have a dependency on the NAT gateway provider here to create
527538
// things in the right order.

packages/@aws-cdk/aws-rds/lib/instance.ts

+17-12
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import * as kms from '@aws-cdk/aws-kms';
55
import * as lambda from '@aws-cdk/aws-lambda';
66
import * as logs from '@aws-cdk/aws-logs';
77
import * as secretsmanager from '@aws-cdk/aws-secretsmanager';
8-
import { Construct, Duration, IResource, Lazy, RemovalPolicy, Resource, SecretValue, Stack, Token } from '@aws-cdk/core';
8+
import { CfnDeletionPolicy, Construct, Duration, IResource, Lazy, RemovalPolicy, Resource, SecretValue, Stack, Token } from '@aws-cdk/core';
99
import { DatabaseSecret } from './database-secret';
1010
import { Endpoint } from './endpoint';
1111
import { IOptionGroup } from './option-group';
@@ -536,9 +536,9 @@ export interface DatabaseInstanceNewProps {
536536
* The CloudFormation policy to apply when the instance is removed from the
537537
* stack or replaced during an update.
538538
*
539-
* @default RemovalPolicy.Retain
539+
* @default - RemovalPolicy.SNAPSHOT (remove the resource, but retain a snapshot of the data)
540540
*/
541-
readonly removalPolicy?: RemovalPolicy
541+
readonly removalPolicy?: RemovalPolicy;
542542

543543
/**
544544
* Upper limit to which RDS can scale the storage in GiB(Gibibyte).
@@ -886,9 +886,7 @@ export class DatabaseInstance extends DatabaseInstanceSource implements IDatabas
886886
const portAttribute = Token.asNumber(instance.attrEndpointPort);
887887
this.instanceEndpoint = new Endpoint(instance.attrEndpointAddress, portAttribute);
888888

889-
instance.applyRemovalPolicy(props.removalPolicy, {
890-
applyToUpdateReplacePolicy: true,
891-
});
889+
applyInstanceDeletionPolicy(instance, props.removalPolicy);
892890

893891
if (secret) {
894892
this.secret = secret.attach(this);
@@ -984,9 +982,7 @@ export class DatabaseInstanceFromSnapshot extends DatabaseInstanceSource impleme
984982
const portAttribute = Token.asNumber(instance.attrEndpointPort);
985983
this.instanceEndpoint = new Endpoint(instance.attrEndpointAddress, portAttribute);
986984

987-
instance.applyRemovalPolicy(props.removalPolicy, {
988-
applyToUpdateReplacePolicy: true,
989-
});
985+
applyInstanceDeletionPolicy(instance, props.removalPolicy);
990986

991987
if (secret) {
992988
this.secret = secret.attach(this);
@@ -1054,9 +1050,7 @@ export class DatabaseInstanceReadReplica extends DatabaseInstanceNew implements
10541050
const portAttribute = Token.asNumber(instance.attrEndpointPort);
10551051
this.instanceEndpoint = new Endpoint(instance.attrEndpointAddress, portAttribute);
10561052

1057-
instance.applyRemovalPolicy(props.removalPolicy, {
1058-
applyToUpdateReplacePolicy: true,
1059-
});
1053+
applyInstanceDeletionPolicy(instance, props.removalPolicy);
10601054

10611055
this.setLogRetention();
10621056
}
@@ -1072,3 +1066,14 @@ function renderProcessorFeatures(features: ProcessorFeatures): CfnDBInstance.Pro
10721066

10731067
return featuresList.length === 0 ? undefined : featuresList;
10741068
}
1069+
1070+
function applyInstanceDeletionPolicy(cfnDbInstance: CfnDBInstance, removalPolicy: RemovalPolicy | undefined): void {
1071+
if (!removalPolicy) {
1072+
// the default DeletionPolicy is 'Snapshot', which is fine,
1073+
// but we should also make it 'Snapshot' for UpdateReplace policy
1074+
cfnDbInstance.cfnOptions.updateReplacePolicy = CfnDeletionPolicy.SNAPSHOT;
1075+
} else {
1076+
// just apply whatever removal policy the customer explicitly provided
1077+
cfnDbInstance.applyRemovalPolicy(removalPolicy);
1078+
}
1079+
}

packages/@aws-cdk/aws-rds/test/integ.cluster-rotation.lit.expected.json

+4-9
Original file line numberDiff line numberDiff line change
@@ -706,8 +706,7 @@
706706
}
707707
]
708708
},
709-
"UpdateReplacePolicy": "Retain",
710-
"DeletionPolicy": "Retain"
709+
"UpdateReplacePolicy": "Snapshot"
711710
},
712711
"DatabaseInstance1844F58FD": {
713712
"Type": "AWS::RDS::DBInstance",
@@ -725,9 +724,7 @@
725724
"VPCPrivateSubnet1DefaultRouteAE1D6490",
726725
"VPCPrivateSubnet2DefaultRouteF4F5CFD2",
727726
"VPCPrivateSubnet3DefaultRoute27F311AE"
728-
],
729-
"UpdateReplacePolicy": "Retain",
730-
"DeletionPolicy": "Retain"
727+
]
731728
},
732729
"DatabaseInstance2AA380DEE": {
733730
"Type": "AWS::RDS::DBInstance",
@@ -745,9 +742,7 @@
745742
"VPCPrivateSubnet1DefaultRouteAE1D6490",
746743
"VPCPrivateSubnet2DefaultRouteF4F5CFD2",
747744
"VPCPrivateSubnet3DefaultRoute27F311AE"
748-
],
749-
"UpdateReplacePolicy": "Retain",
750-
"DeletionPolicy": "Retain"
745+
]
751746
},
752747
"DatabaseRotationSingleUserSecurityGroupAC6E0E73": {
753748
"Type": "AWS::EC2::SecurityGroup",
@@ -817,4 +812,4 @@
817812
}
818813
}
819814
}
820-
}
815+
}

packages/@aws-cdk/aws-rds/test/integ.cluster-s3.expected.json

+4-9
Original file line numberDiff line numberDiff line change
@@ -668,8 +668,7 @@
668668
}
669669
]
670670
},
671-
"UpdateReplacePolicy": "Retain",
672-
"DeletionPolicy": "Retain"
671+
"UpdateReplacePolicy": "Snapshot"
673672
},
674673
"DatabaseInstance1844F58FD": {
675674
"Type": "AWS::RDS::DBInstance",
@@ -687,9 +686,7 @@
687686
"DependsOn": [
688687
"VPCPublicSubnet1DefaultRoute91CEF279",
689688
"VPCPublicSubnet2DefaultRouteB7481BBA"
690-
],
691-
"UpdateReplacePolicy": "Retain",
692-
"DeletionPolicy": "Retain"
689+
]
693690
},
694691
"DatabaseInstance2AA380DEE": {
695692
"Type": "AWS::RDS::DBInstance",
@@ -707,9 +704,7 @@
707704
"DependsOn": [
708705
"VPCPublicSubnet1DefaultRoute91CEF279",
709706
"VPCPublicSubnet2DefaultRouteB7481BBA"
710-
],
711-
"UpdateReplacePolicy": "Retain",
712-
"DeletionPolicy": "Retain"
707+
]
713708
}
714709
}
715-
}
710+
}

packages/@aws-cdk/aws-rds/test/integ.cluster.expected.json

+4-9
Original file line numberDiff line numberDiff line change
@@ -500,8 +500,7 @@
500500
}
501501
]
502502
},
503-
"UpdateReplacePolicy": "Retain",
504-
"DeletionPolicy": "Retain"
503+
"UpdateReplacePolicy": "Snapshot"
505504
},
506505
"DatabaseInstance1844F58FD": {
507506
"Type": "AWS::RDS::DBInstance",
@@ -519,9 +518,7 @@
519518
"DependsOn": [
520519
"VPCPublicSubnet1DefaultRoute91CEF279",
521520
"VPCPublicSubnet2DefaultRouteB7481BBA"
522-
],
523-
"UpdateReplacePolicy": "Retain",
524-
"DeletionPolicy": "Retain"
521+
]
525522
},
526523
"DatabaseInstance2AA380DEE": {
527524
"Type": "AWS::RDS::DBInstance",
@@ -539,9 +536,7 @@
539536
"DependsOn": [
540537
"VPCPublicSubnet1DefaultRoute91CEF279",
541538
"VPCPublicSubnet2DefaultRouteB7481BBA"
542-
],
543-
"UpdateReplacePolicy": "Retain",
544-
"DeletionPolicy": "Retain"
539+
]
545540
}
546541
}
547-
}
542+
}

packages/@aws-cdk/aws-rds/test/integ.instance.lit.expected.json

+2-3
Original file line numberDiff line numberDiff line change
@@ -694,8 +694,7 @@
694694
}
695695
]
696696
},
697-
"UpdateReplacePolicy": "Retain",
698-
"DeletionPolicy": "Retain"
697+
"UpdateReplacePolicy": "Snapshot"
699698
},
700699
"InstanceLogRetentiontrace487771C8": {
701700
"Type": "Custom::LogRetention",
@@ -1122,4 +1121,4 @@
11221121
"Description": "Artifact hash for asset \"82c54bfa7c42ba410d6d18dad983ba51c93a5ea940818c5c20230f8b59c19d4e\""
11231122
}
11241123
}
1125-
}
1124+
}

packages/@aws-cdk/aws-rds/test/test.cluster.ts

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { expect, haveResource, ResourcePart, SynthUtils } from '@aws-cdk/assert';
1+
import { ABSENT, countResources, expect, haveResource, ResourcePart, SynthUtils } from '@aws-cdk/assert';
22
import * as ec2 from '@aws-cdk/aws-ec2';
33
import { ManagedPolicy, Role, ServicePrincipal } from '@aws-cdk/aws-iam';
44
import * as kms from '@aws-cdk/aws-kms';
@@ -8,7 +8,7 @@ import { Test } from 'nodeunit';
88
import { ClusterParameterGroup, DatabaseCluster, DatabaseClusterEngine, ParameterGroup } from '../lib';
99

1010
export = {
11-
'check that instantiation works'(test: Test) {
11+
'creating a Cluster also creates 2 DB Instances'(test: Test) {
1212
// GIVEN
1313
const stack = testStack();
1414
const vpc = new ec2.Vpc(stack, 'VPC');
@@ -35,17 +35,19 @@ export = {
3535
MasterUserPassword: 'tooshort',
3636
VpcSecurityGroupIds: [ {'Fn::GetAtt': ['DatabaseSecurityGroup5C91FDCB', 'GroupId']}],
3737
},
38-
DeletionPolicy: 'Retain',
39-
UpdateReplacePolicy: 'Retain',
38+
DeletionPolicy: ABSENT,
39+
UpdateReplacePolicy: 'Snapshot',
4040
}, ResourcePart.CompleteDefinition));
4141

42+
expect(stack).to(countResources('AWS::RDS::DBInstance', 2));
4243
expect(stack).to(haveResource('AWS::RDS::DBInstance', {
43-
DeletionPolicy: 'Retain',
44-
UpdateReplacePolicy: 'Retain',
44+
DeletionPolicy: ABSENT,
45+
UpdateReplacePolicy: ABSENT,
4546
}, ResourcePart.CompleteDefinition));
4647

4748
test.done();
4849
},
50+
4951
'can create a cluster with a single instance'(test: Test) {
5052
// GIVEN
5153
const stack = testStack();

packages/@aws-cdk/aws-rds/test/test.instance.ts

+3-8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { countResources, expect, haveResource, ResourcePart } from '@aws-cdk/assert';
1+
import { ABSENT, countResources, expect, haveResource, ResourcePart } from '@aws-cdk/assert';
22
import * as ec2 from '@aws-cdk/aws-ec2';
33
import * as targets from '@aws-cdk/aws-events-targets';
44
import { ManagedPolicy, Role, ServicePrincipal } from '@aws-cdk/aws-iam';
@@ -105,13 +105,8 @@ export = {
105105
},
106106
],
107107
},
108-
DeletionPolicy: 'Retain',
109-
UpdateReplacePolicy: 'Retain',
110-
}, ResourcePart.CompleteDefinition));
111-
112-
expect(stack).to(haveResource('AWS::RDS::DBInstance', {
113-
DeletionPolicy: 'Retain',
114-
UpdateReplacePolicy: 'Retain',
108+
DeletionPolicy: ABSENT,
109+
UpdateReplacePolicy: 'Snapshot',
115110
}, ResourcePart.CompleteDefinition));
116111

117112
expect(stack).to(haveResource('AWS::RDS::DBSubnetGroup', {

packages/@aws-cdk/core/lib/cfn-resource.ts

+4
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ export class CfnResource extends CfnRefElement {
116116
deletionPolicy = CfnDeletionPolicy.RETAIN;
117117
break;
118118

119+
case RemovalPolicy.SNAPSHOT:
120+
deletionPolicy = CfnDeletionPolicy.SNAPSHOT;
121+
break;
122+
119123
default:
120124
throw new Error(`Invalid removal policy: ${policy}`);
121125
}

packages/@aws-cdk/core/lib/removal-policy.ts

+11
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@ export enum RemovalPolicy {
1010
* in the account, but orphaned from the stack.
1111
*/
1212
RETAIN = 'retain',
13+
14+
/**
15+
* This retention policy deletes the resource,
16+
* but saves a snapshot of its data before deleting,
17+
* so that it can be re-created later.
18+
* Only available for some stateful resources,
19+
* like databases, EFS volumes, etc.
20+
*
21+
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html#aws-attribute-deletionpolicy-options
22+
*/
23+
SNAPSHOT = 'snapshot',
1324
}
1425

1526
export interface RemovalPolicyOptions {

0 commit comments

Comments
 (0)