From 58574b571b01502c497e14583934303254f06a05 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Mon, 7 Oct 2024 00:28:08 +0900 Subject: [PATCH] feat(kms): allow fromLookup method to return a dummy key if target key was not found --- .../cdk.out | 1 + .../integ.json | 13 ++ .../key-from-lookup-dummy.assets.json | 20 +++ .../key-from-lookup-dummy.template.json | 41 ++++++ ...efaultTestDeployAssert59B83056.assets.json | 19 +++ ...aultTestDeployAssert59B83056.template.json | 36 +++++ .../manifest.json | 131 ++++++++++++++++++ .../tree.json | 117 ++++++++++++++++ .../test/integ.key-from-lookup-dummy.ts | 21 +++ .../aws-cdk-lib/aws-kms/lib/key-lookup.ts | 11 ++ packages/aws-cdk-lib/aws-kms/lib/key.ts | 4 + .../aws-kms/test/key.from-lookup.test.ts | 29 +++- .../aws-cdk-lib/core/lib/context-provider.ts | 2 +- .../aws-cdk/lib/context-providers/keys.ts | 6 + .../test/context-providers/keys.test.ts | 27 ++++ 15 files changed, 476 insertions(+), 2 deletions(-) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/key-from-lookup-dummy.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/key-from-lookup-dummy.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/keyfromlookupdummyintegDefaultTestDeployAssert59B83056.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/keyfromlookupdummyintegDefaultTestDeployAssert59B83056.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/tree.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/cdk.out new file mode 100644 index 0000000000000..c6e612584e352 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"38.0.1"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/integ.json new file mode 100644 index 0000000000000..a023d9784bef3 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/integ.json @@ -0,0 +1,13 @@ +{ + "enableLookups": true, + "version": "38.0.1", + "testCases": { + "key-from-lookup-dummy-integ/DefaultTest": { + "stacks": [ + "key-from-lookup-dummy" + ], + "assertionStack": "key-from-lookup-dummy-integ/DefaultTest/DeployAssert", + "assertionStackName": "keyfromlookupdummyintegDefaultTestDeployAssert59B83056" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/key-from-lookup-dummy.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/key-from-lookup-dummy.assets.json new file mode 100644 index 0000000000000..1675ef6086d66 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/key-from-lookup-dummy.assets.json @@ -0,0 +1,20 @@ +{ + "version": "38.0.1", + "files": { + "108859781ef94bf4058c98d631d659c64aaa91ada86b02972458aeb561fc24da": { + "source": { + "path": "key-from-lookup-dummy.template.json", + "packaging": "file" + }, + "destinations": { + "12345678-test-region": { + "bucketName": "cdk-hnb659fds-assets-12345678-test-region", + "objectKey": "108859781ef94bf4058c98d631d659c64aaa91ada86b02972458aeb561fc24da.json", + "region": "test-region", + "assumeRoleArn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-file-publishing-role-12345678-test-region" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/key-from-lookup-dummy.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/key-from-lookup-dummy.template.json new file mode 100644 index 0000000000000..4e2669a9be1cf --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/key-from-lookup-dummy.template.json @@ -0,0 +1,41 @@ +{ + "Outputs": { + "KeyId": { + "Value": "1234abcd-12ab-34cd-56ef-1234567890ab" + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/keyfromlookupdummyintegDefaultTestDeployAssert59B83056.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/keyfromlookupdummyintegDefaultTestDeployAssert59B83056.assets.json new file mode 100644 index 0000000000000..063d18ecc9628 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/keyfromlookupdummyintegDefaultTestDeployAssert59B83056.assets.json @@ -0,0 +1,19 @@ +{ + "version": "38.0.1", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "keyfromlookupdummyintegDefaultTestDeployAssert59B83056.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/keyfromlookupdummyintegDefaultTestDeployAssert59B83056.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/keyfromlookupdummyintegDefaultTestDeployAssert59B83056.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/keyfromlookupdummyintegDefaultTestDeployAssert59B83056.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/manifest.json new file mode 100644 index 0000000000000..db3d05518cb56 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/manifest.json @@ -0,0 +1,131 @@ +{ + "version": "38.0.1", + "artifacts": { + "key-from-lookup-dummy.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "key-from-lookup-dummy.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "key-from-lookup-dummy": { + "type": "aws:cloudformation:stack", + "environment": "aws://12345678/test-region", + "properties": { + "templateFile": "key-from-lookup-dummy.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "notificationArns": [], + "assumeRoleArn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-deploy-role-12345678-test-region", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-cfn-exec-role-12345678-test-region", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-12345678-test-region/108859781ef94bf4058c98d631d659c64aaa91ada86b02972458aeb561fc24da.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "key-from-lookup-dummy.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-lookup-role-12345678-test-region", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "key-from-lookup-dummy.assets" + ], + "metadata": { + "/key-from-lookup-dummy/KeyId": [ + { + "type": "aws:cdk:logicalId", + "data": "KeyId" + } + ], + "/key-from-lookup-dummy/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/key-from-lookup-dummy/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "key-from-lookup-dummy" + }, + "keyfromlookupdummyintegDefaultTestDeployAssert59B83056.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "keyfromlookupdummyintegDefaultTestDeployAssert59B83056.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "keyfromlookupdummyintegDefaultTestDeployAssert59B83056": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "keyfromlookupdummyintegDefaultTestDeployAssert59B83056.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "notificationArns": [], + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "keyfromlookupdummyintegDefaultTestDeployAssert59B83056.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "keyfromlookupdummyintegDefaultTestDeployAssert59B83056.assets" + ], + "metadata": { + "/key-from-lookup-dummy-integ/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/key-from-lookup-dummy-integ/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "key-from-lookup-dummy-integ/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + }, + "missing": [ + { + "key": "key-provider:account=12345678:aliasName=alias/foo:region=test-region", + "provider": "key-provider", + "props": { + "dummyValue": { + "keyId": "1234abcd-12ab-34cd-56ef-1234567890ab" + }, + "ignoreErrorOnMissingContext": true, + "account": "12345678", + "region": "test-region", + "aliasName": "alias/foo", + "lookupRoleArn": "arn:${AWS::Partition}:iam::12345678:role/cdk-hnb659fds-lookup-role-12345678-test-region" + } + } + ] +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/tree.json new file mode 100644 index 0000000000000..d5f07caf4914b --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.js.snapshot/tree.json @@ -0,0 +1,117 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "key-from-lookup-dummy": { + "id": "key-from-lookup-dummy", + "path": "key-from-lookup-dummy", + "children": { + "Key": { + "id": "Key", + "path": "key-from-lookup-dummy/Key", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "KeyId": { + "id": "KeyId", + "path": "key-from-lookup-dummy/KeyId", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "key-from-lookup-dummy/BootstrapVersion", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "key-from-lookup-dummy/CheckBootstrapVersion", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "key-from-lookup-dummy-integ": { + "id": "key-from-lookup-dummy-integ", + "path": "key-from-lookup-dummy-integ", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "key-from-lookup-dummy-integ/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "key-from-lookup-dummy-integ/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "key-from-lookup-dummy-integ/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "key-from-lookup-dummy-integ/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "key-from-lookup-dummy-integ/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.ts new file mode 100644 index 0000000000000..dfa90c95fe79f --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-from-lookup-dummy.ts @@ -0,0 +1,21 @@ +import * as cdk from 'aws-cdk-lib/core'; +import * as integ from '@aws-cdk/integ-tests-alpha'; +import { Key } from 'aws-cdk-lib/aws-kms'; + +const app = new cdk.App(); + +const stack = new cdk.Stack(app, 'key-from-lookup-dummy', { + env: { + account: process.env.CDK_INTEG_ACCOUNT ?? process.env.CDK_DEFAULT_ACCOUNT, + region: process.env.CDK_INTEG_REGION ?? process.env.CDK_DEFAULT_REGION, + }, +}); + +const dummy = Key.fromLookup(stack, 'Key', { aliasName: 'alias/foo', returnDummyKeyOnMissing: true }); + +new cdk.CfnOutput(stack, 'KeyId', { value: dummy.keyId }); + +new integ.IntegTest(app, 'key-from-lookup-dummy-integ', { + enableLookups: true, + testCases: [stack], +}); diff --git a/packages/aws-cdk-lib/aws-kms/lib/key-lookup.ts b/packages/aws-cdk-lib/aws-kms/lib/key-lookup.ts index 0ac02b2185d49..8261aec83307e 100644 --- a/packages/aws-cdk-lib/aws-kms/lib/key-lookup.ts +++ b/packages/aws-cdk-lib/aws-kms/lib/key-lookup.ts @@ -8,4 +8,15 @@ export interface KeyLookupOptions { * Must be in the format `alias/`. */ readonly aliasName: string; + + /** + * Whether to return a dummy key if the key was not found. + * + * If it is set to `true` and the key was not found, a dummy + * key with a key id '1234abcd-12ab-34cd-56ef-1234567890ab' + * will be returned. + * + * @default false + */ + readonly returnDummyKeyOnMissing?: boolean; } diff --git a/packages/aws-cdk-lib/aws-kms/lib/key.ts b/packages/aws-cdk-lib/aws-kms/lib/key.ts index 7cdd14fc546e0..e2a5bc478cc2e 100644 --- a/packages/aws-cdk-lib/aws-kms/lib/key.ts +++ b/packages/aws-cdk-lib/aws-kms/lib/key.ts @@ -651,6 +651,9 @@ export class Key extends KeyBase { * You can therefore not use any values that will only be available at * CloudFormation execution time (i.e., Tokens). * + * If you set `returnDummyKeyOnMissing` to `true` in `options` and the key was not found, + * this method will return a dummy key with a key id '1234abcd-12ab-34cd-56ef-1234567890ab'. + * * The Key information will be cached in `cdk.context.json` and the same Key * will be used on future runs. To refresh the lookup, you will have to * evict the value from the cache using the `cdk context` command. See @@ -685,6 +688,7 @@ export class Key extends KeyBase { dummyValue: { keyId: '1234abcd-12ab-34cd-56ef-1234567890ab', }, + ignoreErrorOnMissingContext: options.returnDummyKeyOnMissing, }).value; return new Import(attributes.keyId, diff --git a/packages/aws-cdk-lib/aws-kms/test/key.from-lookup.test.ts b/packages/aws-cdk-lib/aws-kms/test/key.from-lookup.test.ts index 34af7d0030d9f..c1c271e617bd8 100644 --- a/packages/aws-cdk-lib/aws-kms/test/key.from-lookup.test.ts +++ b/packages/aws-cdk-lib/aws-kms/test/key.from-lookup.test.ts @@ -1,6 +1,6 @@ import { Construct } from 'constructs'; import * as cxschema from '../../cloud-assembly-schema'; -import { ContextProvider, GetContextValueOptions, GetContextValueResult, Lazy, Stack } from '../../core'; +import { App, ContextProvider, GetContextValueOptions, GetContextValueResult, Lazy, Stack } from '../../core'; import * as cxapi from '../../cx-api'; import { Key } from '../lib'; @@ -39,6 +39,33 @@ test('return correct key', () => { restoreContextProvider(previous); }); +test('return dummy key if returnDummyKeyOnMissing is true', () => { + const app = new App(); + const stack = new Stack(app, 'MyStack', { env: { region: 'us-east-1', account: '123456789012' } }); + const key = Key.fromLookup(stack, 'Key', { + aliasName: 'alias/foo', + returnDummyKeyOnMissing: true, + }); + + expect(key.keyId).toEqual('1234abcd-12ab-34cd-56ef-1234567890ab'); + expect(app.synth().manifest.missing).toEqual([ + { + key: 'key-provider:account=123456789012:aliasName=alias/foo:region=us-east-1', + props: { + account: '123456789012', + aliasName: 'alias/foo', + ignoreErrorOnMissingContext: true, + lookupRoleArn: 'arn:${AWS::Partition}:iam::123456789012:role/cdk-hnb659fds-lookup-role-123456789012-us-east-1', + dummyValue: { + keyId: '1234abcd-12ab-34cd-56ef-1234567890ab', + }, + region: 'us-east-1', + }, + provider: 'key-provider', + }, + ]); +}); + interface MockKeyContextResponse { readonly keyId: string; } diff --git a/packages/aws-cdk-lib/core/lib/context-provider.ts b/packages/aws-cdk-lib/core/lib/context-provider.ts index fb4cdd00496c2..b58405098174b 100644 --- a/packages/aws-cdk-lib/core/lib/context-provider.ts +++ b/packages/aws-cdk-lib/core/lib/context-provider.ts @@ -117,7 +117,7 @@ export class ContextProvider { // We'll store the extendedProps in the missingContextKey report // so that we can retrieve the dummyValue and ignoreError flag - // in the aws-cdk's ssm-context provider + // in the aws-cdk's ssm-context and kms key provider stack.reportMissingContextKey({ key, provider: options.provider as cxschema.ContextProvider, diff --git a/packages/aws-cdk/lib/context-providers/keys.ts b/packages/aws-cdk/lib/context-providers/keys.ts index 52c5dd08f140d..270714f7be3a2 100644 --- a/packages/aws-cdk/lib/context-providers/keys.ts +++ b/packages/aws-cdk/lib/context-providers/keys.ts @@ -40,6 +40,12 @@ export class KeyContextProviderPlugin implements ContextProviderPlugin { nextMarker = response.NextMarker; } while (response.Truncated); + const suppressError = 'ignoreErrorOnMissingContext' in args && args.ignoreErrorOnMissingContext as boolean; + const hasDummyKeyId = 'dummyValue' in args && typeof args.dummyValue === 'object' && args.dummyValue !== null && 'keyId' in args.dummyValue; + if (suppressError && hasDummyKeyId) { + const keyId = (args.dummyValue as { keyId: string }).keyId; + return { TargetKeyId: keyId }; + } throw new Error(`Could not find any key with alias named ${args.aliasName}`); } diff --git a/packages/aws-cdk/test/context-providers/keys.test.ts b/packages/aws-cdk/test/context-providers/keys.test.ts index 2503110745963..d46ea86b3f2f6 100644 --- a/packages/aws-cdk/test/context-providers/keys.test.ts +++ b/packages/aws-cdk/test/context-providers/keys.test.ts @@ -152,5 +152,32 @@ test('throw exception - no key found', async () => { region: 'us-east-1', aliasName: 'alias/foo', })).rejects.toThrow(/Could not find any key with alias named/); +}); + +test('don\'t throw exception - no key found but ignoreErrorOnMissingContext is true', async () => { + // GIVEN + const provider = new KeyContextProviderPlugin(mockSDK); + + AWS.mock('KMS', 'listAliases', (params: aws.KMS.ListAliasesRequest, cb: AwsCallback) => { + expect(params.KeyId).toBeUndefined(); + return cb(null, { + }); + }); + // WHEN + const args = { + account: '1234', + region: 'us-east-1', + aliasName: 'alias/foo', + dummyValue: { + keyId: '1234abcd-12ab-34cd-56ef-1234567890ab', + }, + ignoreErrorOnMissingContext: true, + }; + const result = await provider.getValue(args); + + // THEN + expect(result).toEqual({ + keyId: '1234abcd-12ab-34cd-56ef-1234567890ab', + }); }); \ No newline at end of file