How to make child module resources *stay* inside of the child module when synthesizing?

Hi!

I made a ticket for this issue on github because I wasn’t sure if it was a bug, or a misunderstanding on my part: https://github.com/hashicorp/terraform-cdk/issues/3604

Given a stack that declares a Terraform module:

// main.ts

import { Construct } from "constructs";
import { App, TerraformStack } from "cdktf";
import * as ModuleA from "./modules/moduleA/main";

class MyStack extends TerraformStack {
  constructor(scope: Construct, id: string) {
    super(scope, id);

    new ModuleA.ModuleA(this, "module_a", {
      source: "./modules/moduleA",
    });
  }
}

const app = new App();
new MyStack(app, "mystack");
app.synth();

And the module contains a scoped resource:

// modules/moduleA/main.ts

import { TerraformModule, TerraformModuleConfig } from "cdktf";
import { Construct } from "constructs";
import { RandomProvider } from "@cdktf/provider-random/lib/provider";
import { Id as RandomId } from "@cdktf/provider-random/lib/id";

export class ModuleA extends TerraformModule {
  public constructor(
    scope: Construct,
    id: string,
    config: TerraformModuleConfig
  ) {
    super(scope, id, {
      ...config,
    });
    new RandomProvider(this, "default");
    new RandomId(this, "mod_a_resource_one", {
      byteLength: 2,
    });
  }
}

I expected to see the resource inside of the module in the synthesized hcl, because it was specified in a different scope, like this for example:

// cdktf.out/stacks/mystack/cdk.tf

terraform {
  required_providers {
    random = {
      version = "3.6.0"
      source  = "hashicorp/random"
    }
  }
  backend "local" {
    path = "<path>/terraform.mystack.tfstate"
  }
}

module "module_a" {
  source = "./assets/__cdktf_module_asset_26CE565C/AED96664F96F513147DECF4060B0C6AE"
}
// ./assets/__cdktf_module_asset_26CE565C/AED96664F96F513147DECF4060B0C6AE/main.tf

provider "random" {
}
resource "random_id" "mod_a_resource_one_0BDEBAC6" {
  byte_length = 2
}

But to my surprise, the resource that was created in the terraform module wasn’t actually in the module:

// cdktf.out/stacks/mystack/cdk.tf

terraform {
  required_providers {
    random = {
      version = "3.6.0"
      source  = "hashicorp/random"
    }
  }
  backend "local" {
    path = "/<path>/terraform.mystack.tfstate"
  }
}

module "module_a" {
  source = "./assets/__cdktf_module_asset_26CE565C/AED96664F96F513147DECF4060B0C6AE"
}

provider "random" {
}
resource "random_id" "module_a_mod_a_resource_one_0BDEBAC6" {
  byte_length = 2
}

For context, this is how my remote state file currently looks. Resources are nested inside of child modules, and those modules are then referenced in the main.tf, but the child resources are not exposed in that file, if that makes sense.

I wanted to migrate my state from HCL files to CDKTF, but keep the same resource ID’s/configuration structure, so I was hoping I could reverse-engineer my config with cdktf synth --hcl. Is this possible?

One thing I noticed is that synth produces a state file with a version value equal to 3, while my pre-existing terraform.tfstate in production has a version value equal to 4. I wonder if that’s related somehow?

Any thoughts/advice would be appreciated :pray: thank you