What happened?
In a muxed SDKv2 + Plugin Framework provider, the MaxItemsOne decision for provider config fields is computed twice from two different schemas, and the two disagree.
MuxShimWithDisjointgPF builds a merged ProviderShim whose Schema() is the SDKv2 provider config schema (newProviderShim copies provider.Schema() from the first provider; extend merges resources, data sources and functions but not the provider schema). tfgen therefore flattens MaxItems: 1 config blocks and emits singular property names.
At runtime, MakeMuxedServer hands the PF sub-server an info.P of muxedPFSchemaProvider, which overrides ResourcesMap() and ListResourcesMap() to return the merged schema but leaves Schema() resolving to the embedded PF ShimProvider (pkg/pf/tfbridge/main.go:225). So NewConfigEncoder derives the provider-config encoder, and its property names, from the PF schema. PF blocks carry no MaxItems; the bridge recovers it only by regex-matching validator description strings (pfutils/block.go detectSizeConstraints), so a ListNestedBlock with no size validator reads as MaxItems() == 0 even when the SDKv2 twin declares MaxItems: 1.
Two symptoms follow, selected by whether pluralization changes the field's name:
Example
hashicorp/terraform-provider-google-beta declares batching and external_credentials identically: SDKv2 TypeList + MaxItems: 1, PF ListNestedBlock with no size validator. Running tfbridge.TerraformToPulumiNameV2 over the two schema views:
MaxItems=1 (SDKv2 view, used by tfgen): batching -> batching external_credentials -> externalCredentials
MaxItems=0 (PF view, used at runtime): batching -> batchings external_credentials -> externalCredentials
Against gcp 9.33.0, gcp:externalCredentials in object form fails with the error above, and gcp:batching is accepted in both object and array form — it is never encoded, so the value is dropped on the PF half of the mux.
Suggested fix
Give muxedPFSchemaProvider a Schema() that returns schemaProvider.Schema(), mirroring what is already done for ResourcesMap(), so the PF sub-server's provider-config encoder uses the same schema tfgen used. Worth checking whether any other name or shape convention on the PF sub-server is being derived from the PF-only view.
Related
pulumi/pulumi-gcp#3869, pulumi/pulumi-vault#1087. Distinct from #3557 and #3558, which are about the flattened encoding itself being lossy rather than two layers disagreeing about which fields are flattened.
What happened?
In a muxed SDKv2 + Plugin Framework provider, the MaxItemsOne decision for provider config fields is computed twice from two different schemas, and the two disagree.
MuxShimWithDisjointgPFbuilds a mergedProviderShimwhoseSchema()is the SDKv2 provider config schema (newProviderShimcopiesprovider.Schema()from the first provider;extendmerges resources, data sources and functions but not the provider schema). tfgen therefore flattensMaxItems: 1config blocks and emits singular property names.At runtime,
MakeMuxedServerhands the PF sub-server aninfo.PofmuxedPFSchemaProvider, which overridesResourcesMap()andListResourcesMap()to return the merged schema but leavesSchema()resolving to the embedded PFShimProvider(pkg/pf/tfbridge/main.go:225). SoNewConfigEncoderderives the provider-config encoder, and its property names, from the PF schema. PF blocks carry noMaxItems; the bridge recovers it only by regex-matching validator description strings (pfutils/block.godetectSizeConstraints), so aListNestedBlockwith no size validator reads asMaxItems() == 0even when the SDKv2 twin declaresMaxItems: 1.Two symptoms follow, selected by whether pluralization changes the field's name:
cannot encode provider configuration to call ValidateProviderConfig: objectEncoder failed on property "external_credentials": Expected an Array PropertyValue. Reported as Provider external_credentials fails at ValidateProviderConfig: objectEncoder "Expected an Array PropertyValue" (typed SDK shape); raw array shape works pulumi-gcp#3869 and Regression in 7.11.0: auth_login_aws object shape rejected by provider config encoder pulumi-vault#1087.Example
hashicorp/terraform-provider-google-betadeclaresbatchingandexternal_credentialsidentically: SDKv2TypeList+MaxItems: 1, PFListNestedBlockwith no size validator. Runningtfbridge.TerraformToPulumiNameV2over the two schema views:Against gcp 9.33.0,
gcp:externalCredentialsin object form fails with the error above, andgcp:batchingis accepted in both object and array form — it is never encoded, so the value is dropped on the PF half of the mux.Suggested fix
Give
muxedPFSchemaProvideraSchema()that returnsschemaProvider.Schema(), mirroring what is already done forResourcesMap(), so the PF sub-server's provider-config encoder uses the same schema tfgen used. Worth checking whether any other name or shape convention on the PF sub-server is being derived from the PF-only view.Related
pulumi/pulumi-gcp#3869, pulumi/pulumi-vault#1087. Distinct from #3557 and #3558, which are about the flattened encoding itself being lossy rather than two layers disagreeing about which fields are flattened.