azurerm: AzurermProviderFeatures Value is not an array
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
- Upgrade github.com/cdktf/cdktf-provider-azurerm-go/azurerm/v12/provider to github.com/cdktf/cdktf-provider-azurerm-go/azurerm/v13/provider
- Run
cdktf deployto see panic - Update
Featuresfrom&provider.AzurermProviderFeatures{}to[]*provider.AzurermProviderFeatures{} - Run
cdktf deployto see error offeaturesargument 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
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.
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.
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.
╵
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:
-
cdktf synth --output test -
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"
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.
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{}}},
)