-
Notifications
You must be signed in to change notification settings - Fork 4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(core): unable to reference resources across multiple nested stacks (
#7187) Fixes #6473 by centralizing the logic to resolve cross-references and prepare nested stack template assets in `App.prepare`, which has a global view of the app and is the last prepare to execute before synthesis. This dramatically simplified reference resolution and allows dealing with nested stack assets only after all cross references have been resolved (the root cause for #7059). This logic is implemented in a function called `prepareApp` which is normally called from `App.prepare()` but if a `Stack` is created as a root (normally in unit tests, we invoke this logic from there to retain current behavior). This algorithm takes care of both resolving cross references and add template assets for nested stacks. This is because assets are currently addressed using CFN parameters, which means that when we adding them to the parent of a nested stack, the parent is mutated, so we need to rectify references again. To make sure this is done correctly, we always create assets in DFS order. All changes to the test snapshots stem from new asset IDs of nested stack templates, not the template themselves. The change is a result of the fact that the refactor caused the "Parameters" section to appear in a different place in the template, but the template itself is identical. Fixes #7059 by first resolving all references in the app and only then calculating the hash of the nested stack templates for their assets. Fixes #5888 but this was not verified.
- Loading branch information
Elad Ben-Israel
authored
Apr 16, 2020
1 parent
4ab3ffa
commit 000f0c2
Showing
17 changed files
with
882 additions
and
289 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
116 changes: 116 additions & 0 deletions
116
packages/@aws-cdk/aws-cloudformation/test/integ.nested-stacks-multi-refs.expected.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
{ | ||
"Resources": { | ||
"Level1ABBD39B3": { | ||
"Type": "AWS::SNS::Topic" | ||
}, | ||
"Nested1NestedStackNested1NestedStackResourceCD0AD36B": { | ||
"Type": "AWS::CloudFormation::Stack", | ||
"Properties": { | ||
"TemplateURL": { | ||
"Fn::Join": [ | ||
"", | ||
[ | ||
"https://s3.", | ||
{ | ||
"Ref": "AWS::Region" | ||
}, | ||
".", | ||
{ | ||
"Ref": "AWS::URLSuffix" | ||
}, | ||
"/", | ||
{ | ||
"Ref": "AssetParametersad23da1cfc8b3fd7916c6ffc7debacadf084765e62fab8acf0b8b0a9b0289f95S3BucketDB605F9E" | ||
}, | ||
"/", | ||
{ | ||
"Fn::Select": [ | ||
0, | ||
{ | ||
"Fn::Split": [ | ||
"||", | ||
{ | ||
"Ref": "AssetParametersad23da1cfc8b3fd7916c6ffc7debacadf084765e62fab8acf0b8b0a9b0289f95S3VersionKey26685906" | ||
} | ||
] | ||
} | ||
] | ||
}, | ||
{ | ||
"Fn::Select": [ | ||
1, | ||
{ | ||
"Fn::Split": [ | ||
"||", | ||
{ | ||
"Ref": "AssetParametersad23da1cfc8b3fd7916c6ffc7debacadf084765e62fab8acf0b8b0a9b0289f95S3VersionKey26685906" | ||
} | ||
] | ||
} | ||
] | ||
} | ||
] | ||
] | ||
}, | ||
"Parameters": { | ||
"referencetonestedstacksmultirefsLevel19FB2466DTopicName": { | ||
"Fn::GetAtt": [ | ||
"Level1ABBD39B3", | ||
"TopicName" | ||
] | ||
}, | ||
"referencetonestedstacksmultirefsAssetParameters495a6bc36c13a0adeb3778c921d18ac4a8205f5471108fcc199a291d14855c3aS3Bucket03F0C3B1Ref": { | ||
"Ref": "AssetParameters495a6bc36c13a0adeb3778c921d18ac4a8205f5471108fcc199a291d14855c3aS3Bucket58724FCA" | ||
}, | ||
"referencetonestedstacksmultirefsAssetParameters495a6bc36c13a0adeb3778c921d18ac4a8205f5471108fcc199a291d14855c3aS3VersionKey5F9CF809Ref": { | ||
"Ref": "AssetParameters495a6bc36c13a0adeb3778c921d18ac4a8205f5471108fcc199a291d14855c3aS3VersionKey2CCE0573" | ||
}, | ||
"referencetonestedstacksmultirefsAssetParameterscc623add53df153cf6a7df1cea4dc90740d7be087472579110754a633ec90847S3Bucket8F1E17B9Ref": { | ||
"Ref": "AssetParameterscc623add53df153cf6a7df1cea4dc90740d7be087472579110754a633ec90847S3Bucket9A14AA6D" | ||
}, | ||
"referencetonestedstacksmultirefsAssetParameterscc623add53df153cf6a7df1cea4dc90740d7be087472579110754a633ec90847S3VersionKey9EEEF950Ref": { | ||
"Ref": "AssetParameterscc623add53df153cf6a7df1cea4dc90740d7be087472579110754a633ec90847S3VersionKeyF124C0D9" | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
"Parameters": { | ||
"AssetParameters495a6bc36c13a0adeb3778c921d18ac4a8205f5471108fcc199a291d14855c3aS3Bucket58724FCA": { | ||
"Type": "String", | ||
"Description": "S3 bucket for asset \"495a6bc36c13a0adeb3778c921d18ac4a8205f5471108fcc199a291d14855c3a\"" | ||
}, | ||
"AssetParameters495a6bc36c13a0adeb3778c921d18ac4a8205f5471108fcc199a291d14855c3aS3VersionKey2CCE0573": { | ||
"Type": "String", | ||
"Description": "S3 key for asset version \"495a6bc36c13a0adeb3778c921d18ac4a8205f5471108fcc199a291d14855c3a\"" | ||
}, | ||
"AssetParameters495a6bc36c13a0adeb3778c921d18ac4a8205f5471108fcc199a291d14855c3aArtifactHashAE1436B7": { | ||
"Type": "String", | ||
"Description": "Artifact hash for asset \"495a6bc36c13a0adeb3778c921d18ac4a8205f5471108fcc199a291d14855c3a\"" | ||
}, | ||
"AssetParameterscc623add53df153cf6a7df1cea4dc90740d7be087472579110754a633ec90847S3Bucket9A14AA6D": { | ||
"Type": "String", | ||
"Description": "S3 bucket for asset \"cc623add53df153cf6a7df1cea4dc90740d7be087472579110754a633ec90847\"" | ||
}, | ||
"AssetParameterscc623add53df153cf6a7df1cea4dc90740d7be087472579110754a633ec90847S3VersionKeyF124C0D9": { | ||
"Type": "String", | ||
"Description": "S3 key for asset version \"cc623add53df153cf6a7df1cea4dc90740d7be087472579110754a633ec90847\"" | ||
}, | ||
"AssetParameterscc623add53df153cf6a7df1cea4dc90740d7be087472579110754a633ec90847ArtifactHashAF64C405": { | ||
"Type": "String", | ||
"Description": "Artifact hash for asset \"cc623add53df153cf6a7df1cea4dc90740d7be087472579110754a633ec90847\"" | ||
}, | ||
"AssetParametersad23da1cfc8b3fd7916c6ffc7debacadf084765e62fab8acf0b8b0a9b0289f95S3BucketDB605F9E": { | ||
"Type": "String", | ||
"Description": "S3 bucket for asset \"ad23da1cfc8b3fd7916c6ffc7debacadf084765e62fab8acf0b8b0a9b0289f95\"" | ||
}, | ||
"AssetParametersad23da1cfc8b3fd7916c6ffc7debacadf084765e62fab8acf0b8b0a9b0289f95S3VersionKey26685906": { | ||
"Type": "String", | ||
"Description": "S3 key for asset version \"ad23da1cfc8b3fd7916c6ffc7debacadf084765e62fab8acf0b8b0a9b0289f95\"" | ||
}, | ||
"AssetParametersad23da1cfc8b3fd7916c6ffc7debacadf084765e62fab8acf0b8b0a9b0289f95ArtifactHashAF8D54FC": { | ||
"Type": "String", | ||
"Description": "Artifact hash for asset \"ad23da1cfc8b3fd7916c6ffc7debacadf084765e62fab8acf0b8b0a9b0289f95\"" | ||
} | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
packages/@aws-cdk/aws-cloudformation/test/integ.nested-stacks-multi-refs.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import * as sns from '@aws-cdk/aws-sns'; | ||
import { App, Fn, Stack } from '@aws-cdk/core'; | ||
import { NestedStack } from '../lib'; | ||
|
||
const app = new App(); | ||
const top = new Stack(app, 'nested-stacks-multi-refs'); | ||
const level1 = new sns.Topic(top, 'Level1'); | ||
const nested1 = new NestedStack(top, 'Nested1'); | ||
const nested2 = new NestedStack(nested1, 'Nested2'); | ||
const nested3 = new NestedStack(nested2, 'Nested3'); | ||
|
||
// WHEN | ||
const level2 = new sns.Topic(nested2, 'Level2ReferencesLevel1', { | ||
displayName: shortName(level1.topicName) | ||
}); | ||
|
||
new sns.Topic(nested3, 'Level3ReferencesLevel1', { | ||
displayName: shortName(level1.topicName) | ||
}); | ||
|
||
new sns.Topic(nested3, 'Level3ReferencesLevel2', { | ||
displayName: shortName(level2.topicName) | ||
}); | ||
|
||
app.synth(); | ||
|
||
// topicName is too long for displayName, so just take the second part: | ||
// Stack1-NestedUnderStack1NestedStackNestedUnderStack1NestedStackResourceF616305B-EM64TEGA04J9-TopicInNestedUnderStack115E329C4-HEO7NLYC1AFL | ||
function shortName(topicName: string) { | ||
return Fn.select(1, Fn.split('-', topicName)); | ||
} |
Oops, something went wrong.