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.51k stars 3.85k forks source link

Cannot find a Stack parent for 'SecurityGroupResource [lb/SecurityGroup/Resource]' #756

Closed dsilvasc closed 5 years ago

dsilvasc commented 5 years ago

repro in scala:

case class DemoStack(app: App, stackName: String, stackProps: StackProps, instanceType: String = "t2.medium")
    extends Stack(app, stackName, stackProps) {

  private val vpc = SharedInfra.vpc(this)

  new LoadBalancer(app, "lb", LoadBalancerProps.builder.withVpc(vpc).build)
}

object SharedInfra {
  def vpc(parent: Construct): VpcNetworkRef = {
    val props = VpcNetworkRefProps.builder
      .withVpcId("test-vpc-id")
      .withAvailabilityZones(Arrays.asList("us-east-1a"))
      .withPublicSubnetIds(Arrays.asList("test-public-id"))
      .withPrivateSubnetIds(Arrays.asList("test-private-id"))
      .build()
    VpcNetworkRef.import_(parent, "SharedInfraVPC", props)
  }
}

object DemoCDKSynth {
  def main(args: Array[String]): Unit = {
    val app = new software.amazon.awscdk.App
    val props = StackProps.builder.withEnv(Environment.builder.withRegion("us-east-1").build).build
    val stack = DemoStack(app, "demo-cdk", props)
    val output = app.synthesizeStack(stack.getName)
    println(output.getTemplate)
  }
}

Output:

Exception in thread "main" software.amazon.jsii.JsiiException: Cannot find a Stack parent for 'SecurityGroupResource [lb/SecurityGroup/Resource]'
Error: Cannot find a Stack parent for 'SecurityGroupResource [lb/SecurityGroup/Resource]'
    at Function.find (/private/var/folders/w8/6myw35gj1j73m5m2bjy_fnzr0000gn/T/jsii-kernel-xukuiz/node_modules/@aws-cdk/cdk/lib/cloudformation/stack.js:51:19)
    at new StackElement (/private/var/folders/w8/6myw35gj1j73m5m2bjy_fnzr0000gn/T/jsii-kernel-xukuiz/node_modules/@aws-cdk/cdk/lib/cloudformation/stack.js:223:25)
    at new Referenceable (/private/var/folders/w8/6myw35gj1j73m5m2bjy_fnzr0000gn/T/jsii-kernel-xukuiz/node_modules/@aws-cdk/cdk/lib/cloudformation/stack.js:271:1)
    at new Resource (/private/var/folders/w8/6myw35gj1j73m5m2bjy_fnzr0000gn/T/jsii-kernel-xukuiz/node_modules/@aws-cdk/cdk/lib/cloudformation/resource.js:15:9)
    at new SecurityGroupResource (/private/var/folders/w8/6myw35gj1j73m5m2bjy_fnzr0000gn/T/jsii-kernel-xukuiz/node_modules/@aws-cdk/aws-ec2/lib/ec2.generated.js:2490:13)
    at new SecurityGroup (/private/var/folders/w8/6myw35gj1j73m5m2bjy_fnzr0000gn/T/jsii-kernel-xukuiz/node_modules/@aws-cdk/aws-ec2/lib/security-group.js:57:30)
    at new LoadBalancer (/private/var/folders/w8/6myw35gj1j73m5m2bjy_fnzr0000gn/T/jsii-kernel-xukuiz/node_modules/@aws-cdk/aws-elasticloadbalancing/lib/load-balancer.js:28:30)
    at s._wrapSandboxCode (/private/var/folders/w8/6myw35gj1j73m5m2bjy_fnzr0000gn/T/jsii-java-runtime4905811189423068361/jsii-runtime.js:1:83354)
    at t.Kernel._wrapSandboxCode (/private/var/folders/w8/6myw35gj1j73m5m2bjy_fnzr0000gn/T/jsii-java-runtime4905811189423068361/jsii-runtime.js:1:90978)
    at t.Kernel._create (/private/var/folders/w8/6myw35gj1j73m5m2bjy_fnzr0000gn/T/jsii-java-runtime4905811189423068361/jsii-runtime.js:1:83333)
    at t.Kernel.create (/private/var/folders/w8/6myw35gj1j73m5m2bjy_fnzr0000gn/T/jsii-java-runtime4905811189423068361/jsii-runtime.js:1:78437)
    at t.KernelHost.processRequest (/private/var/folders/w8/6myw35gj1j73m5m2bjy_fnzr0000gn/T/jsii-java-runtime4905811189423068361/jsii-runtime.js:1:75203)
    at t.KernelHost.run (/private/var/folders/w8/6myw35gj1j73m5m2bjy_fnzr0000gn/T/jsii-java-runtime4905811189423068361/jsii-runtime.js:1:74892)
    at e.processRequest (/private/var/folders/w8/6myw35gj1j73m5m2bjy_fnzr0000gn/T/jsii-java-runtime4905811189423068361/jsii-runtime.js:1:74918)
    at t.KernelHost.processRequest (/private/var/folders/w8/6myw35gj1j73m5m2bjy_fnzr0000gn/T/jsii-java-runtime4905811189423068361/jsii-runtime.js:1:75657)
    at t.KernelHost.run (/private/var/folders/w8/6myw35gj1j73m5m2bjy_fnzr0000gn/T/jsii-java-runtime4905811189423068361/jsii-runtime.js:1:74892)
    at e.processRequest (/private/var/folders/w8/6myw35gj1j73m5m2bjy_fnzr0000gn/T/jsii-java-runtime4905811189423068361/jsii-runtime.js:1:74918)
    at i.then.e (/private/var/folders/w8/6myw35gj1j73m5m2bjy_fnzr0000gn/T/jsii-java-runtime4905811189423068361/jsii-runtime.js:1:75531)
    at <anonymous>
        at software.amazon.jsii.JsiiRuntime.processErrorResponse(JsiiRuntime.java:118)
        at software.amazon.jsii.JsiiRuntime.requestResponse(JsiiRuntime.java:90)
        at software.amazon.jsii.JsiiRuntime.processCallbackResponse(JsiiRuntime.java:163)
        at software.amazon.jsii.JsiiRuntime.requestResponse(JsiiRuntime.java:95)
        at software.amazon.jsii.JsiiClient.createObject(JsiiClient.java:101)
        at software.amazon.jsii.JsiiEngine.createNewObject(JsiiEngine.java:447)
        at software.amazon.awscdk.services.elasticloadbalancing.LoadBalancer.<init>(LoadBalancer.java:16)

Looks like a bug in my stack whose fix is to change new LoadBalancer(app to new LoadBalancer(this. It would be nice to catch this at compile time.

Should the constructor for LoadBalancer take a Stack instead of a Construct for its parent, since that's what it actually needs at runtime?

rix0rrr commented 5 years ago

It doesn't need a Stack as its direct parent, but it does need it somewhere up the construct tree. This is hard to encode with types, so it's has to be a runtime check.