-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
core: Double nested stack outputs not resolved correctly #15155
Comments
Hey @MasonHM, thanks for reporting the issue, and for the awesome small reproduction, as always! Unfortunately, I'm afraid you're running into a limitation/bug of the CDK Nested Stack support, not necessarily anything with You can see that in the following example: import * as cdk from '@aws-cdk/core';
import * as s3 from '@aws-cdk/aws-s3';
class DoubleNestedStack2 extends cdk.Stack {
public readonly outputBucket: s3.CfnBucket;
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const middleStack = new cdk.NestedStack(this, 'MiddleStack');
const bottomStack = new cdk.NestedStack(middleStack, 'BottomStack', {
parameters: {
'Name': 'anything',
},
});
const cfnParameter = new cdk.CfnParameter(bottomStack, 'Name');
const cfnBucket = new s3.CfnBucket(bottomStack, 'Bucket', {
bucketName: cfnParameter.valueAsString,
});
this.outputBucket = cfnBucket;
}
}
interface OtherStackProps extends cdk.StackProps {
readonly bucketName: string;
}
class OtherStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props: OtherStackProps) {
super(scope, id, props);
const newBucket = new s3.Bucket(this, 'newBucket', {
bucketName: props.bucketName,
});
}
}
const app = new cdk.App();
const doubleNestedStack2 = new DoubleNestedStack2(app, 'DoubleNestedStack2');
new OtherStack(app, 'OtherStack2', {
bucketName: doubleNestedStack2.outputBucket.bucketName!,
}); Which fails synthesis with roughly the same error as your example:
|
I can even minimize the reproduction further: import * as cdk from '@aws-cdk/core';
import * as s3 from '@aws-cdk/aws-s3';
class DoubleNestedStack2 extends cdk.Stack {
public readonly outputBucket: s3.CfnBucket;
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const middleStack = new cdk.NestedStack(this, 'MiddleStack');
const bottomStack = new cdk.NestedStack(middleStack, 'BottomStack');
this.outputBucket = new s3.CfnBucket(bottomStack, 'Bucket');
}
}
interface OtherStackProps extends cdk.StackProps {
readonly bucketName: string;
}
class OtherStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props: OtherStackProps) {
super(scope, id, props);
new s3.Bucket(this, 'newBucket', {
bucketName: props.bucketName,
});
}
}
const app = new cdk.App();
const doubleNestedStack2 = new DoubleNestedStack2(app, 'DoubleNestedStack2');
new OtherStack(app, 'OtherStack2', {
bucketName: doubleNestedStack2.outputBucket.ref,
}); |
Looks like the problem is here:
Apparently |
Paging @eladb on this one, as he's much more proficient at Nested Stacks than I am 🙂. |
I'll take a look next week |
Any update on this issue? |
@eladb did you have a chance to look at this error? |
When the CDK generates a CloudFormation output to communicate information from the nested stack, it uses the `reference.displayName` property to increase uniqueness. If the display name includes a token, the id of the generated output includes a token and that’s not allowed. The fix is to do the same thing we do for parameter IDs: `resolve()` the generated output ID before using it. Fixes #15155
When the CDK generates a CloudFormation output to communicate information from the nested stack, it uses the `reference.displayName` property to increase uniqueness. If the display name includes a token, the id of the generated output includes a token and that’s not allowed. The fix is to do the same thing we do for parameter IDs: `resolve()` the generated output ID before using it. Fixes #15155 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
|
…5380) When the CDK generates a CloudFormation output to communicate information from the nested stack, it uses the `reference.displayName` property to increase uniqueness. If the display name includes a token, the id of the generated output includes a token and that’s not allowed. The fix is to do the same thing we do for parameter IDs: `resolve()` the generated output ID before using it. Fixes aws#15155 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
When multiple stacks are nested inside of each other, accessing resources that depend on parameters doesn't seem to work correctly. I don't have a good explanation of what is happening, but I have multiple ways to fix whatever the problem is.
The CloudFormation I'm trying to import that is failing looks like:
The problem we're running into is using the
TargetGroup
fromload-balancer-stack-1.yaml
in some new CDK resources.This is related to #1374
Reproduction Steps
bin/cdk-test.ts
:parent-stack.yaml
:middle-stack.yaml
:bottom-stack.yaml
:What did you expect to happen?
I expected
cdk synth
to work and myOtherStack
to be able to reference the double nested stack's resource. (I realize that I'm trying to name an S3 bucket the same thing as another bucket, but that's not the problem)What actually happened?
Failure Output:
cdk synth
failed due to CDK using a token in the ID of an internal construct. The code for this ID seems to be here:aws-cdk/packages/@aws-cdk/core/lib/private/refs.ts
Line 204 in 7966f8d
I've found multiple ways to avoid the problem:
bottom-stack.yaml
'sBucketName
property to a string instead of a reference to a parameterOtherStack
or its usage ofBottomStack
's outputEnvironment
Other
This is 🐛 Bug Report
The text was updated successfully, but these errors were encountered: