terraform-cdk icon indicating copy to clipboard operation
terraform-cdk copied to clipboard

azurerm: AzurermProviderFeatures Value is not an array

Open JordanSussman opened this issue 1 year ago • 6 comments

Expected Behavior

Upgrading from github.com/cdktf/cdktf-provider-azurerm-go/azurerm/v12/provider to github.com/cdktf/cdktf-provider-azurerm-go/azurerm/v13/provider works without issues.

Actual Behavior

Upgrading from v12 to v13 results in the following errors:

[2024-11-19T18:21:49.369] [ERROR] default - panic: Passed to parameter config of new @cdktf/provider-azurerm.provider.AzurermProvider: Unable to deserialize value as @cdktf/provider-azurerm.provider.AzurermProviderConfig | undefined
	├── 🛑 Failing value is an object
	│      { '$jsii.struct': [Object] }
	╰── 🔍 Failure reason(s):
	    ╰─ Key 'features': Unable to deserialize value as cdktf.IResolvable | array<@cdktf/provider-azurerm.provider.AzurermProviderFeatures> | undefined
	        ├── 🛑 Failing value is an object
	        │      { '$jsii.struct': [Object] }
	        ╰── 🔍 Failure reason(s):
	            ├─ [as array<@cdktf/provider-azurerm.provider.AzurermProviderFeatures>] Value is not an array
	            ╰─ [as cdktf.IResolvable] Value does not have the "$jsii.byref" key

These errors can be resolved after Features is updated from &provider.AzurermProviderFeatures{} to []*provider.AzurermProviderFeatures{}. However, this change results in a differnt error of:

     │ Error: Missing required argument
     │
     │   with provider["registry.terraform.io/hashicorp/azurerm"].test,
     │   on cdk.tf.json line 30, in provider.azurerm[0]:
     │   30:         "features": [
     │   31:         ],
     │
cdk  │ The argument "features" is required, but no definition was found.

Steps to Reproduce

  1. Upgrade github.com/cdktf/cdktf-provider-azurerm-go/azurerm/v12/provider to github.com/cdktf/cdktf-provider-azurerm-go/azurerm/v13/provider
  2. Run cdktf deploy to see panic
  3. Update Features from &provider.AzurermProviderFeatures{} to []*provider.AzurermProviderFeatures{}
  4. Run cdktf deploy to see error of features argument missing

Broken code for v13:

package main

import (
	"github.com/aws/constructs-go/constructs/v10"
	"github.com/aws/jsii-runtime-go"
	"github.com/cdktf/cdktf-provider-azurerm-go/azurerm/v13/dataazurermvirtualnetwork"
	"github.com/cdktf/cdktf-provider-azurerm-go/azurerm/v13/provider"
	"github.com/hashicorp/terraform-cdk-go/cdktf"
)

func NewMyStack(scope constructs.Construct, id string) cdktf.TerraformStack {
	stack := cdktf.NewTerraformStack(scope, &id)

	prov := provider.NewAzurermProvider(stack, jsii.String("test"), &provider.AzurermProviderConfig{
		Alias:                    jsii.String("test"),
		Features:                 []*provider.AzurermProviderFeatures{},
		SubscriptionId:           jsii.String("1234"),
		SkipProviderRegistration: jsii.Bool(true),
		TenantId:                 jsii.String("1234"),
	})

	_ = dataazurermvirtualnetwork.NewDataAzurermVirtualNetwork(stack, jsii.String("fake"), &dataazurermvirtualnetwork.DataAzurermVirtualNetworkConfig{
		Name:              jsii.String("fake"),
		Provider:          prov,
		ResourceGroupName: jsii.String("fake"),
	})

	return stack
}

func main() {
	app := cdktf.NewApp(nil)

	NewMyStack(app, "cdk")

	app.Synth()
}

Working code for v12:

package main

import (
	"github.com/aws/constructs-go/constructs/v10"
	"github.com/aws/jsii-runtime-go"
	"github.com/cdktf/cdktf-provider-azurerm-go/azurerm/v12/dataazurermvirtualnetwork"
	"github.com/cdktf/cdktf-provider-azurerm-go/azurerm/v12/provider"
	"github.com/hashicorp/terraform-cdk-go/cdktf"
)

func NewMyStack(scope constructs.Construct, id string) cdktf.TerraformStack {
	stack := cdktf.NewTerraformStack(scope, &id)

	prov := provider.NewAzurermProvider(stack, jsii.String("test"), &provider.AzurermProviderConfig{
		Alias:                    jsii.String("test"),
		Features:                 &provider.AzurermProviderFeatures{},
		SubscriptionId:           jsii.String("1234"),
		SkipProviderRegistration: jsii.Bool(true),
		TenantId:                 jsii.String("1234"),
	})

	_ = dataazurermvirtualnetwork.NewDataAzurermVirtualNetwork(stack, jsii.String("fake"), &dataazurermvirtualnetwork.DataAzurermVirtualNetworkConfig{
		Name:              jsii.String("fake"),
		Provider:          prov,
		ResourceGroupName: jsii.String("fake"),
	})

	return stack
}

func main() {
	app := cdktf.NewApp(nil)

	NewMyStack(app, "cdk")

	app.Synth()
}

Versions

language: go cdktf-cli: 0.20.10 node: v23.1.0 cdktf: 0.20.9 constructs: 10.4.2 jsii: 1.105.0 terraform: 1.9.8 arch: arm64 os: darwin 24.0.0 go: go version go1.23.3 darwin/arm64 providers github.com/cdktf/cdktf-provider-azurerm-go/azurerm (PREBUILT) terraform provider version: 4.10.0 prebuilt provider version: 13.10.0 cdktf version: ^0.20.0

Providers

┌───────────────┬──────────────────┬─────────┬────────────┬────────────────────────────────────────────────────┬─────────────────┐ │ Provider Name │ Provider Version │ CDKTF │ Constraint │ Package Name │ Package Version │ ├───────────────┼──────────────────┼─────────┼────────────┼────────────────────────────────────────────────────┼─────────────────┤ │ azurerm │ 4.10.0 │ ^0.20.0 │ │ github.com/cdktf/cdktf-provider-azurerm-go/azurerm │ 13.10.0 │ └───────────────┴──────────────────┴─────────┴────────────┴────────────────────────────────────────────────────┴─────────────────┘

Gist

No response

Possible Solutions

No response

Workarounds

No response

Anything Else?

The original error appears to be caused by the changes introduced within https://github.com/cdktf/cdktf-provider-azurerm-go/blob/main/azurerm/provider/AzurermProvider__checks.go#L111-L137.

References

No response

Help Wanted

  • [ ] I'm interested in contributing a fix myself

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

JordanSussman avatar Nov 20 '24 00:11 JordanSussman

The providers major version changed between 12 and 13 so I think the need to adjust the code in general is expected. Have you tried passing nil instead of an empty slice? I think JSII handles them quite differently, nil being handled as a Typescript null which is what you might be expressing here.

DanielMSchmidt avatar Nov 25 '24 09:11 DanielMSchmidt

Setting Features to nil does prevent the Go code from panicking. However, this leads to the same issue where Terraform fails with the error: The argument "features" is required, but no definition was found. because the features argument isn't being defined in the format that Terraform expects.

JordanSussman avatar Nov 25 '24 14:11 JordanSussman

Same problem in C#, the example is not up-to-date.

https://github.com/hashicorp/terraform-cdk/blob/main/examples/csharp/azure/Main.cs#L19

I'm getting a first error that I was able to fix using this instead

Features = new IAzurermProviderFeatures[]
{
    new AzurermProviderFeatures()
}

But then I'm getting the same error

        │ Error: Invalid provider configuration
        │ 
        │ Provider "registry.terraform.io/hashicorp/azurerm" requires explicit
        │ configuration. Add a provider block to the root module and configure the
        │ provider's required arguments as described in the provider documentation.
        │ 
        ╵
        ╷
        │ Error: Missing required argument
        │ 
        │   with provider["registry.terraform.io/hashicorp/azurerm"],
        │   on <empty> line 0:
        │   (source code not available)
        │ 
        │ The argument "features" is required, but no definition was found.
        ╵

Socolin avatar Feb 05 '25 20:02 Socolin

This is by no means an ideal solution, but I used a basic jq command to modify the output file from cdktf synth to match the format Terraform requires. This serves as a temporary workaround until the official fix is available. For those interested, the steps are:

  1. cdktf synth --output test
  2. jq '.provider.azurerm[].features |= if . == [] then {} else . end' test/stacks/cdk/cdk.tf.json > updated.json && mv updated.json test/stacks/cdk/cdk.tf.json"

JordanSussman avatar Feb 05 '25 21:02 JordanSussman

The same issue is for Java: the expectation is to have a List, and the only way to set the features is viathe reflection API. The sample won't work. https://github.com/cdktf/cdktf-provider-azurerm/blob/v12.27.0/docs/provider.java.md is the last version of spec that works, anything v13 and above is broken.

Malinskiy avatar Apr 19 '25 05:04 Malinskiy

Frustrating for sure especially the silence. Looking at the code and via trial and error I was able to determine how to pass the provider config correctly, if you want to call it that.

It seems to expect that features is passed via a Slice and that slice cannot be empty so I arrived at this little beauty. If you have real features you want to employ

	provider.NewAzurermProvider(stack, jsii.String("azurerm"), &provider.AzurermProviderConfig{
		SubscriptionId: jsii.String("<Your subscription Id>"),
		Features: []provider.AzurermProviderFeatures{ provider.AzurermProviderFeatures{}}},
	)

cmcniel avatar Jun 19 '25 15:06 cmcniel