Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NEXT_CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
### Bug Fixes

* Expand the "workspace-level resource requires a workspace_id" error to list all sources checked (resource `provider_config`, provider `workspace_id`, the configured profile, and the `DATABRICKS_WORKSPACE_ID` environment variable) so users know where to set it ([#5763](https://github.com/databricks/terraform-provider-databricks/pull/5763)).
* Reject `workspace_id` values with a leading zero (e.g. `0470576644108500`) in `provider_config` so the literal value is no longer written to state where it would not match the canonical numeric workspace ID returned by the API ([#5764](https://github.com/databricks/terraform-provider-databricks/pull/5764)).

### Documentation

Expand Down
26 changes: 25 additions & 1 deletion common/unified_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"strconv"
"strings"

"github.com/databricks/databricks-sdk-go"
"github.com/databricks/databricks-sdk-go/client"
Expand All @@ -30,8 +31,31 @@ type ProviderConfig struct {
// workspaceIDValidateFunc is used to validate the workspace ID for the provider configuration.
// Accepts either a classic numeric workspace ID or a connection ID that the platform gateway
// can disambiguate via the X-Databricks-Workspace-Id header.
//
// All-digit values are treated as classic numeric workspace IDs and must be in
// canonical form: a leading zero (e.g. "0470576644108500") is rejected. Although
// strconv.ParseInt tolerates leading zeros and the resource would still be created
// in the correct workspace, the literal value is written verbatim to Terraform
// state, where it no longer matches the canonical numeric form returned by the API.
// That mismatch poisons every downstream string comparison (perpetual diffs,
// failed workspace_id reconciliation). Non-numeric connection IDs are left
// untouched so the platform gateway can disambiguate them server-side.
func workspaceIDValidateFunc() func(interface{}, string) ([]string, []error) {
return validation.StringIsNotEmpty
return func(i interface{}, k string) ([]string, []error) {
if warnings, errs := validation.StringIsNotEmpty(i, k); len(errs) > 0 {
return warnings, errs
}
v := i.(string)
// Only constrain all-digit values; connection IDs (containing non-digit
// characters) are passed through unchanged.
if isNumericWorkspaceID(v) && len(v) > 1 && v[0] == '0' {
return nil, []error{fmt.Errorf(
"expected %s to be a numeric workspace ID without a leading zero, got %q; "+
"use the canonical numeric form (e.g. %q)",
k, v, strings.TrimLeft(v, "0"))}
}
return nil, nil
}
}

// AddNamespaceInSchema adds the provider_config schema to the given schema map.
Expand Down
17 changes: 16 additions & 1 deletion common/unified_provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,30 @@ func TestWorkspaceIDValidateFunc(t *testing.T) {
expectError: false,
},
{
name: "value with leading zero now accepted",
name: "numeric value with leading zero rejected",
input: "0123",
expectError: true,
},
{
name: "numeric value with leading zero rejected - long form",
input: "0470576644108500",
expectError: true,
},
{
name: "single zero accepted",
input: "0",
expectError: false,
},
{
name: "valid arbitrary non-empty string",
input: "abc123",
expectError: false,
},
{
name: "connection ID with leading zero accepted",
input: "0abc-def-123",
expectError: false,
},
{
name: "invalid empty string",
input: "",
Expand Down
Loading