From da10d7434c3966ded952d1f56b5fb90c6273c5d1 Mon Sep 17 00:00:00 2001 From: Nick Lynch Date: Mon, 28 Sep 2020 10:28:47 +0100 Subject: [PATCH] fix(secretsmanager): cannot import secrets if ARN is a token The feature to support importing secrets by name (#10309) failed to handle scenarios where the secret ARN is a token, due to parsing the ARN to retrieve the secret name. fixes #10520 --- .../@aws-cdk/aws-secretsmanager/lib/secret.ts | 9 ++++++- .../aws-secretsmanager/test/test.secret.ts | 24 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-secretsmanager/lib/secret.ts b/packages/@aws-cdk/aws-secretsmanager/lib/secret.ts index c4539cca154ea..d0a350fb73031 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, IConstruct, IResource, RemovalPolicy, Resource, SecretValue, Stack } from '@aws-cdk/core'; +import { Construct, Fn, IConstruct, IResource, RemovalPolicy, Resource, SecretValue, Stack, Token } from '@aws-cdk/core'; import { ResourcePolicy } from './policy'; import { RotationSchedule, RotationScheduleOptions } from './rotation-schedule'; import * as secretsmanager from './secretsmanager.generated'; @@ -596,6 +596,13 @@ export interface SecretStringGenerator { /** Parses the secret name from the ARN. */ function parseSecretName(construct: IConstruct, secretArn: string) { + if (Token.isUnresolved(secretArn)) { + // Split the ARN by ':' to get the resource name; + // note that this returns the full secret name (vs the "friendly name" without the suffix) + // because there is no reasonable way to get the last index of the suffix delimiter ('-'). + return Fn.select(6, Fn.split(':', secretArn)); + } + const resourceName = Stack.of(construct).parseArn(secretArn).resourceName; if (resourceName) { // Secret resource names are in the format `${secretName}-${SecretsManager suffix}` diff --git a/packages/@aws-cdk/aws-secretsmanager/test/test.secret.ts b/packages/@aws-cdk/aws-secretsmanager/test/test.secret.ts index 1b7c1e3063ed9..523ce501b9126 100644 --- a/packages/@aws-cdk/aws-secretsmanager/test/test.secret.ts +++ b/packages/@aws-cdk/aws-secretsmanager/test/test.secret.ts @@ -482,6 +482,30 @@ export = { test.done(); }, + 'import by secretArn supports tokens for ARNs'(test: Test) { + // GIVEN + const app = new cdk.App(); + const stackA = new cdk.Stack(app, 'StackA'); + const stackB = new cdk.Stack(app, 'StackB'); + const secretA = new secretsmanager.Secret(stackA, 'SecretA'); + + // WHEN + const secretB = secretsmanager.Secret.fromSecretArn(stackB, 'SecretB', secretA.secretArn); + new cdk.CfnOutput(stackB, 'secretBSecretName', { value: secretB.secretName }); + + // THEN + test.equals(secretB.secretArn, secretA.secretArn); + expect(stackB).toMatch({ + Outputs: { + secretBSecretName: { + Value: { 'Fn::Select': [6, { 'Fn::Split': [':', { 'Fn::ImportValue': 'StackA:ExportsOutputRefSecretA188F281703FC8A52' }] }] }, + }, + }, + }); + + test.done(); + }, + 'import by attributes'(test: Test) { // GIVEN const stack = new cdk.Stack();