From 0580dc2856d2755c516666e6bf9a3ce2a31a36c5 Mon Sep 17 00:00:00 2001 From: Mar Cabrera Date: Fri, 12 Dec 2025 11:25:03 +0100 Subject: [PATCH 1/7] Add custom plan modifier for RequestOnlyRequiredOnCreate Attribute --- .../request_only_required_create.go | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 internal/common/customplanmodifier/request_only_required_create.go diff --git a/internal/common/customplanmodifier/request_only_required_create.go b/internal/common/customplanmodifier/request_only_required_create.go new file mode 100644 index 0000000000..1c1cfd9953 --- /dev/null +++ b/internal/common/customplanmodifier/request_only_required_create.go @@ -0,0 +1,118 @@ +package customplanmodifier + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" +) + +// RequestOnlyRequiredOnCreate returns a plan modifier that fails planning if the value is +// missing (null/unknown) during create (i.e., when state is null), but allows omission on read/import. +func RequestOnlyRequiredOnCreate() RequestOnlyRequiredOnCreateModifier { + return &requestOnlyRequiredOnCreateAttributePlanModifier{} +} + +// Single interface so the modifier can be applied to any attribute type. +type RequestOnlyRequiredOnCreateModifier interface { + planmodifier.String + planmodifier.Bool + planmodifier.Int64 + planmodifier.Float64 + planmodifier.Number + planmodifier.List + planmodifier.Map + planmodifier.Set + planmodifier.Object +} + +type requestOnlyRequiredOnCreateAttributePlanModifier struct{} + +func (m *requestOnlyRequiredOnCreateAttributePlanModifier) Description(ctx context.Context) string { + return m.MarkdownDescription(ctx) +} + +func (m *requestOnlyRequiredOnCreateAttributePlanModifier) MarkdownDescription(ctx context.Context) string { + return "Ensures that create operations fail when attempting to create a resource with a missing required attribute." +} + +func (m *requestOnlyRequiredOnCreateAttributePlanModifier) PlanModifyString(ctx context.Context, req planmodifier.StringRequest, resp *planmodifier.StringResponse) { + if isCreate(&req.State) && (req.PlanValue.IsNull() || req.PlanValue.IsUnknown()) { + resp.Diagnostics.AddError( + fmt.Sprintf("%s is required when creating this resource", req.Path), + fmt.Sprintf("Provide a value for %s during resource creation.", req.Path), + ) + } +} + +func (m *requestOnlyRequiredOnCreateAttributePlanModifier) PlanModifyBool(ctx context.Context, req planmodifier.BoolRequest, resp *planmodifier.BoolResponse) { + if isCreate(&req.State) && (req.PlanValue.IsNull() || req.PlanValue.IsUnknown()) { + resp.Diagnostics.AddError( + fmt.Sprintf("%s is required when creating this resource", req.Path), + fmt.Sprintf("Provide a value for %s during resource creation.", req.Path), + ) + } +} + +func (m *requestOnlyRequiredOnCreateAttributePlanModifier) PlanModifyInt64(ctx context.Context, req planmodifier.Int64Request, resp *planmodifier.Int64Response) { + if isCreate(&req.State) && (req.PlanValue.IsNull() || req.PlanValue.IsUnknown()) { + resp.Diagnostics.AddError( + fmt.Sprintf("%s is required when creating this resource", req.Path), + fmt.Sprintf("Provide a value for %s during resource creation.", req.Path), + ) + } +} + +func (m *requestOnlyRequiredOnCreateAttributePlanModifier) PlanModifyFloat64(ctx context.Context, req planmodifier.Float64Request, resp *planmodifier.Float64Response) { + if isCreate(&req.State) && (req.PlanValue.IsNull() || req.PlanValue.IsUnknown()) { + resp.Diagnostics.AddError( + fmt.Sprintf("%s is required when creating this resource", req.Path), + fmt.Sprintf("Provide a value for %s during resource creation.", req.Path), + ) + } +} + +func (m *requestOnlyRequiredOnCreateAttributePlanModifier) PlanModifyNumber(ctx context.Context, req planmodifier.NumberRequest, resp *planmodifier.NumberResponse) { + if isCreate(&req.State) && (req.PlanValue.IsNull() || req.PlanValue.IsUnknown()) { + resp.Diagnostics.AddError( + fmt.Sprintf("%s is required when creating this resource", req.Path), + fmt.Sprintf("Provide a value for %s during resource creation.", req.Path), + ) + } +} + +func (m *requestOnlyRequiredOnCreateAttributePlanModifier) PlanModifyList(ctx context.Context, req planmodifier.ListRequest, resp *planmodifier.ListResponse) { + if isCreate(&req.State) && (req.PlanValue.IsNull() || req.PlanValue.IsUnknown()) { + resp.Diagnostics.AddError( + fmt.Sprintf("%s is required when creating this resource", req.Path), + fmt.Sprintf("Provide a value for %s during resource creation.", req.Path), + ) + } +} + +func (m *requestOnlyRequiredOnCreateAttributePlanModifier) PlanModifyMap(ctx context.Context, req planmodifier.MapRequest, resp *planmodifier.MapResponse) { + if isCreate(&req.State) && (req.PlanValue.IsNull() || req.PlanValue.IsUnknown()) { + resp.Diagnostics.AddError( + fmt.Sprintf("%s is required when creating this resource", req.Path), + fmt.Sprintf("Provide a value for %s during resource creation.", req.Path), + ) + } +} + +func (m *requestOnlyRequiredOnCreateAttributePlanModifier) PlanModifySet(ctx context.Context, req planmodifier.SetRequest, resp *planmodifier.SetResponse) { + if isCreate(&req.State) && (req.PlanValue.IsNull() || req.PlanValue.IsUnknown()) { + resp.Diagnostics.AddError( + fmt.Sprintf("%s is required when creating this resource", req.Path), + fmt.Sprintf("Provide a value for %s during resource creation.", req.Path), + ) + } +} + +func (m *requestOnlyRequiredOnCreateAttributePlanModifier) PlanModifyObject(ctx context.Context, req planmodifier.ObjectRequest, resp *planmodifier.ObjectResponse) { + if isCreate(&req.State) && (req.PlanValue.IsNull() || req.PlanValue.IsUnknown()) { + resp.Diagnostics.AddError( + fmt.Sprintf("%s is required when creating this resource", req.Path), + fmt.Sprintf("Provide a value for %s during resource creation.", req.Path), + ) + } +} From 7e958de2e6b36aa3b8dbf463fff37290e3412e02 Mon Sep 17 00:00:00 2001 From: Mar Cabrera Date: Fri, 12 Dec 2025 12:41:35 +0100 Subject: [PATCH 2/7] refactor custom plan modifiers to get triggered when attribute of type requestonlyrequiredonCreate is detected --- .../orgserviceaccountapi/resource_schema.go | 2 +- .../resource_schema.go | 2 +- .../gofilegen/schema/schema_attribute.go | 27 +++++++++++-------- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/internal/serviceapi/orgserviceaccountapi/resource_schema.go b/internal/serviceapi/orgserviceaccountapi/resource_schema.go index fc28d52c11..c220542569 100755 --- a/internal/serviceapi/orgserviceaccountapi/resource_schema.go +++ b/internal/serviceapi/orgserviceaccountapi/resource_schema.go @@ -45,7 +45,7 @@ func ResourceSchema(ctx context.Context) schema.Schema { "secret_expires_after_hours": schema.Int64Attribute{ Optional: true, MarkdownDescription: "The expiration time of the new Service Account secret, provided in hours. The minimum and maximum allowed expiration times are subject to change and are controlled by the organization's settings.", - PlanModifiers: []planmodifier.Int64{customplanmodifier.CreateOnly()}, + PlanModifiers: []planmodifier.Int64{customplanmodifier.CreateOnly(), customplanmodifier.RequestOnlyRequiredOnCreate()}, }, "secrets": schema.SetNestedAttribute{ Computed: true, diff --git a/internal/serviceapi/orgserviceaccountsecretapi/resource_schema.go b/internal/serviceapi/orgserviceaccountsecretapi/resource_schema.go index 749fd399a4..7d0c843a85 100755 --- a/internal/serviceapi/orgserviceaccountsecretapi/resource_schema.go +++ b/internal/serviceapi/orgserviceaccountsecretapi/resource_schema.go @@ -52,7 +52,7 @@ func ResourceSchema(ctx context.Context) schema.Schema { "secret_expires_after_hours": schema.Int64Attribute{ Optional: true, MarkdownDescription: "The expiration time of the new Service Account secret, provided in hours. The minimum and maximum allowed expiration times are subject to change and are controlled by the organization's settings.", - PlanModifiers: []planmodifier.Int64{customplanmodifier.CreateOnly()}, + PlanModifiers: []planmodifier.Int64{customplanmodifier.CreateOnly(), customplanmodifier.RequestOnlyRequiredOnCreate()}, }, }, } diff --git a/tools/codegen/gofilegen/schema/schema_attribute.go b/tools/codegen/gofilegen/schema/schema_attribute.go index 43ca12d540..8ba7d3f7d3 100644 --- a/tools/codegen/gofilegen/schema/schema_attribute.go +++ b/tools/codegen/gofilegen/schema/schema_attribute.go @@ -167,7 +167,6 @@ func commonAttrStructure(attr *codespec.Attribute, attrDefType, planModifierType Imports: propsStmts.Imports, } } - func commonProperties(attr *codespec.Attribute, planModifierType string) []CodeStatement { var result []CodeStatement if attr.ComputedOptionalRequired == codespec.Required { @@ -199,21 +198,27 @@ func commonProperties(attr *codespec.Attribute, planModifierType string) []CodeS Imports: imports, }) } - if attr.CreateOnly { // As of now this is the only property which implies defining plan modifiers. - planModifierImports := []string{ - "github.com/mongodb/terraform-provider-mongodbatlas/internal/common/customplanmodifier", - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier", - } - code := fmt.Sprintf("PlanModifiers: []%s{customplanmodifier.CreateOnly()}", planModifierType) - // For bool attributes with create-only and default value, use CreateOnlyBoolWithDefault + var customPlanModifiers []string + if attr.CreateOnly { if attr.Bool != nil && attr.Bool.Default != nil { - code = fmt.Sprintf("PlanModifiers: []%s{customplanmodifier.CreateOnlyBoolWithDefault(%t)}", planModifierType, *attr.Bool.Default) + // For bool attributes with create-only and default value, use CreateOnlyBoolWithDefault + customPlanModifiers = append(customPlanModifiers, fmt.Sprintf("customplanmodifier.CreateOnlyBoolWithDefault(%t)", *attr.Bool.Default)) + } else { + customPlanModifiers = append(customPlanModifiers, "customplanmodifier.CreateOnly()") } + } + if attr.RequestOnlyRequiredOnCreate { + customPlanModifiers = append(customPlanModifiers, "customplanmodifier.RequestOnlyRequiredOnCreate()") + } + if len(customPlanModifiers) > 0 { result = append(result, CodeStatement{ - Code: code, - Imports: planModifierImports, + Code: fmt.Sprintf("PlanModifiers: []%s{%s}", planModifierType, strings.Join(customPlanModifiers, ", ")), + Imports: []string{ + "github.com/mongodb/terraform-provider-mongodbatlas/internal/common/customplanmodifier", + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier", + }, }) } return result From 9c0db5080d5b59e789873c9afbdf23305073121c Mon Sep 17 00:00:00 2001 From: Mar Cabrera Date: Fri, 12 Dec 2025 15:51:18 +0100 Subject: [PATCH 3/7] Follow-up from PR #3972: Rename transformation function to match attribute name --- tools/codegen/codespec/config.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/codegen/codespec/config.go b/tools/codegen/codespec/config.go index 1d103fa89b..a05a315617 100644 --- a/tools/codegen/codespec/config.go +++ b/tools/codegen/codespec/config.go @@ -88,7 +88,7 @@ var transformations = []AttributeTransformation{ aliasTransformation, overridesTransformation, createOnlyTransformation, - requiredOnCreateInputOnlyTransformation, + requestOnlyRequiredOnCreateTransformation, } var dataSourceTransformations = []AttributeTransformation{ @@ -223,7 +223,7 @@ func createOnlyTransformation(attr *Attribute, _ *attrPaths, _ config.SchemaOpti return nil } -func requiredOnCreateInputOnlyTransformation(attr *Attribute, _ *attrPaths, _ config.SchemaOptions) error { +func requestOnlyRequiredOnCreateTransformation(attr *Attribute, _ *attrPaths, _ config.SchemaOptions) error { if attr.ComputedOptionalRequired == Required && attr.ReqBodyUsage == OmitInUpdateBody && !attr.PresentInAnyResponse { attr.RequestOnlyRequiredOnCreate = true attr.ComputedOptionalRequired = Optional From 7b9d1dbee580c36beb026ffba23a5b1996ea0cf3 Mon Sep 17 00:00:00 2001 From: Mar Cabrera Date: Fri, 12 Dec 2025 16:17:16 +0100 Subject: [PATCH 4/7] Add unit test for custom plan modifier --- .../gofilegen/schema/schema_attribute_test.go | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/tools/codegen/gofilegen/schema/schema_attribute_test.go b/tools/codegen/gofilegen/schema/schema_attribute_test.go index 428ce28acc..9cd7055193 100644 --- a/tools/codegen/gofilegen/schema/schema_attribute_test.go +++ b/tools/codegen/gofilegen/schema/schema_attribute_test.go @@ -117,3 +117,48 @@ func TestGenerateSchemaAttributes_CreateOnly(t *testing.T) { }) } } + +func TestGenerateSchemaAttributes_RequestOnlyRequiredOnCreate(t *testing.T) { + + tests := map[string]struct { + attribute codespec.Attribute + hasPlanModifier bool + }{ + "No RequestOnlyRequiredOnCreate - no plan modifiers": { + attribute: codespec.Attribute{ + TFSchemaName: "test_string", + TFModelName: "TestString", + String: &codespec.StringAttribute{}, + ComputedOptionalRequired: codespec.Optional, + RequestOnlyRequiredOnCreate: false, + }, + hasPlanModifier: false, + }, + "RequestOnlyRequiredOnCreate - uses RequestOnlyRequiredOnCreate()": { + attribute: codespec.Attribute{ + TFSchemaName: "test_string", + TFModelName: "TestString", + String: &codespec.StringAttribute{}, + ComputedOptionalRequired: codespec.Optional, + RequestOnlyRequiredOnCreate: true, + }, + hasPlanModifier: true, + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + result := schema.GenerateSchemaAttributes([]codespec.Attribute{tc.attribute}) + code := result.Code + if !tc.hasPlanModifier { + assert.NotContains(t, code, "PlanModifiers:") + return + } + assert.Contains(t, code, "PlanModifiers:") + if tc.attribute.RequestOnlyRequiredOnCreate { + assert.Contains(t, code, "customplanmodifier.RequestOnlyRequiredOnCreate()") + } + }) + } + +} From 245911457150c353f233a766708f7c80668aaef9 Mon Sep 17 00:00:00 2001 From: Mar Cabrera Date: Fri, 12 Dec 2025 16:31:09 +0100 Subject: [PATCH 5/7] Refactor custom plan modifier function --- .../request_only_required_create.go | 122 ++++++++++-------- 1 file changed, 70 insertions(+), 52 deletions(-) diff --git a/internal/common/customplanmodifier/request_only_required_create.go b/internal/common/customplanmodifier/request_only_required_create.go index 1c1cfd9953..4c5f5492db 100644 --- a/internal/common/customplanmodifier/request_only_required_create.go +++ b/internal/common/customplanmodifier/request_only_required_create.go @@ -4,6 +4,9 @@ import ( "context" "fmt" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" ) @@ -37,82 +40,97 @@ func (m *requestOnlyRequiredOnCreateAttributePlanModifier) MarkdownDescription(c } func (m *requestOnlyRequiredOnCreateAttributePlanModifier) PlanModifyString(ctx context.Context, req planmodifier.StringRequest, resp *planmodifier.StringResponse) { - if isCreate(&req.State) && (req.PlanValue.IsNull() || req.PlanValue.IsUnknown()) { - resp.Diagnostics.AddError( - fmt.Sprintf("%s is required when creating this resource", req.Path), - fmt.Sprintf("Provide a value for %s during resource creation.", req.Path), - ) - } + validateRequestOnlyRequiredOnCreate( + isCreate(&req.State), + req.PlanValue, + req.Path, + &resp.Diagnostics, + ) } func (m *requestOnlyRequiredOnCreateAttributePlanModifier) PlanModifyBool(ctx context.Context, req planmodifier.BoolRequest, resp *planmodifier.BoolResponse) { - if isCreate(&req.State) && (req.PlanValue.IsNull() || req.PlanValue.IsUnknown()) { - resp.Diagnostics.AddError( - fmt.Sprintf("%s is required when creating this resource", req.Path), - fmt.Sprintf("Provide a value for %s during resource creation.", req.Path), - ) - } + validateRequestOnlyRequiredOnCreate( + isCreate(&req.State), + req.PlanValue, + req.Path, + &resp.Diagnostics, + ) } func (m *requestOnlyRequiredOnCreateAttributePlanModifier) PlanModifyInt64(ctx context.Context, req planmodifier.Int64Request, resp *planmodifier.Int64Response) { - if isCreate(&req.State) && (req.PlanValue.IsNull() || req.PlanValue.IsUnknown()) { - resp.Diagnostics.AddError( - fmt.Sprintf("%s is required when creating this resource", req.Path), - fmt.Sprintf("Provide a value for %s during resource creation.", req.Path), - ) - } + validateRequestOnlyRequiredOnCreate( + isCreate(&req.State), + req.PlanValue, + req.Path, + &resp.Diagnostics, + ) } func (m *requestOnlyRequiredOnCreateAttributePlanModifier) PlanModifyFloat64(ctx context.Context, req planmodifier.Float64Request, resp *planmodifier.Float64Response) { - if isCreate(&req.State) && (req.PlanValue.IsNull() || req.PlanValue.IsUnknown()) { - resp.Diagnostics.AddError( - fmt.Sprintf("%s is required when creating this resource", req.Path), - fmt.Sprintf("Provide a value for %s during resource creation.", req.Path), - ) - } + validateRequestOnlyRequiredOnCreate( + isCreate(&req.State), + req.PlanValue, + req.Path, + &resp.Diagnostics, + ) } func (m *requestOnlyRequiredOnCreateAttributePlanModifier) PlanModifyNumber(ctx context.Context, req planmodifier.NumberRequest, resp *planmodifier.NumberResponse) { - if isCreate(&req.State) && (req.PlanValue.IsNull() || req.PlanValue.IsUnknown()) { - resp.Diagnostics.AddError( - fmt.Sprintf("%s is required when creating this resource", req.Path), - fmt.Sprintf("Provide a value for %s during resource creation.", req.Path), - ) - } + validateRequestOnlyRequiredOnCreate( + isCreate(&req.State), + req.PlanValue, + req.Path, + &resp.Diagnostics, + ) } func (m *requestOnlyRequiredOnCreateAttributePlanModifier) PlanModifyList(ctx context.Context, req planmodifier.ListRequest, resp *planmodifier.ListResponse) { - if isCreate(&req.State) && (req.PlanValue.IsNull() || req.PlanValue.IsUnknown()) { - resp.Diagnostics.AddError( - fmt.Sprintf("%s is required when creating this resource", req.Path), - fmt.Sprintf("Provide a value for %s during resource creation.", req.Path), - ) - } + validateRequestOnlyRequiredOnCreate( + isCreate(&req.State), + req.PlanValue, + req.Path, + &resp.Diagnostics, + ) } func (m *requestOnlyRequiredOnCreateAttributePlanModifier) PlanModifyMap(ctx context.Context, req planmodifier.MapRequest, resp *planmodifier.MapResponse) { - if isCreate(&req.State) && (req.PlanValue.IsNull() || req.PlanValue.IsUnknown()) { - resp.Diagnostics.AddError( - fmt.Sprintf("%s is required when creating this resource", req.Path), - fmt.Sprintf("Provide a value for %s during resource creation.", req.Path), - ) - } + validateRequestOnlyRequiredOnCreate( + isCreate(&req.State), + req.PlanValue, + req.Path, + &resp.Diagnostics, + ) } func (m *requestOnlyRequiredOnCreateAttributePlanModifier) PlanModifySet(ctx context.Context, req planmodifier.SetRequest, resp *planmodifier.SetResponse) { - if isCreate(&req.State) && (req.PlanValue.IsNull() || req.PlanValue.IsUnknown()) { - resp.Diagnostics.AddError( - fmt.Sprintf("%s is required when creating this resource", req.Path), - fmt.Sprintf("Provide a value for %s during resource creation.", req.Path), - ) - } + validateRequestOnlyRequiredOnCreate( + isCreate(&req.State), + req.PlanValue, + req.Path, + &resp.Diagnostics, + ) } func (m *requestOnlyRequiredOnCreateAttributePlanModifier) PlanModifyObject(ctx context.Context, req planmodifier.ObjectRequest, resp *planmodifier.ObjectResponse) { - if isCreate(&req.State) && (req.PlanValue.IsNull() || req.PlanValue.IsUnknown()) { - resp.Diagnostics.AddError( - fmt.Sprintf("%s is required when creating this resource", req.Path), - fmt.Sprintf("Provide a value for %s during resource creation.", req.Path), + validateRequestOnlyRequiredOnCreate( + isCreate(&req.State), + req.PlanValue, + req.Path, + &resp.Diagnostics, + ) +} + +// validateRequestOnlyRequiredOnCreate checks that an attribute has a known, non-null +// value during create and adds an error if it does not. +func validateRequestOnlyRequiredOnCreate(isCreate bool, planValue attr.Value, attrPath path.Path, diagnostics *diag.Diagnostics) { + if !isCreate { + return + } + + if planValue.IsNull() || planValue.IsUnknown() { + diagnostics.AddError( + fmt.Sprintf("%s is required when creating this resource", attrPath), + fmt.Sprintf("Provide a value for %s during resource creation.", attrPath), ) } } From e09468c36fd14f4846c7858ab99b8c6b8228fbdc Mon Sep 17 00:00:00 2001 From: Mar Cabrera Date: Fri, 12 Dec 2025 16:31:24 +0100 Subject: [PATCH 6/7] Fix lint issues --- tools/codegen/gofilegen/schema/schema_attribute_test.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/tools/codegen/gofilegen/schema/schema_attribute_test.go b/tools/codegen/gofilegen/schema/schema_attribute_test.go index 9cd7055193..c4c27c56af 100644 --- a/tools/codegen/gofilegen/schema/schema_attribute_test.go +++ b/tools/codegen/gofilegen/schema/schema_attribute_test.go @@ -117,9 +117,7 @@ func TestGenerateSchemaAttributes_CreateOnly(t *testing.T) { }) } } - func TestGenerateSchemaAttributes_RequestOnlyRequiredOnCreate(t *testing.T) { - tests := map[string]struct { attribute codespec.Attribute hasPlanModifier bool @@ -160,5 +158,4 @@ func TestGenerateSchemaAttributes_RequestOnlyRequiredOnCreate(t *testing.T) { } }) } - } From 7b3a1751f3f745e73ca0fd04e1d5cbdafef6899a Mon Sep 17 00:00:00 2001 From: Mar Cabrera Date: Mon, 15 Dec 2025 18:10:52 +0100 Subject: [PATCH 7/7] Address PR comments --- .../common/customplanmodifier/request_only_required_create.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/common/customplanmodifier/request_only_required_create.go b/internal/common/customplanmodifier/request_only_required_create.go index 4c5f5492db..3c38c073ae 100644 --- a/internal/common/customplanmodifier/request_only_required_create.go +++ b/internal/common/customplanmodifier/request_only_required_create.go @@ -120,14 +120,14 @@ func (m *requestOnlyRequiredOnCreateAttributePlanModifier) PlanModifyObject(ctx ) } -// validateRequestOnlyRequiredOnCreate checks that an attribute has a known, non-null +// validateRequestOnlyRequiredOnCreate checks that an attribute has a non-null // value during create and adds an error if it does not. func validateRequestOnlyRequiredOnCreate(isCreate bool, planValue attr.Value, attrPath path.Path, diagnostics *diag.Diagnostics) { if !isCreate { return } - if planValue.IsNull() || planValue.IsUnknown() { + if planValue.IsNull() { diagnostics.AddError( fmt.Sprintf("%s is required when creating this resource", attrPath), fmt.Sprintf("Provide a value for %s during resource creation.", attrPath),