aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.57k stars 3.88k forks source link

aws-cdk-lib: NestedStack reference of CustomResource with Fn results in "id.replace is not a function" #30130

Open hakenmt opened 4 months ago

hakenmt commented 4 months ago

Describe the bug

When I pass a custom resource to a nested stack via props, and then use getAttString() on the custom resource with an input of something like Fn.ref(AWS::Region), when I call app.synth(), I get TypeError: id.replace is not a function.

Expected Behavior

I expect this to work as it does when the custom resource is created in the nested stack. This error does not occur if the custom resource is not passed across stacks via props.

Current Behavior

TypeError: id.replace is not a function

   9 |     const stack = new BugStack(app, 'MyTestStack');
  10 |     
> 11 |     app.synth();
     |         ^
  12 |
  13 |     const template = Template.fromStack(stack);
  14 | });

  at sanitizeId (node_modules/constructs/src/construct.ts:552:13)
  at Node.tryFindChild (node_modules/constructs/src/construct.ts:119:27)
  at createNestedStackParameter (node_modules/aws-cdk-lib/core/lib/private/refs.js:1:6613)
  at resolveValue (node_modules/aws-cdk-lib/core/lib/private/refs.js:1:3177)
  at resolveReferences (node_modules/aws-cdk-lib/core/lib/private/refs.js:1:1516)
  at prepareApp (node_modules/aws-cdk-lib/core/lib/private/prepare-app.js:1:904)
  at synthesize (node_modules/aws-cdk-lib/core/lib/private/synthesis.js:1:1632)
  at App.synth (node_modules/aws-cdk-lib/core/lib/stage.js:1:2365)
  at Object.<anonymous> (test/bug.test.ts:11:9)

Reproduction Steps

export class BugStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    console.log("Creating bug stack");

    let func: IFunction = new Function(this, "AvailabilityZoneMapperFunction", {
        runtime: Runtime.PYTHON_3_12,
        code: Code.fromInline("\ndef handler(event, context):\n  return"),
        handler: "index.handler",
        memorySize: 512,
    });

    let mapper: CustomResource = new CustomResource(this, "AvailabilityZoneMapper", {
      serviceToken: func.functionArn,
    });

    new NestedStackWithReference(this, "NestedStack", {
      mapper: mapper
    });
  }
}

export interface NestedStackWithReferenceProps extends NestedStackProps
{
  readonly mapper: CustomResource;
}

export class NestedStackWithReference extends NestedStack
{
  constructor(scope: Construct, id: string, props: NestedStackWithReferenceProps)
  {
    super(scope, id, props);

    new Queue(this, "Queue", {
      queueName: props.mapper.getAttString(Fn.ref("AWS::Region"))
    }); 
  }
}

Possible Solution

No response

Additional Information/Context

No response

CDK CLI Version

2.138.0 (build 6b41c8b)

Framework Version

No response

Node.js Version

v20.9.0

OS

darwin

Language

TypeScript

Language Version

No response

Other information

No response

khushail commented 4 months ago

thanks @hakenmt for reaching out and sharing the code. I am able to repro it. marking it appropriate for the further action