From cee70dcb908a05e8c8241f27517715135906be54 Mon Sep 17 00:00:00 2001 From: winky Date: Tue, 26 May 2020 01:58:57 +0900 Subject: [PATCH 1/2] feat(secretsmanager): deletionPolicy for secretsmanager We often store important values on secretsmanager.Secret. But, without DeletionPolicy(Retain), it can be deleted by human error. closes: #6527 --- .../@aws-cdk/aws-secretsmanager/lib/secret.ts | 13 +++++++++++- .../aws-secretsmanager/test/test.secret.ts | 21 ++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-secretsmanager/lib/secret.ts b/packages/@aws-cdk/aws-secretsmanager/lib/secret.ts index 4bb50b68aa684..9f66160b91acc 100644 --- a/packages/@aws-cdk/aws-secretsmanager/lib/secret.ts +++ b/packages/@aws-cdk/aws-secretsmanager/lib/secret.ts @@ -1,6 +1,6 @@ import * as iam from '@aws-cdk/aws-iam'; import * as kms from '@aws-cdk/aws-kms'; -import { Construct, IResource, Resource, SecretValue, Stack } from '@aws-cdk/core'; +import { Construct, IResource, RemovalPolicy, Resource, SecretValue, Stack } from '@aws-cdk/core'; import { ResourcePolicy } from './policy'; import { RotationSchedule, RotationScheduleOptions } from './rotation-schedule'; import * as secretsmanager from './secretsmanager.generated'; @@ -102,6 +102,13 @@ export interface SecretProps { * @default - A name is generated by CloudFormation. */ readonly secretName?: string; + + /** + * Policy to apply when the secret is removed from this stack. + * + * @default - Not set. + */ + readonly removalPolicy?: RemovalPolicy; } /** @@ -260,6 +267,10 @@ export class Secret extends SecretBase { name: this.physicalName, }); + if (props.removalPolicy) { + resource.applyRemovalPolicy(props.removalPolicy); + } + this.secretArn = this.getResourceArnAttribute(resource.ref, { service: 'secretsmanager', resource: 'secret', diff --git a/packages/@aws-cdk/aws-secretsmanager/test/test.secret.ts b/packages/@aws-cdk/aws-secretsmanager/test/test.secret.ts index 3b043eb562a97..e9409d330e7ec 100644 --- a/packages/@aws-cdk/aws-secretsmanager/test/test.secret.ts +++ b/packages/@aws-cdk/aws-secretsmanager/test/test.secret.ts @@ -1,4 +1,4 @@ -import { expect, haveResource, haveResourceLike } from '@aws-cdk/assert'; +import { expect, haveResource, haveResourceLike, ResourcePart } from '@aws-cdk/assert'; import * as iam from '@aws-cdk/aws-iam'; import * as kms from '@aws-cdk/aws-kms'; import * as lambda from '@aws-cdk/aws-lambda'; @@ -22,6 +22,25 @@ export = { test.done(); }, + 'set removalPolicy to secret'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new secretsmanager.Secret(stack, 'Secret', { + removalPolicy: cdk.RemovalPolicy.RETAIN, + }); + + // THEN + expect(stack).to(haveResourceLike('AWS::SecretsManager::Secret', + { + DeletionPolicy: 'Retain', + }, ResourcePart.CompleteDefinition, + )); + + test.done(); + }, + 'secret with kms'(test: Test) { // GIVEN const stack = new cdk.Stack(); From 2f26b122b01a57a0716600893f58396a927d540f Mon Sep 17 00:00:00 2001 From: winky Date: Tue, 26 May 2020 05:22:30 +0900 Subject: [PATCH 2/2] fix: lint error --- packages/@aws-cdk/aws-secretsmanager/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/@aws-cdk/aws-secretsmanager/README.md b/packages/@aws-cdk/aws-secretsmanager/README.md index 920b4d4146bf5..fb3a61e920725 100644 --- a/packages/@aws-cdk/aws-secretsmanager/README.md +++ b/packages/@aws-cdk/aws-secretsmanager/README.md @@ -39,6 +39,8 @@ const secret = secretsmanager.Secret.fromSecretAttributes(scope, 'ImportedSecret SecretsManager secret values can only be used in select set of properties. For the list of properties, see [the CloudFormation Dynamic References documentation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/dynamic-references.html). +A secret can set `RemovalPolicy`. If it set to `RETAIN`, that removing a secret will fail. + ### Grant permission to use the secret to a role You must grant permission to a resource for that resource to be allowed to