Terraform CDKTF How to Access Data List Attribute with Python Within Resource

889 Views Asked by At

I have this Terraform HCL code which works perfectly:

data "aws_availability_zones" "zones" {
  state = "available"
}

resource "aws_vpc" "CustomVpc" {
  cidr_block       = "10.0.0.0/16"

  tags = {
    Name = "dcb-vpc"
  }
}

resource "aws_subnet" "Subnet" {
  count = length(data.aws_availability_zones.zones.names)
  vpc_id     = aws_vpc.CustomVpc.id
  availability_zone = data.aws_availability_zones.zones.names[count.index]
  cidr_block = cidrsubnet("10.0.0.0/16", 8, count.index)

  tags = {
    Name = "dcb-subnet"
  }
}

output availability_zones {
  value = data.aws_availability_zones.zones.names[*]
}

Created this CDTF python code that does not work:

        zones = datasources.DataAwsAvailabilityZones(self, "zones",
                                                    state = "available")

        myVpc = vpc.Vpc(self, "CustomVpc",
                        tags = {"Name":"dcb-vpc"},
                        cidr_block = '10.0.0.0/16')

        subnet = vpc.Subnet(self, "Subnet",
                            vpc_id = myVpc.id,
                            availability_zone="${{zones.names[count.index]}}",
                            cidr_block="${cidrsubnet(\"10.0.0.0/16\", 8, count.index)}",
                            tags = {"Name":"dcb-subnet"})

        subnet.add_override("count", Fn.length_of(zones.names))

        TerraformOutput(self, "azs",
                        value=zones.names)

Getting the error below.

│ Error: Reference to undeclared resource │ │ on cdk.tf.json line 138, in resource.aws_subnet.Subnet: │ 138: "availability_zone": "${zones.names[count.index]}", │ │ A managed resource "zones" "names" has not been declared in the root

How do you reference data resource arrays?

1

There are 1 best solutions below

2
On

This is the offending line: availability_zone="${{zones.names[count.index]}}"

${{...}} tells terraform to execute everything within as a Terraform expression, exactly the right choice for this iterative behaviour. The problem is you are referring to the python variable named zones within a string, so there is no way for terraform (and cdktf) to know that you meant the variables content, therefore it's interpretet as Terraform (since it happens to also be a possibly valid terraform expression).

To solve this you need to use sth like this: availability_zone="${{ {}[count.index] }}".format(zones.names). On synthesise time the format will be executed putting the stringified version of zones.names in front of the [count.index]. This stringified version will be the correct terraform resource address.