hashicorp / terraform-cdk

Define infrastructure resources using programming constructs and provision them using HashiCorp Terraform
https://www.terraform.io/cdktf
Mozilla Public License 2.0
4.8k stars 443 forks source link

Incorrect bindings generated for the `Azure/naming/azurerm` module. #3477

Open jesseward opened 5 months ago

jesseward commented 5 months ago

Expected Behavior

The bindings generated for the https://github.com/Azure/terraform-azurerm-naming module do not correctly reference the output maps defined in their module..

For this module, the outputs function should return a map instead of a string. Or some other function that provides access to the output (that contains 8 keys). See https://github.com/Azure/terraform-azurerm-naming/blob/8a1c8616d4cd05423e53c3260a016919ce0df33d/main.tf#L1869-L1878

Actual Behavior

The creation of the cdktf bindings for the "Azure/naming/azurerm" module (https://github.com/Azure/terraform-azurerm-naming) do not properly handle their map output values.

The root of the issue is that the language specific functions generated for this module yields a token that references a key->value map type, and not the actual output (string) value.

For example, calling ResourceGroupOutput() yields ${module.resourceNaming.resource_group}, where the resource_group output value is actually a map. When running tf plan, we're greeted with the error module.resourceNaming.resource_group is object with 8 attributes

The module reference in question can be found at main.tf and output.tf

Steps to Reproduce

I have created an example repo that provides guidance on how to reproduce this behaviour. See https://github.com/jesseward/cdktf-aznaming-output-failure-example for details.

Versions

language: go

providers

Providers

┌───────────────┬──────────────────┬───────┬────────────┬──────────────┬─────────────────┐
│ Provider Name │ Provider Version │ CDKTF │ Constraint │ Package Name │ Package Version │
├───────────────┼──────────────────┼───────┼────────────┼──────────────┼─────────────────┤
│ azurerm       │ 3.89.0           │       │ ~>3        │              │                 │
└───────────────┴──────────────────┴───────┴────────────┴──────────────┴─────────────────┘

Gist

https://github.com/jesseward/cdktf-aznaming-output-failure-example

Possible Solutions

No response

Workarounds

Modify the cdktf.json that references the module output, to specify the key in question. For example

        "name": "${module.resourceNaming.resource_group[\"name\"]}"

Anything Else?

I am not sure if this is a bug or expected behaviour due to an unsupported model of mapping output values within a module.

References

Looks like others have encountered similar issues as well and raised the following in the Azure/terraform-azurerm-naming repo.

Help Wanted

Community Note

ansgarm commented 5 months ago

Hi @jesseward 👋

Thank you for raising this. It is true that all outputs are currently typed as strings. This is a current shortcoming that happens because types of outputs are inferred by Terraform and not part of the configuration as its written. This means that a future version of cdktf get has to invoke parts of Terraform to parse and evaluate the module in order to get the types right.

For your case it should be possible to use Fn.Lookup(someModule.ResourceGroupOutput(), "name") to get to the right value. There is also Token.AsList() which can be used to turn the string output into a list token which would be the correct output type we'd expect.

jesseward commented 5 months ago

hey @ansgarm, thanks for the pointer here. I tested the Fn_Lookup(..) function and it works as advertised 🙇

I have added some notes to README.md and I updated my sample code at main.go.

Does it make sense to document this scenario? Or is this something that could be easily inferred from the cdktf docs in general. This was my first rodeo with cdktf and hit this early on, so admittedly haven't dove through the entirety of the gotchas/usage oddities.