From b33b9b0a3ce2cfd79082bb743b36c6fda9e8278b Mon Sep 17 00:00:00 2001 From: Momo Kornher Date: Tue, 25 Oct 2022 20:51:15 +0100 Subject: [PATCH] fix(ssm): `StringParameter.fromSecureStringParameterAttributes` not working without version (#22618) It is possible to omit the `version` of an SSM SecureString parameter. When omitted, the reference generated by CDK results in a ValidationError when applying the changes. e.g. ``` Error [ValidationError]: Incorrect format is used in the following SSM reference: [{{resolve:ssm-secure:/some/parameter:}}] ``` Related to #18729 Replaces #22311 ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Unconventional Dependencies: * [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies) ### New Features * [x] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [x] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-ssm/README.md | 26 +- packages/@aws-cdk/aws-ssm/lib/parameter.ts | 5 +- ...lit.ts => integ.parameter-store-string.ts} | 64 +- .../index.js | 768 ++++++++++++++++++ .../cdk.out | 1 + .../integ.json | 12 + .../manifest.json | 214 +++++ .../sspms-cleanup.assets.json | 32 + .../sspms-cleanup.template.json | 119 +++ .../sspms-creating.assets.json | 32 + .../sspms-creating.template.json | 129 +++ .../sspms-using.assets.json | 19 + .../sspms-using.template.json | 90 ++ .../tree.json | 329 ++++++++ .../cdk.out | 1 - .../integ.json | 14 - .../manifest.json | 72 -- .../sspms-creating.template.json | 12 - .../sspms-using.template.json | 38 - .../tree.json | 139 ---- .../@aws-cdk/aws-ssm/test/parameter.test.ts | 2 +- 21 files changed, 1823 insertions(+), 295 deletions(-) rename packages/@aws-cdk/aws-ssm/test/{integ.parameter-store-string.lit.ts => integ.parameter-store-string.ts} (58%) create mode 100644 packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/asset.b54b99043c35bd080b9d9d1afce31e3541cf15b679799ba980ed40c837dcb03b.bundle/index.js create mode 100644 packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/cdk.out create mode 100644 packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/integ.json create mode 100644 packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/manifest.json create mode 100644 packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/sspms-cleanup.assets.json create mode 100644 packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/sspms-cleanup.template.json create mode 100644 packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/sspms-creating.assets.json create mode 100644 packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/sspms-creating.template.json create mode 100644 packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/sspms-using.assets.json create mode 100644 packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/sspms-using.template.json create mode 100644 packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/tree.json delete mode 100644 packages/@aws-cdk/aws-ssm/test/parameter-store-string.lit.integ.snapshot/cdk.out delete mode 100644 packages/@aws-cdk/aws-ssm/test/parameter-store-string.lit.integ.snapshot/integ.json delete mode 100644 packages/@aws-cdk/aws-ssm/test/parameter-store-string.lit.integ.snapshot/manifest.json delete mode 100644 packages/@aws-cdk/aws-ssm/test/parameter-store-string.lit.integ.snapshot/sspms-creating.template.json delete mode 100644 packages/@aws-cdk/aws-ssm/test/parameter-store-string.lit.integ.snapshot/sspms-using.template.json delete mode 100644 packages/@aws-cdk/aws-ssm/test/parameter-store-string.lit.integ.snapshot/tree.json diff --git a/packages/@aws-cdk/aws-ssm/README.md b/packages/@aws-cdk/aws-ssm/README.md index a96bf50d7d752..7c8fdbb9bd003 100644 --- a/packages/@aws-cdk/aws-ssm/README.md +++ b/packages/@aws-cdk/aws-ssm/README.md @@ -18,7 +18,31 @@ This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aw You can reference existing SSM Parameter Store values that you want to use in your CDK app by using `ssm.StringParameter.fromStringParameterAttributes`: -[using SSM parameter](test/integ.parameter-store-string.lit.ts) +```ts +// Retrieve the latest value of the non-secret parameter +// with name "/My/String/Parameter". +const stringValue = ssm.StringParameter.fromStringParameterAttributes(this, 'MyValue', { + parameterName: '/My/Public/Parameter', + // 'version' can be specified but is optional. +}).stringValue; +const stringValueVersionFromToken = ssm.StringParameter.fromStringParameterAttributes(this, 'MyValueVersionFromToken', { + parameterName: '/My/Public/Parameter', + // parameter version from token + version: parameterVersion, +}).stringValue; + +// Retrieve a specific version of the secret (SecureString) parameter. +// 'version' is always required. +const secretValue = ssm.StringParameter.fromSecureStringParameterAttributes(this, 'MySecureValue', { + parameterName: '/My/Secret/Parameter', + version: 5, +}); +const secretValueVersionFromToken = ssm.StringParameter.fromSecureStringParameterAttributes(this, 'MySecureValueVersionFromToken', { + parameterName: '/My/Secret/Parameter', + // parameter version from token + version: parameterVersion, +}); +``` You can also reference an existing SSM Parameter Store value that matches an [AWS specific parameter type](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html#aws-specific-parameter-types): diff --git a/packages/@aws-cdk/aws-ssm/lib/parameter.ts b/packages/@aws-cdk/aws-ssm/lib/parameter.ts index f24e4d0375108..5721cd30e922d 100644 --- a/packages/@aws-cdk/aws-ssm/lib/parameter.ts +++ b/packages/@aws-cdk/aws-ssm/lib/parameter.ts @@ -492,7 +492,10 @@ export class StringParameter extends ParameterBase implements IStringParameter { */ public static fromSecureStringParameterAttributes(scope: Construct, id: string, attrs: SecureStringParameterAttributes): IStringParameter { const version = attrs.version ? Tokenization.stringifyNumber(attrs.version) : ''; - const stringValue = new CfnDynamicReference(CfnDynamicReferenceService.SSM_SECURE, `${attrs.parameterName}:${version}`).toString(); + const stringValue = new CfnDynamicReference( + CfnDynamicReferenceService.SSM_SECURE, + version ? `${attrs.parameterName}:${version}` : attrs.parameterName, + ).toString(); class Import extends ParameterBase { public readonly parameterName = attrs.parameterName; diff --git a/packages/@aws-cdk/aws-ssm/test/integ.parameter-store-string.lit.ts b/packages/@aws-cdk/aws-ssm/test/integ.parameter-store-string.ts similarity index 58% rename from packages/@aws-cdk/aws-ssm/test/integ.parameter-store-string.lit.ts rename to packages/@aws-cdk/aws-ssm/test/integ.parameter-store-string.ts index 09e0f6f17f01f..7386e9ff03fef 100644 --- a/packages/@aws-cdk/aws-ssm/test/integ.parameter-store-string.lit.ts +++ b/packages/@aws-cdk/aws-ssm/test/integ.parameter-store-string.ts @@ -1,14 +1,26 @@ -/// !cdk-integ * import * as cdk from '@aws-cdk/core'; +import * as integ from '@aws-cdk/integ-tests'; import * as ssm from '../lib'; +const SECURE_PARAM_NAME = '/My/Secret/Parameter'; + class CreatingStack extends cdk.Stack { constructor(scope: cdk.App, id: string) { super(scope, id); new ssm.StringParameter(this, 'String', { parameterName: '/My/Public/Parameter', - stringValue: 'abcdef', + stringValue: 'Abc123', + }); + + new integ.AwsApiCall(this, 'SecureParam', { + service: 'SSM', + api: 'putParameter', + parameters: { + Name: SECURE_PARAM_NAME, + Type: 'SecureString', + Value: 'Abc123', + }, }); } } @@ -24,7 +36,6 @@ class UsingStack extends cdk.Stack { default: 1, }).valueAsNumber; - /// !show // Retrieve the latest value of the non-secret parameter // with name "/My/String/Parameter". const stringValue = ssm.StringParameter.fromStringParameterAttributes(this, 'MyValue', { @@ -38,33 +49,54 @@ class UsingStack extends cdk.Stack { }).stringValue; // Retrieve a specific version of the secret (SecureString) parameter. - // 'version' is always required. const secretValue = ssm.StringParameter.fromSecureStringParameterAttributes(this, 'MySecureValue', { parameterName: '/My/Secret/Parameter', - version: 5, - }); + }).stringValue; + const secretValueVersion = ssm.StringParameter.fromSecureStringParameterAttributes(this, 'MySecureValueVersion', { + parameterName: '/My/Secret/Parameter', + version: 1, + }).stringValue; const secretValueVersionFromToken = ssm.StringParameter.fromSecureStringParameterAttributes(this, 'MySecureValueVersionFromToken', { parameterName: '/My/Secret/Parameter', // parameter version from token version: parameterVersion, - }); - - /// !hide - - new cdk.CfnResource(this, 'Dummy', { type: 'AWS::SNS::Topic' }); - new cdk.CfnOutput(this, 'TheValue', { value: stringValue }); - new cdk.CfnOutput(this, 'TheValueVersionFromToken', { value: stringValueVersionFromToken }); + }).stringValue; - // Cannot be provisioned so cannot be actually used - Array.isArray(secretValue); - Array.isArray(secretValueVersionFromToken); + const user = new cdk.CfnResource(this, 'DummyResourceUsingStringParameters', { + type: 'AWS::IAM::User', + properties: { + LoginProfile: { + Password: cdk.Fn.join('-', [ + stringValue, + stringValueVersionFromToken, + secretValue, + secretValueVersion, + secretValueVersionFromToken, + ]), + }, + }, + }); + user.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY); } } const app = new cdk.App(); const creating = new CreatingStack(app, 'sspms-creating'); + const using = new UsingStack(app, 'sspms-using'); using.addDependency(creating); +const cleanup = new cdk.Stack(app, 'sspms-cleanup'); +cleanup.addDependency(using); + +const integTest = new integ.IntegTest(app, 'SSMParameterStoreTest', { + assertionStack: cleanup, + testCases: [using], +}); + +integTest.assertions.awsApiCall('SSM', 'deleteParameter', { + Name: SECURE_PARAM_NAME, +}); + app.synth(); diff --git a/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/asset.b54b99043c35bd080b9d9d1afce31e3541cf15b679799ba980ed40c837dcb03b.bundle/index.js b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/asset.b54b99043c35bd080b9d9d1afce31e3541cf15b679799ba980ed40c837dcb03b.bundle/index.js new file mode 100644 index 0000000000000..2d6c2f0e85497 --- /dev/null +++ b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/asset.b54b99043c35bd080b9d9d1afce31e3541cf15b679799ba980ed40c837dcb03b.bundle/index.js @@ -0,0 +1,768 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// lib/assertions/providers/lambda-handler/index.ts +var lambda_handler_exports = {}; +__export(lambda_handler_exports, { + handler: () => handler, + isComplete: () => isComplete, + onTimeout: () => onTimeout +}); +module.exports = __toCommonJS(lambda_handler_exports); + +// ../assertions/lib/matcher.ts +var Matcher = class { + static isMatcher(x) { + return x && x instanceof Matcher; + } +}; +var MatchResult = class { + constructor(target) { + this.failures = []; + this.captures = /* @__PURE__ */ new Map(); + this.finalized = false; + this.target = target; + } + push(matcher, path, message) { + return this.recordFailure({ matcher, path, message }); + } + recordFailure(failure) { + this.failures.push(failure); + return this; + } + hasFailed() { + return this.failures.length !== 0; + } + get failCount() { + return this.failures.length; + } + compose(id, inner) { + const innerF = inner.failures; + this.failures.push(...innerF.map((f) => { + return { path: [id, ...f.path], message: f.message, matcher: f.matcher }; + })); + inner.captures.forEach((vals, capture) => { + vals.forEach((value) => this.recordCapture({ capture, value })); + }); + return this; + } + finished() { + if (this.finalized) { + return this; + } + if (this.failCount === 0) { + this.captures.forEach((vals, cap) => cap._captured.push(...vals)); + } + this.finalized = true; + return this; + } + toHumanStrings() { + return this.failures.map((r) => { + const loc = r.path.length === 0 ? "" : ` at ${r.path.join("")}`; + return "" + r.message + loc + ` (using ${r.matcher.name} matcher)`; + }); + } + recordCapture(options) { + let values = this.captures.get(options.capture); + if (values === void 0) { + values = []; + } + values.push(options.value); + this.captures.set(options.capture, values); + } +}; + +// ../assertions/lib/private/matchers/absent.ts +var AbsentMatch = class extends Matcher { + constructor(name) { + super(); + this.name = name; + } + test(actual) { + const result = new MatchResult(actual); + if (actual !== void 0) { + result.recordFailure({ + matcher: this, + path: [], + message: `Received ${actual}, but key should be absent` + }); + } + return result; + } +}; + +// ../assertions/lib/private/type.ts +function getType(obj) { + return Array.isArray(obj) ? "array" : typeof obj; +} + +// ../assertions/lib/match.ts +var Match = class { + static absent() { + return new AbsentMatch("absent"); + } + static arrayWith(pattern) { + return new ArrayMatch("arrayWith", pattern); + } + static arrayEquals(pattern) { + return new ArrayMatch("arrayEquals", pattern, { subsequence: false }); + } + static exact(pattern) { + return new LiteralMatch("exact", pattern, { partialObjects: false }); + } + static objectLike(pattern) { + return new ObjectMatch("objectLike", pattern); + } + static objectEquals(pattern) { + return new ObjectMatch("objectEquals", pattern, { partial: false }); + } + static not(pattern) { + return new NotMatch("not", pattern); + } + static serializedJson(pattern) { + return new SerializedJson("serializedJson", pattern); + } + static anyValue() { + return new AnyMatch("anyValue"); + } + static stringLikeRegexp(pattern) { + return new StringLikeRegexpMatch("stringLikeRegexp", pattern); + } +}; +var LiteralMatch = class extends Matcher { + constructor(name, pattern, options = {}) { + super(); + this.name = name; + this.pattern = pattern; + this.partialObjects = options.partialObjects ?? false; + if (Matcher.isMatcher(this.pattern)) { + throw new Error("LiteralMatch cannot directly contain another matcher. Remove the top-level matcher or nest it more deeply."); + } + } + test(actual) { + if (Array.isArray(this.pattern)) { + return new ArrayMatch(this.name, this.pattern, { subsequence: false, partialObjects: this.partialObjects }).test(actual); + } + if (typeof this.pattern === "object") { + return new ObjectMatch(this.name, this.pattern, { partial: this.partialObjects }).test(actual); + } + const result = new MatchResult(actual); + if (typeof this.pattern !== typeof actual) { + result.recordFailure({ + matcher: this, + path: [], + message: `Expected type ${typeof this.pattern} but received ${getType(actual)}` + }); + return result; + } + if (actual !== this.pattern) { + result.recordFailure({ + matcher: this, + path: [], + message: `Expected ${this.pattern} but received ${actual}` + }); + } + return result; + } +}; +var ArrayMatch = class extends Matcher { + constructor(name, pattern, options = {}) { + super(); + this.name = name; + this.pattern = pattern; + this.subsequence = options.subsequence ?? true; + this.partialObjects = options.partialObjects ?? false; + } + test(actual) { + if (!Array.isArray(actual)) { + return new MatchResult(actual).recordFailure({ + matcher: this, + path: [], + message: `Expected type array but received ${getType(actual)}` + }); + } + if (!this.subsequence && this.pattern.length !== actual.length) { + return new MatchResult(actual).recordFailure({ + matcher: this, + path: [], + message: `Expected array of length ${this.pattern.length} but received ${actual.length}` + }); + } + let patternIdx = 0; + let actualIdx = 0; + const result = new MatchResult(actual); + while (patternIdx < this.pattern.length && actualIdx < actual.length) { + const patternElement = this.pattern[patternIdx]; + const matcher = Matcher.isMatcher(patternElement) ? patternElement : new LiteralMatch(this.name, patternElement, { partialObjects: this.partialObjects }); + const matcherName = matcher.name; + if (this.subsequence && (matcherName == "absent" || matcherName == "anyValue")) { + throw new Error(`The Matcher ${matcherName}() cannot be nested within arrayWith()`); + } + const innerResult = matcher.test(actual[actualIdx]); + if (!this.subsequence || !innerResult.hasFailed()) { + result.compose(`[${actualIdx}]`, innerResult); + patternIdx++; + actualIdx++; + } else { + actualIdx++; + } + } + for (; patternIdx < this.pattern.length; patternIdx++) { + const pattern = this.pattern[patternIdx]; + const element = Matcher.isMatcher(pattern) || typeof pattern === "object" ? " " : ` [${pattern}] `; + result.recordFailure({ + matcher: this, + path: [], + message: `Missing element${element}at pattern index ${patternIdx}` + }); + } + return result; + } +}; +var ObjectMatch = class extends Matcher { + constructor(name, pattern, options = {}) { + super(); + this.name = name; + this.pattern = pattern; + this.partial = options.partial ?? true; + } + test(actual) { + if (typeof actual !== "object" || Array.isArray(actual)) { + return new MatchResult(actual).recordFailure({ + matcher: this, + path: [], + message: `Expected type object but received ${getType(actual)}` + }); + } + const result = new MatchResult(actual); + if (!this.partial) { + for (const a of Object.keys(actual)) { + if (!(a in this.pattern)) { + result.recordFailure({ + matcher: this, + path: [`/${a}`], + message: "Unexpected key" + }); + } + } + } + for (const [patternKey, patternVal] of Object.entries(this.pattern)) { + if (!(patternKey in actual) && !(patternVal instanceof AbsentMatch)) { + result.recordFailure({ + matcher: this, + path: [`/${patternKey}`], + message: `Missing key '${patternKey}' among {${Object.keys(actual).join(",")}}` + }); + continue; + } + const matcher = Matcher.isMatcher(patternVal) ? patternVal : new LiteralMatch(this.name, patternVal, { partialObjects: this.partial }); + const inner = matcher.test(actual[patternKey]); + result.compose(`/${patternKey}`, inner); + } + return result; + } +}; +var SerializedJson = class extends Matcher { + constructor(name, pattern) { + super(); + this.name = name; + this.pattern = pattern; + } + test(actual) { + const result = new MatchResult(actual); + if (getType(actual) !== "string") { + result.recordFailure({ + matcher: this, + path: [], + message: `Expected JSON as a string but found ${getType(actual)}` + }); + return result; + } + let parsed; + try { + parsed = JSON.parse(actual); + } catch (err) { + if (err instanceof SyntaxError) { + result.recordFailure({ + matcher: this, + path: [], + message: `Invalid JSON string: ${actual}` + }); + return result; + } else { + throw err; + } + } + const matcher = Matcher.isMatcher(this.pattern) ? this.pattern : new LiteralMatch(this.name, this.pattern); + const innerResult = matcher.test(parsed); + result.compose(`(${this.name})`, innerResult); + return result; + } +}; +var NotMatch = class extends Matcher { + constructor(name, pattern) { + super(); + this.name = name; + this.pattern = pattern; + } + test(actual) { + const matcher = Matcher.isMatcher(this.pattern) ? this.pattern : new LiteralMatch(this.name, this.pattern); + const innerResult = matcher.test(actual); + const result = new MatchResult(actual); + if (innerResult.failCount === 0) { + result.recordFailure({ + matcher: this, + path: [], + message: `Found unexpected match: ${JSON.stringify(actual, void 0, 2)}` + }); + } + return result; + } +}; +var AnyMatch = class extends Matcher { + constructor(name) { + super(); + this.name = name; + } + test(actual) { + const result = new MatchResult(actual); + if (actual == null) { + result.recordFailure({ + matcher: this, + path: [], + message: "Expected a value but found none" + }); + } + return result; + } +}; +var StringLikeRegexpMatch = class extends Matcher { + constructor(name, pattern) { + super(); + this.name = name; + this.pattern = pattern; + } + test(actual) { + const result = new MatchResult(actual); + const regex = new RegExp(this.pattern, "gm"); + if (typeof actual !== "string") { + result.recordFailure({ + matcher: this, + path: [], + message: `Expected a string, but got '${typeof actual}'` + }); + } + if (!regex.test(actual)) { + result.recordFailure({ + matcher: this, + path: [], + message: `String '${actual}' did not match pattern '${this.pattern}'` + }); + } + return result; + } +}; + +// lib/assertions/providers/lambda-handler/base.ts +var https = __toESM(require("https")); +var url = __toESM(require("url")); +var AWS = __toESM(require("aws-sdk")); +var CustomResourceHandler = class { + constructor(event, context) { + this.event = event; + this.context = context; + this.timedOut = false; + this.timeout = setTimeout(async () => { + await this.respond({ + status: "FAILED", + reason: "Lambda Function Timeout", + data: this.context.logStreamName + }); + this.timedOut = true; + }, context.getRemainingTimeInMillis() - 1200); + this.event = event; + this.physicalResourceId = extractPhysicalResourceId(event); + } + async handle() { + try { + if ("stateMachineArn" in this.event.ResourceProperties) { + const req = { + stateMachineArn: this.event.ResourceProperties.stateMachineArn, + name: this.event.RequestId, + input: JSON.stringify(this.event) + }; + await this.startExecution(req); + return; + } else { + const response = await this.processEvent(this.event.ResourceProperties); + return response; + } + } catch (e) { + console.log(e); + throw e; + } finally { + clearTimeout(this.timeout); + } + } + async handleIsComplete() { + try { + const result = await this.processEvent(this.event.ResourceProperties); + return result; + } catch (e) { + console.log(e); + return; + } finally { + clearTimeout(this.timeout); + } + } + async startExecution(req) { + try { + const sfn = new AWS.StepFunctions(); + await sfn.startExecution(req).promise(); + } finally { + clearTimeout(this.timeout); + } + } + respond(response) { + if (this.timedOut) { + return; + } + const cfResponse = { + Status: response.status, + Reason: response.reason, + PhysicalResourceId: this.physicalResourceId, + StackId: this.event.StackId, + RequestId: this.event.RequestId, + LogicalResourceId: this.event.LogicalResourceId, + NoEcho: false, + Data: response.data + }; + const responseBody = JSON.stringify(cfResponse); + console.log("Responding to CloudFormation", responseBody); + const parsedUrl = url.parse(this.event.ResponseURL); + const requestOptions = { + hostname: parsedUrl.hostname, + path: parsedUrl.path, + method: "PUT", + headers: { "content-type": "", "content-length": responseBody.length } + }; + return new Promise((resolve, reject) => { + try { + const request2 = https.request(requestOptions, resolve); + request2.on("error", reject); + request2.write(responseBody); + request2.end(); + } catch (e) { + reject(e); + } finally { + clearTimeout(this.timeout); + } + }); + } +}; +function extractPhysicalResourceId(event) { + switch (event.RequestType) { + case "Create": + return event.LogicalResourceId; + case "Update": + case "Delete": + return event.PhysicalResourceId; + } +} + +// lib/assertions/providers/lambda-handler/assertion.ts +var AssertionHandler = class extends CustomResourceHandler { + async processEvent(request2) { + let actual = decodeCall(request2.actual); + const expected = decodeCall(request2.expected); + let result; + const matcher = new MatchCreator(expected).getMatcher(); + console.log(`Testing equality between ${JSON.stringify(request2.actual)} and ${JSON.stringify(request2.expected)}`); + const matchResult = matcher.test(actual); + matchResult.finished(); + if (matchResult.hasFailed()) { + result = { + failed: true, + assertion: JSON.stringify({ + status: "fail", + message: [ + ...matchResult.toHumanStrings(), + JSON.stringify(matchResult.target, void 0, 2) + ].join("\n") + }) + }; + if (request2.failDeployment) { + throw new Error(result.assertion); + } + } else { + result = { + assertion: JSON.stringify({ + status: "success" + }) + }; + } + return result; + } +}; +var MatchCreator = class { + constructor(obj) { + this.parsedObj = { + matcher: obj + }; + } + getMatcher() { + try { + const final = JSON.parse(JSON.stringify(this.parsedObj), function(_k, v) { + const nested = Object.keys(v)[0]; + switch (nested) { + case "$ArrayWith": + return Match.arrayWith(v[nested]); + case "$ObjectLike": + return Match.objectLike(v[nested]); + case "$StringLike": + return Match.stringLikeRegexp(v[nested]); + default: + return v; + } + }); + if (Matcher.isMatcher(final.matcher)) { + return final.matcher; + } + return Match.exact(final.matcher); + } catch { + return Match.exact(this.parsedObj.matcher); + } + } +}; +function decodeCall(call) { + if (!call) { + return void 0; + } + try { + const parsed = JSON.parse(call); + return parsed; + } catch (e) { + return call; + } +} + +// lib/assertions/providers/lambda-handler/utils.ts +function decode(object) { + return JSON.parse(JSON.stringify(object), (_k, v) => { + switch (v) { + case "TRUE:BOOLEAN": + return true; + case "FALSE:BOOLEAN": + return false; + default: + return v; + } + }); +} + +// lib/assertions/providers/lambda-handler/sdk.ts +function flatten(object) { + return Object.assign( + {}, + ...function _flatten(child, path = []) { + return [].concat(...Object.keys(child).map((key) => { + let childKey = Buffer.isBuffer(child[key]) ? child[key].toString("utf8") : child[key]; + if (typeof childKey === "string") { + childKey = isJsonString(childKey); + } + return typeof childKey === "object" && childKey !== null ? _flatten(childKey, path.concat([key])) : { [path.concat([key]).join(".")]: childKey }; + })); + }(object) + ); +} +var AwsApiCallHandler = class extends CustomResourceHandler { + async processEvent(request2) { + const AWS2 = require("aws-sdk"); + console.log(`AWS SDK VERSION: ${AWS2.VERSION}`); + if (!Object.prototype.hasOwnProperty.call(AWS2, request2.service)) { + throw Error(`Service ${request2.service} does not exist in AWS SDK version ${AWS2.VERSION}.`); + } + const service = new AWS2[request2.service](); + const response = await service[request2.api](request2.parameters && decode(request2.parameters)).promise(); + console.log(`SDK response received ${JSON.stringify(response)}`); + delete response.ResponseMetadata; + const respond = { + apiCallResponse: response + }; + const flatData = { + ...flatten(respond) + }; + const resp = request2.flattenResponse === "true" ? flatData : respond; + console.log(`Returning result ${JSON.stringify(resp)}`); + return resp; + } +}; +function isJsonString(value) { + try { + return JSON.parse(value); + } catch { + return value; + } +} + +// lib/assertions/providers/lambda-handler/types.ts +var ASSERT_RESOURCE_TYPE = "Custom::DeployAssert@AssertEquals"; +var SDK_RESOURCE_TYPE_PREFIX = "Custom::DeployAssert@SdkCall"; + +// lib/assertions/providers/lambda-handler/index.ts +async function handler(event, context) { + console.log(`Event: ${JSON.stringify({ ...event, ResponseURL: "..." })}`); + const provider = createResourceHandler(event, context); + try { + if (event.RequestType === "Delete") { + await provider.respond({ + status: "SUCCESS", + reason: "OK" + }); + return; + } + const result = await provider.handle(); + if ("stateMachineArn" in event.ResourceProperties) { + console.info('Found "stateMachineArn", waiter statemachine started'); + return; + } else if ("expected" in event.ResourceProperties) { + console.info('Found "expected", testing assertions'); + const actualPath = event.ResourceProperties.actualPath; + const actual = actualPath ? result[`apiCallResponse.${actualPath}`] : result.apiCallResponse; + const assertion = new AssertionHandler({ + ...event, + ResourceProperties: { + ServiceToken: event.ServiceToken, + actual, + expected: event.ResourceProperties.expected + } + }, context); + try { + const assertionResult = await assertion.handle(); + await provider.respond({ + status: "SUCCESS", + reason: "OK", + data: { + ...assertionResult, + ...result + } + }); + return; + } catch (e) { + await provider.respond({ + status: "FAILED", + reason: e.message ?? "Internal Error" + }); + return; + } + } + await provider.respond({ + status: "SUCCESS", + reason: "OK", + data: result + }); + } catch (e) { + await provider.respond({ + status: "FAILED", + reason: e.message ?? "Internal Error" + }); + return; + } + return; +} +async function onTimeout(timeoutEvent) { + const isCompleteRequest = JSON.parse(JSON.parse(timeoutEvent.Cause).errorMessage); + const provider = createResourceHandler(isCompleteRequest, standardContext); + await provider.respond({ + status: "FAILED", + reason: "Operation timed out: " + JSON.stringify(isCompleteRequest) + }); +} +async function isComplete(event, context) { + console.log(`Event: ${JSON.stringify({ ...event, ResponseURL: "..." })}`); + const provider = createResourceHandler(event, context); + try { + const result = await provider.handleIsComplete(); + const actualPath = event.ResourceProperties.actualPath; + if (result) { + const actual = actualPath ? result[`apiCallResponse.${actualPath}`] : result.apiCallResponse; + if ("expected" in event.ResourceProperties) { + const assertion = new AssertionHandler({ + ...event, + ResourceProperties: { + ServiceToken: event.ServiceToken, + actual, + expected: event.ResourceProperties.expected + } + }, context); + const assertionResult = await assertion.handleIsComplete(); + if (!(assertionResult == null ? void 0 : assertionResult.failed)) { + await provider.respond({ + status: "SUCCESS", + reason: "OK", + data: { + ...assertionResult, + ...result + } + }); + return; + } else { + console.log(`Assertion Failed: ${JSON.stringify(assertionResult)}`); + throw new Error(JSON.stringify(event)); + } + } + await provider.respond({ + status: "SUCCESS", + reason: "OK", + data: result + }); + } else { + console.log("No result"); + throw new Error(JSON.stringify(event)); + } + return; + } catch (e) { + console.log(e); + throw new Error(JSON.stringify(event)); + } +} +function createResourceHandler(event, context) { + if (event.ResourceType.startsWith(SDK_RESOURCE_TYPE_PREFIX)) { + return new AwsApiCallHandler(event, context); + } else if (event.ResourceType.startsWith(ASSERT_RESOURCE_TYPE)) { + return new AssertionHandler(event, context); + } else { + throw new Error(`Unsupported resource type "${event.ResourceType}`); + } +} +var standardContext = { + getRemainingTimeInMillis: () => 9e4 +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + handler, + isComplete, + onTimeout +}); diff --git a/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/cdk.out b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/cdk.out new file mode 100644 index 0000000000000..8ecc185e9dbee --- /dev/null +++ b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"21.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/integ.json b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/integ.json new file mode 100644 index 0000000000000..37dd1517a09fc --- /dev/null +++ b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "21.0.0", + "testCases": { + "SSMParameterStoreTest/DefaultTest": { + "stacks": [ + "sspms-using" + ], + "assertionStack": "sspms-cleanup", + "assertionStackName": "sspms-cleanup" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/manifest.json b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/manifest.json new file mode 100644 index 0000000000000..b3dea0254e5ea --- /dev/null +++ b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/manifest.json @@ -0,0 +1,214 @@ +{ + "version": "21.0.0", + "artifacts": { + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + }, + "sspms-creating.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "sspms-creating.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "sspms-creating": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "sspms-creating.template.json", + "validateOnSynth": false, + "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}/774681e523ca39cdb798d74ea486ac7874030c04a36debc6a623f24afe196859.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "sspms-creating.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": [ + "sspms-creating.assets" + ], + "metadata": { + "/sspms-creating/String/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "String0BA8456E" + } + ], + "/sspms-creating/SecureParam/Default/Default": [ + { + "type": "aws:cdk:logicalId", + "data": "SecureParam" + } + ], + "/sspms-creating/SingletonFunction1488541a7b23466481b69b4408076b81/Role": [ + { + "type": "aws:cdk:logicalId", + "data": "SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73" + } + ], + "/sspms-creating/SingletonFunction1488541a7b23466481b69b4408076b81/Handler": [ + { + "type": "aws:cdk:logicalId", + "data": "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F" + } + ], + "/sspms-creating/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/sspms-creating/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "sspms-creating" + }, + "sspms-using.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "sspms-using.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "sspms-using": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "sspms-using.template.json", + "validateOnSynth": false, + "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}/f6e392d82be8514b35d4085f6ff4e3df808815b1cf4cc7a119cb67ace46e03b9.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "sspms-using.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": [ + "sspms-creating", + "sspms-using.assets" + ], + "metadata": { + "/sspms-using/MyParameterVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "MyParameterVersion" + } + ], + "/sspms-using/MyValue.Parameter": [ + { + "type": "aws:cdk:logicalId", + "data": "MyValueParameter" + } + ], + "/sspms-using/DummyResourceUsingStringParameters": [ + { + "type": "aws:cdk:logicalId", + "data": "DummyResourceUsingStringParameters" + } + ], + "/sspms-using/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/sspms-using/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "sspms-using" + }, + "sspms-cleanup.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "sspms-cleanup.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "sspms-cleanup": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "sspms-cleanup.template.json", + "validateOnSynth": false, + "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}/ed82f3ce48345002448971161c8bd7594b2f548f56641b70afb2f4688e4c0aef.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "sspms-cleanup.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": [ + "sspms-using", + "sspms-cleanup.assets" + ], + "metadata": { + "/sspms-cleanup/AwsApiCallSSMdeleteParameter/Default/Default": [ + { + "type": "aws:cdk:logicalId", + "data": "AwsApiCallSSMdeleteParameter" + } + ], + "/sspms-cleanup/SingletonFunction1488541a7b23466481b69b4408076b81/Role": [ + { + "type": "aws:cdk:logicalId", + "data": "SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73" + } + ], + "/sspms-cleanup/SingletonFunction1488541a7b23466481b69b4408076b81/Handler": [ + { + "type": "aws:cdk:logicalId", + "data": "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F" + } + ], + "/sspms-cleanup/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/sspms-cleanup/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "sspms-cleanup" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/sspms-cleanup.assets.json b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/sspms-cleanup.assets.json new file mode 100644 index 0000000000000..dd2d2b82e2cc2 --- /dev/null +++ b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/sspms-cleanup.assets.json @@ -0,0 +1,32 @@ +{ + "version": "21.0.0", + "files": { + "b54b99043c35bd080b9d9d1afce31e3541cf15b679799ba980ed40c837dcb03b": { + "source": { + "path": "asset.b54b99043c35bd080b9d9d1afce31e3541cf15b679799ba980ed40c837dcb03b.bundle", + "packaging": "zip" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "b54b99043c35bd080b9d9d1afce31e3541cf15b679799ba980ed40c837dcb03b.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "ed82f3ce48345002448971161c8bd7594b2f548f56641b70afb2f4688e4c0aef": { + "source": { + "path": "sspms-cleanup.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "ed82f3ce48345002448971161c8bd7594b2f548f56641b70afb2f4688e4c0aef.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/aws-ssm/test/parameter-store-string.integ.snapshot/sspms-cleanup.template.json b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/sspms-cleanup.template.json new file mode 100644 index 0000000000000..a2af3eeea9e3d --- /dev/null +++ b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/sspms-cleanup.template.json @@ -0,0 +1,119 @@ +{ + "Resources": { + "AwsApiCallSSMdeleteParameter": { + "Type": "Custom::DeployAssert@SdkCallSSMdeleteParameter", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F", + "Arn" + ] + }, + "service": "SSM", + "api": "deleteParameter", + "parameters": { + "Name": "/My/Secret/Parameter" + }, + "flattenResponse": "false", + "salt": "1666616854742" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ] + }, + "ManagedPolicyArns": [ + { + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + } + ], + "Policies": [ + { + "PolicyName": "Inline", + "PolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "ssm:DeleteParameter" + ], + "Effect": "Allow", + "Resource": [ + "*" + ] + } + ] + } + } + ] + } + }, + "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Runtime": "nodejs14.x", + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "b54b99043c35bd080b9d9d1afce31e3541cf15b679799ba980ed40c837dcb03b.zip" + }, + "Timeout": 120, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73", + "Arn" + ] + } + } + } + }, + "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/aws-ssm/test/parameter-store-string.integ.snapshot/sspms-creating.assets.json b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/sspms-creating.assets.json new file mode 100644 index 0000000000000..58c023eab8e3b --- /dev/null +++ b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/sspms-creating.assets.json @@ -0,0 +1,32 @@ +{ + "version": "21.0.0", + "files": { + "b54b99043c35bd080b9d9d1afce31e3541cf15b679799ba980ed40c837dcb03b": { + "source": { + "path": "asset.b54b99043c35bd080b9d9d1afce31e3541cf15b679799ba980ed40c837dcb03b.bundle", + "packaging": "zip" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "b54b99043c35bd080b9d9d1afce31e3541cf15b679799ba980ed40c837dcb03b.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "774681e523ca39cdb798d74ea486ac7874030c04a36debc6a623f24afe196859": { + "source": { + "path": "sspms-creating.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "774681e523ca39cdb798d74ea486ac7874030c04a36debc6a623f24afe196859.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/aws-ssm/test/parameter-store-string.integ.snapshot/sspms-creating.template.json b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/sspms-creating.template.json new file mode 100644 index 0000000000000..5300480f9984b --- /dev/null +++ b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/sspms-creating.template.json @@ -0,0 +1,129 @@ +{ + "Resources": { + "String0BA8456E": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Type": "String", + "Value": "Abc123", + "Name": "/My/Public/Parameter" + } + }, + "SecureParam": { + "Type": "Custom::DeployAssert@SdkCallSSMputParameter", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F", + "Arn" + ] + }, + "service": "SSM", + "api": "putParameter", + "parameters": { + "Name": "/My/Secret/Parameter", + "Type": "SecureString", + "Value": "Abc123" + }, + "flattenResponse": "false", + "salt": "1666616854737" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ] + }, + "ManagedPolicyArns": [ + { + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + } + ], + "Policies": [ + { + "PolicyName": "Inline", + "PolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "ssm:PutParameter" + ], + "Effect": "Allow", + "Resource": [ + "*" + ] + } + ] + } + } + ] + } + }, + "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Runtime": "nodejs14.x", + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "b54b99043c35bd080b9d9d1afce31e3541cf15b679799ba980ed40c837dcb03b.zip" + }, + "Timeout": 120, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73", + "Arn" + ] + } + } + } + }, + "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/aws-ssm/test/parameter-store-string.integ.snapshot/sspms-using.assets.json b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/sspms-using.assets.json new file mode 100644 index 0000000000000..5b3b30e94ddf0 --- /dev/null +++ b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/sspms-using.assets.json @@ -0,0 +1,19 @@ +{ + "version": "21.0.0", + "files": { + "f6e392d82be8514b35d4085f6ff4e3df808815b1cf4cc7a119cb67ace46e03b9": { + "source": { + "path": "sspms-using.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "f6e392d82be8514b35d4085f6ff4e3df808815b1cf4cc7a119cb67ace46e03b9.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/aws-ssm/test/parameter-store-string.integ.snapshot/sspms-using.template.json b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/sspms-using.template.json new file mode 100644 index 0000000000000..ed9e26d07c61c --- /dev/null +++ b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/sspms-using.template.json @@ -0,0 +1,90 @@ +{ + "Parameters": { + "MyParameterVersion": { + "Type": "Number", + "Default": 1 + }, + "MyValueParameter": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/My/Public/Parameter" + }, + "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]" + } + }, + "Resources": { + "DummyResourceUsingStringParameters": { + "Type": "AWS::IAM::User", + "Properties": { + "LoginProfile": { + "Password": { + "Fn::Join": [ + "-", + [ + { + "Ref": "MyValueParameter" + }, + { + "Fn::Join": [ + "", + [ + "{{resolve:ssm:/My/Public/Parameter:", + { + "Ref": "MyParameterVersion" + }, + "}}" + ] + ] + }, + "{{resolve:ssm-secure:/My/Secret/Parameter}}-{{resolve:ssm-secure:/My/Secret/Parameter:1}}", + { + "Fn::Join": [ + "", + [ + "{{resolve:ssm-secure:/My/Secret/Parameter:", + { + "Ref": "MyParameterVersion" + }, + "}}" + ] + ] + } + ] + ] + } + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + }, + "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/aws-ssm/test/parameter-store-string.integ.snapshot/tree.json b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/tree.json new file mode 100644 index 0000000000000..89b9dbbcb8d05 --- /dev/null +++ b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.integ.snapshot/tree.json @@ -0,0 +1,329 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.133" + } + }, + "sspms-creating": { + "id": "sspms-creating", + "path": "sspms-creating", + "children": { + "String": { + "id": "String", + "path": "sspms-creating/String", + "children": { + "Resource": { + "id": "Resource", + "path": "sspms-creating/String/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::SSM::Parameter", + "aws:cdk:cloudformation:props": { + "type": "String", + "value": "Abc123", + "name": "/My/Public/Parameter" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ssm.CfnParameter", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ssm.StringParameter", + "version": "0.0.0" + } + }, + "SecureParam": { + "id": "SecureParam", + "path": "sspms-creating/SecureParam", + "children": { + "SdkProvider": { + "id": "SdkProvider", + "path": "sspms-creating/SecureParam/SdkProvider", + "children": { + "AssertionsProvider": { + "id": "AssertionsProvider", + "path": "sspms-creating/SecureParam/SdkProvider/AssertionsProvider", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.133" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.AssertionsProvider", + "version": "0.0.0" + } + }, + "Default": { + "id": "Default", + "path": "sspms-creating/SecureParam/Default", + "children": { + "Default": { + "id": "Default", + "path": "sspms-creating/SecureParam/Default/Default", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.CustomResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.AwsApiCall", + "version": "0.0.0" + } + }, + "SingletonFunction1488541a7b23466481b69b4408076b81": { + "id": "SingletonFunction1488541a7b23466481b69b4408076b81", + "path": "sspms-creating/SingletonFunction1488541a7b23466481b69b4408076b81", + "children": { + "Staging": { + "id": "Staging", + "path": "sspms-creating/SingletonFunction1488541a7b23466481b69b4408076b81/Staging", + "constructInfo": { + "fqn": "@aws-cdk/core.AssetStaging", + "version": "0.0.0" + } + }, + "Role": { + "id": "Role", + "path": "sspms-creating/SingletonFunction1488541a7b23466481b69b4408076b81/Role", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + }, + "Handler": { + "id": "Handler", + "path": "sspms-creating/SingletonFunction1488541a7b23466481b69b4408076b81/Handler", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.133" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "sspms-using": { + "id": "sspms-using", + "path": "sspms-using", + "children": { + "MyParameterVersion": { + "id": "MyParameterVersion", + "path": "sspms-using/MyParameterVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "MyValue.Parameter": { + "id": "MyValue.Parameter", + "path": "sspms-using/MyValue.Parameter", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "MyValue": { + "id": "MyValue", + "path": "sspms-using/MyValue", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "MyValueVersionFromToken": { + "id": "MyValueVersionFromToken", + "path": "sspms-using/MyValueVersionFromToken", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "MySecureValue": { + "id": "MySecureValue", + "path": "sspms-using/MySecureValue", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "MySecureValueVersion": { + "id": "MySecureValueVersion", + "path": "sspms-using/MySecureValueVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "MySecureValueVersionFromToken": { + "id": "MySecureValueVersionFromToken", + "path": "sspms-using/MySecureValueVersionFromToken", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "DummyResourceUsingStringParameters": { + "id": "DummyResourceUsingStringParameters", + "path": "sspms-using/DummyResourceUsingStringParameters", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "sspms-cleanup": { + "id": "sspms-cleanup", + "path": "sspms-cleanup", + "children": { + "AwsApiCallSSMdeleteParameter": { + "id": "AwsApiCallSSMdeleteParameter", + "path": "sspms-cleanup/AwsApiCallSSMdeleteParameter", + "children": { + "SdkProvider": { + "id": "SdkProvider", + "path": "sspms-cleanup/AwsApiCallSSMdeleteParameter/SdkProvider", + "children": { + "AssertionsProvider": { + "id": "AssertionsProvider", + "path": "sspms-cleanup/AwsApiCallSSMdeleteParameter/SdkProvider/AssertionsProvider", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.133" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.AssertionsProvider", + "version": "0.0.0" + } + }, + "Default": { + "id": "Default", + "path": "sspms-cleanup/AwsApiCallSSMdeleteParameter/Default", + "children": { + "Default": { + "id": "Default", + "path": "sspms-cleanup/AwsApiCallSSMdeleteParameter/Default/Default", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.CustomResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.AwsApiCall", + "version": "0.0.0" + } + }, + "SingletonFunction1488541a7b23466481b69b4408076b81": { + "id": "SingletonFunction1488541a7b23466481b69b4408076b81", + "path": "sspms-cleanup/SingletonFunction1488541a7b23466481b69b4408076b81", + "children": { + "Staging": { + "id": "Staging", + "path": "sspms-cleanup/SingletonFunction1488541a7b23466481b69b4408076b81/Staging", + "constructInfo": { + "fqn": "@aws-cdk/core.AssetStaging", + "version": "0.0.0" + } + }, + "Role": { + "id": "Role", + "path": "sspms-cleanup/SingletonFunction1488541a7b23466481b69b4408076b81/Role", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + }, + "Handler": { + "id": "Handler", + "path": "sspms-cleanup/SingletonFunction1488541a7b23466481b69b4408076b81/Handler", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.133" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "SSMParameterStoreTest": { + "id": "SSMParameterStoreTest", + "path": "SSMParameterStoreTest", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "SSMParameterStoreTest/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "SSMParameterStoreTest/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.133" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTest", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ssm/test/parameter-store-string.lit.integ.snapshot/cdk.out b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.lit.integ.snapshot/cdk.out deleted file mode 100644 index 90bef2e09ad39..0000000000000 --- a/packages/@aws-cdk/aws-ssm/test/parameter-store-string.lit.integ.snapshot/cdk.out +++ /dev/null @@ -1 +0,0 @@ -{"version":"17.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ssm/test/parameter-store-string.lit.integ.snapshot/integ.json b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.lit.integ.snapshot/integ.json deleted file mode 100644 index 18726211c7a42..0000000000000 --- a/packages/@aws-cdk/aws-ssm/test/parameter-store-string.lit.integ.snapshot/integ.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "version": "20.0.0", - "testCases": { - "integ.parameter-store-string.lit": { - "stacks": [ - "*" - ], - "diffAssets": false, - "stackUpdateWorkflow": true - } - }, - "synthContext": {}, - "enableLookups": false -} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ssm/test/parameter-store-string.lit.integ.snapshot/manifest.json b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.lit.integ.snapshot/manifest.json deleted file mode 100644 index e28ecb16abfa8..0000000000000 --- a/packages/@aws-cdk/aws-ssm/test/parameter-store-string.lit.integ.snapshot/manifest.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "version": "17.0.0", - "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, - "sspms-creating": { - "type": "aws:cloudformation:stack", - "environment": "aws://unknown-account/unknown-region", - "properties": { - "templateFile": "sspms-creating.template.json", - "validateOnSynth": false - }, - "metadata": { - "/sspms-creating/String/Resource": [ - { - "type": "aws:cdk:logicalId", - "data": "String0BA8456E" - } - ] - }, - "displayName": "sspms-creating" - }, - "sspms-using": { - "type": "aws:cloudformation:stack", - "environment": "aws://unknown-account/unknown-region", - "properties": { - "templateFile": "sspms-using.template.json", - "validateOnSynth": false - }, - "dependencies": [ - "sspms-creating" - ], - "metadata": { - "/sspms-using/MyParameterVersion": [ - { - "type": "aws:cdk:logicalId", - "data": "MyParameterVersion" - } - ], - "/sspms-using/MyValue.Parameter": [ - { - "type": "aws:cdk:logicalId", - "data": "MyValueParameter" - } - ], - "/sspms-using/Dummy": [ - { - "type": "aws:cdk:logicalId", - "data": "Dummy" - } - ], - "/sspms-using/TheValue": [ - { - "type": "aws:cdk:logicalId", - "data": "TheValue" - } - ], - "/sspms-using/TheValueVersionFromToken": [ - { - "type": "aws:cdk:logicalId", - "data": "TheValueVersionFromToken" - } - ] - }, - "displayName": "sspms-using" - } - } -} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ssm/test/parameter-store-string.lit.integ.snapshot/sspms-creating.template.json b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.lit.integ.snapshot/sspms-creating.template.json deleted file mode 100644 index 1e9fc486b77c2..0000000000000 --- a/packages/@aws-cdk/aws-ssm/test/parameter-store-string.lit.integ.snapshot/sspms-creating.template.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "Resources": { - "String0BA8456E": { - "Type": "AWS::SSM::Parameter", - "Properties": { - "Type": "String", - "Value": "abcdef", - "Name": "/My/Public/Parameter" - } - } - } -} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ssm/test/parameter-store-string.lit.integ.snapshot/sspms-using.template.json b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.lit.integ.snapshot/sspms-using.template.json deleted file mode 100644 index 00e99691afa6c..0000000000000 --- a/packages/@aws-cdk/aws-ssm/test/parameter-store-string.lit.integ.snapshot/sspms-using.template.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "Parameters": { - "MyParameterVersion": { - "Type": "Number", - "Default": 1 - }, - "MyValueParameter": { - "Type": "AWS::SSM::Parameter::Value", - "Default": "/My/Public/Parameter" - } - }, - "Resources": { - "Dummy": { - "Type": "AWS::SNS::Topic" - } - }, - "Outputs": { - "TheValue": { - "Value": { - "Ref": "MyValueParameter" - } - }, - "TheValueVersionFromToken": { - "Value": { - "Fn::Join": [ - "", - [ - "{{resolve:ssm:/My/Public/Parameter:", - { - "Ref": "MyParameterVersion" - }, - "}}" - ] - ] - } - } - } -} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ssm/test/parameter-store-string.lit.integ.snapshot/tree.json b/packages/@aws-cdk/aws-ssm/test/parameter-store-string.lit.integ.snapshot/tree.json deleted file mode 100644 index aeab51f8647c0..0000000000000 --- a/packages/@aws-cdk/aws-ssm/test/parameter-store-string.lit.integ.snapshot/tree.json +++ /dev/null @@ -1,139 +0,0 @@ -{ - "version": "tree-0.1", - "tree": { - "id": "App", - "path": "", - "children": { - "Tree": { - "id": "Tree", - "path": "Tree", - "constructInfo": { - "fqn": "@aws-cdk/core.Construct", - "version": "0.0.0" - } - }, - "sspms-creating": { - "id": "sspms-creating", - "path": "sspms-creating", - "children": { - "String": { - "id": "String", - "path": "sspms-creating/String", - "children": { - "Resource": { - "id": "Resource", - "path": "sspms-creating/String/Resource", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::SSM::Parameter", - "aws:cdk:cloudformation:props": { - "type": "String", - "value": "abcdef", - "name": "/My/Public/Parameter" - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-ssm.CfnParameter", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-ssm.StringParameter", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/core.Stack", - "version": "0.0.0" - } - }, - "sspms-using": { - "id": "sspms-using", - "path": "sspms-using", - "children": { - "MyParameterVersion": { - "id": "MyParameterVersion", - "path": "sspms-using/MyParameterVersion", - "constructInfo": { - "fqn": "@aws-cdk/core.CfnParameter", - "version": "0.0.0" - } - }, - "MyValue.Parameter": { - "id": "MyValue.Parameter", - "path": "sspms-using/MyValue.Parameter", - "constructInfo": { - "fqn": "@aws-cdk/core.CfnParameter", - "version": "0.0.0" - } - }, - "MyValue": { - "id": "MyValue", - "path": "sspms-using/MyValue", - "constructInfo": { - "fqn": "@aws-cdk/core.Resource", - "version": "0.0.0" - } - }, - "MyValueVersionFromToken": { - "id": "MyValueVersionFromToken", - "path": "sspms-using/MyValueVersionFromToken", - "constructInfo": { - "fqn": "@aws-cdk/core.Resource", - "version": "0.0.0" - } - }, - "MySecureValue": { - "id": "MySecureValue", - "path": "sspms-using/MySecureValue", - "constructInfo": { - "fqn": "@aws-cdk/core.Resource", - "version": "0.0.0" - } - }, - "MySecureValueVersionFromToken": { - "id": "MySecureValueVersionFromToken", - "path": "sspms-using/MySecureValueVersionFromToken", - "constructInfo": { - "fqn": "@aws-cdk/core.Resource", - "version": "0.0.0" - } - }, - "Dummy": { - "id": "Dummy", - "path": "sspms-using/Dummy", - "constructInfo": { - "fqn": "@aws-cdk/core.CfnResource", - "version": "0.0.0" - } - }, - "TheValue": { - "id": "TheValue", - "path": "sspms-using/TheValue", - "constructInfo": { - "fqn": "@aws-cdk/core.CfnOutput", - "version": "0.0.0" - } - }, - "TheValueVersionFromToken": { - "id": "TheValueVersionFromToken", - "path": "sspms-using/TheValueVersionFromToken", - "constructInfo": { - "fqn": "@aws-cdk/core.CfnOutput", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/core.Stack", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/core.App", - "version": "0.0.0" - } - } -} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ssm/test/parameter.test.ts b/packages/@aws-cdk/aws-ssm/test/parameter.test.ts index 817eb4d264239..c33bfaa01305f 100644 --- a/packages/@aws-cdk/aws-ssm/test/parameter.test.ts +++ b/packages/@aws-cdk/aws-ssm/test/parameter.test.ts @@ -602,7 +602,7 @@ test('StringParameter.fromSecureStringParameterAttributes without version', () = }); // THEN - expect(stack.resolve(param.stringValue)).toEqual('{{resolve:ssm-secure:MyParamName:}}'); + expect(stack.resolve(param.stringValue)).toEqual('{{resolve:ssm-secure:MyParamName}}'); }); test('StringListParameter.fromName', () => {