How to get subnet ids in the same stack

I’m trying to use CDKTF with Typescript to provision EKS clusters in dedicated VPCs, mostly following along with the example GitHub - hashicorp/learn-terraform-provision-eks-cluster.

Is it possible to create the VPC and the EKS cluster? I can’t seem to get the subnet id to resolve correctly. When I try to use DataAwsSubnets with a filter, it can only discover subnets that already exist, and not the ones that are going to be created. Using vpc.privateSubnets to get the list of subnets (like it’s implied in the learning example should work) doesn’t work, it only returns the CIDR range for the subnet and not the subnet ID.

How do you get the IDs for the to-be-created vpc private subnets?

Attempt 1:

    let vpc = new Vpc(this, `${details.name}-vpc`, {
        ...
    });
    new Eks(this, `${details.name}-eks`, {
      clusterName: `${details.name}`,
      clusterVersion: "1.25",
      vpcId: vpc.vpcIdOutput,
      subnetIds: vpc.privateSubnets,

Result 1, during tf apply:

│ Error: creating EKS Cluster (dev): InvalidParameterException: 
The subnet ID '10.5.224.0/19' does not exist
 (Service: AmazonEC2; Status Code: 400; Error Code: 
InvalidSubnetID.NotFound; 

Attempt 2:

    let subnetData = new DataAwsSubnets(this, `ekssubnets`, {
      filter: [{
        name: "vpc-id",
        values: [vpc.vpcIdOutput]
      }],
      tags: {
        Tier: "private"
      }
    })
    new Eks(this, `${details.name}-eks`, {
      clusterName: `${details.name}`,
      clusterVersion: "1.25",
      vpcId: vpc.vpcIdOutput,
      subnetIds: subnetData.ids,

Result 2, during plan:

Planning failed. Terraform encountered an error while generating this plan.

╷
│ Error: Error in function call
│ 
│   on .terraform/modules/dev-eks/main.tf line 35, in resource "aws_eks_cluster" "this":
│   35:     subnet_ids              = coalescelist(var.control_plane_subnet_ids, var.subnet_ids)
│     ├────────────────
│     │ while calling coalescelist(vals...)
│     │ var.control_plane_subnet_ids is empty list of string
│     │ var.subnet_ids is empty list of string
│ 
│ Call to function "coalescelist" failed: no non-null arguments.

Hi @dwarburt :wave:

it seems like your first approach was almost correct. My guess there would be that you’d have to use subnetIds: vpc.privateSubnetsOutput instead of subnetIds: vpc.privateSubnets. The values with the Output suffix are the values returned from modules.

– Ansgar

Seems like this is closer, but it doesn’t work. As a drop in for vpc.privateSubnets there is a typescript compile error:

TSError: ⨯ Unable to compile TypeScript:
    src/main.ts(92,7): error TS2322: Type 'string' is not assignable to type 'string[]'.

I tried wrapping it with square brackets like subnetIds: [vpc.privateSubnetsOutput] but that synthesizes to

      "subnet_ids": [
        "${module.dev-vpc.private_subnets}"
      ],

which errors during plan like so

Planning failed. Terraform encountered an error while generating this plan.

╷
│ Error: Invalid value for input variable
│ 
│   on cdk.tf.json line 68, in module.dev-eks:
│   68:       "subnet_ids": [
│   69:         "${module.dev-vpc.private_subnets}"
│   70:       ],
│ 
│ The given value is not suitable for module.dev-eks.var.subnet_ids declared at
│ .terraform/modules/dev-eks/variables.tf:53,1-22: element 0: string required.
╵

I can see the vpc.privateSubnetsOutput is just a string with this value

${TfToken[TOKEN.3]}

${TfToken[TOKEN.9]}

So I think i have to transform these tokens somehow, but they’re not tokens, just the string identifiers of tokens. How to proceed?

This exact problem is the example in Tokens - CDK for Terraform | Terraform | HashiCorp Developer and now that I’ve read that I can see that Token.asList is what I need here, and that does work. Thanks for the answer, @ansgarm !