diff --git a/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-cfn.expected.json b/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-cfn.expected.json index 2481e51936f1f..63ea285a6f8d4 100644 --- a/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-cfn.expected.json +++ b/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-cfn.expected.json @@ -207,7 +207,8 @@ "CfnChangeSetRole6F05F6FC", "Arn" ] - } + }, + "ParameterOverrides": "{\"BucketName\":{\"Fn::GetArtifactAtt\":[\"SourceArtifact\",\"BucketName\"]},\"ObjectKey\":{\"Fn::GetArtifactAtt\":[\"SourceArtifact\",\"ObjectKey\"]},\"Url\":{\"Fn::GetArtifactAtt\":[\"SourceArtifact\",\"URL\"]},\"OtherParam\":{\"Fn::GetParam\":[\"SourceArtifact\",\"params.json\",\"OtherParam\"]}}" }, "InputArtifacts": [ { diff --git a/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-cfn.ts b/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-cfn.ts index 8d11ce56897ad..f34160c9f40b6 100644 --- a/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-cfn.ts +++ b/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-cfn.ts @@ -39,6 +39,12 @@ new cfn.PipelineCreateReplaceChangeSetAction(stack, 'DeployCFN', { role, templatePath: source.outputArtifact.atPath('test.yaml'), adminPermissions: false, + parameterOverrides: { + BucketName: source.outputArtifact.bucketName, + ObjectKey: source.outputArtifact.objectKey, + Url: source.outputArtifact.url, + OtherParam: source.outputArtifact.getParam('params.json', 'OtherParam'), + }, }); app.run(); diff --git a/packages/@aws-cdk/cdk/lib/cloudformation/instrinsics.ts b/packages/@aws-cdk/cdk/lib/cloudformation/instrinsics.ts index af2094cc5894d..58356f3061a58 100644 --- a/packages/@aws-cdk/cdk/lib/cloudformation/instrinsics.ts +++ b/packages/@aws-cdk/cdk/lib/cloudformation/instrinsics.ts @@ -37,7 +37,15 @@ export function isIntrinsic(x: any) { const keys = Object.keys(x); if (keys.length !== 1) { return false; } - return keys[0] === 'Ref' || keys[0].startsWith('Fn::'); + return keys[0] === 'Ref' || isNameOfCloudFormationIntrinsic(keys[0]); +} + +export function isNameOfCloudFormationIntrinsic(name: string): boolean { + if (!name.startsWith('Fn::')) { + return false; + } + // these are 'fake' intrinsics, only usable inside the parameter overrides of a CFN CodePipeline Action + return name !== 'Fn::GetArtifactAtt' && name !== 'Fn::GetParam'; } /** diff --git a/packages/@aws-cdk/cdk/test/cloudformation/evaluate-cfn.ts b/packages/@aws-cdk/cdk/test/cloudformation/evaluate-cfn.ts index e18883328742f..b9a69d1d9ede3 100644 --- a/packages/@aws-cdk/cdk/test/cloudformation/evaluate-cfn.ts +++ b/packages/@aws-cdk/cdk/test/cloudformation/evaluate-cfn.ts @@ -3,6 +3,8 @@ * * Note that this function is not production quality, it exists to support tests. */ +import { isNameOfCloudFormationIntrinsic } from '../../lib/cloudformation/instrinsics'; + export function evaluateCFN(object: any, context: {[key: string]: string} = {}): any { const intrinsics: any = { 'Fn::Join'(separator: string, args: string[]) { @@ -34,7 +36,7 @@ export function evaluateCFN(object: any, context: {[key: string]: string} = {}): if (typeof obj === 'object') { const keys = Object.keys(obj); - if (keys.length === 1 && (keys[0].startsWith('Fn::') || keys[0] === 'Ref')) { + if (keys.length === 1 && (isNameOfCloudFormationIntrinsic(keys[0]) || keys[0] === 'Ref')) { return evaluateIntrinsic(keys[0], obj[keys[0]]); } diff --git a/packages/@aws-cdk/cdk/test/cloudformation/test.cloudformation-json.ts b/packages/@aws-cdk/cdk/test/cloudformation/test.cloudformation-json.ts index 440e782af6ac6..4b46cab85ff2b 100644 --- a/packages/@aws-cdk/cdk/test/cloudformation/test.cloudformation-json.ts +++ b/packages/@aws-cdk/cdk/test/cloudformation/test.cloudformation-json.ts @@ -92,6 +92,29 @@ export = { test.done(); }, + 'fake intrinsics are serialized to objects'(test: Test) { + const stack = new Stack(); + const fakeIntrinsics = new Token(() => ({ + a: { + 'Fn::GetArtifactAtt': { + key: 'val', + }, + }, + b: { + 'Fn::GetParam': [ + 'val1', + 'val2', + ], + }, + })); + + const stringified = CloudFormationJSON.stringify(fakeIntrinsics, stack); + test.equal(evaluateCFN(stack.node.resolve(stringified)), + '{"a":{"Fn::GetArtifactAtt":{"key":"val"}},"b":{"Fn::GetParam":["val1","val2"]}}'); + + test.done(); + }, + 'embedded string literals in intrinsics are escaped when calling TokenJSON.stringify()'(test: Test) { // GIVEN const stack = new Stack();