Skip to content

Commit 561bb73

Browse files
Elad Ben-Israelmergify[bot]
authored andcommitted
fix(cloudformation): cannot reference resource attributes with "." in nested stacks (#4684)
When rendering the "GetAtt" to reference an auto-generated nested stack output we did not use the actual `output.logicalId`, which can differ from the `id` passed into the output (for example, periods are omitted since they are not supported in logical IDs). This change uses the actual logical ID, but then requires that for sibling-references we resolve this string since it's used for the logical ID of the parameter. Yeah, tricky.
1 parent 5d2e5e3 commit 561bb73

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

packages/@aws-cdk/aws-cloudformation/lib/nested-stack.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,8 @@ export class NestedStack extends Stack {
149149
// the nested stack references a resource from the parent stack:
150150
// we pass it through a as a cloudformation parameter
151151
if (targetStack === sourceStack.parentStack) {
152-
const paramId = `reference-to-${reference.target.node.uniqueId}.${reference.displayName}`;
152+
// we call "this.resolve" to ensure that tokens do not creep in (for example, if the reference display name includes tokens)
153+
const paramId = this.resolve(`reference-to-${reference.target.node.uniqueId}.${reference.displayName}`);
153154
let param = this.node.tryFindChild(paramId) as CfnParameter;
154155
if (!param) {
155156
param = new CfnParameter(this, paramId, { type: 'String' });
@@ -195,7 +196,7 @@ export class NestedStack extends Stack {
195196
output = new CfnOutput(this, outputId, { value: Token.asString(reference) });
196197
}
197198

198-
return this.resource.getAtt(`Outputs.${outputId}`);
199+
return this.resource.getAtt(`Outputs.${output.logicalId}`);
199200
}
200201

201202
private contextualAttribute(innerValue: string, outerValue: string) {

packages/@aws-cdk/aws-cloudformation/test/test.nested-stack.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,50 @@ export = {
827827
data: 'bar'
828828
}
829829
]);
830+
test.done();
831+
},
832+
833+
'referencing attributes with period across stacks'(test: Test) {
834+
// GIVEN
835+
const parent = new Stack();
836+
const nested = new NestedStack(parent, 'nested');
837+
const consumed = new CfnResource(nested, 'resource-in-nested', { type: 'CONSUMED' });
838+
839+
// WHEN
840+
new CfnResource(parent, 'resource-in-parent', {
841+
type: 'CONSUMER',
842+
properties: {
843+
ConsumedAttribute: consumed.getAtt('Consumed.Attribute')
844+
}
845+
});
846+
847+
// THEN
848+
expect(nested).toMatch({
849+
Resources: {
850+
resourceinnested: {
851+
Type: "CONSUMED"
852+
}
853+
},
854+
Outputs: {
855+
nestedresourceinnested59B1F01CConsumedAttribute: {
856+
Value: {
857+
"Fn::GetAtt": [
858+
"resourceinnested",
859+
"Consumed.Attribute"
860+
]
861+
}
862+
}
863+
}
864+
});
865+
expect(parent).to(haveResource('CONSUMER', {
866+
ConsumedAttribute: {
867+
"Fn::GetAtt": [
868+
"nestedNestedStacknestedNestedStackResource3DD143BF",
869+
"Outputs.nestedresourceinnested59B1F01CConsumedAttribute"
870+
]
871+
}
872+
}));
873+
830874
test.done();
831875
}
832876
};

0 commit comments

Comments
 (0)