Skip to content

Commit aa06782

Browse files
EspenAlbertrpabasararidmagroupby
authored
feat: Adds skip_wait_on_update to mongodbatlas_search_deployment to support returning early after an update (#3237)
* init * refactor: Rename schema to skip_wait_on_update * lint fixes * doc: Updates description of skip_wait_on_update * chore: Add changelog entry for skip_wait_on_update enhancement * revert: `extraTargetStates ...string` approach * refactor: use the skipWaitOnUpdate directly to avoid the WaitSearchNodeStateTransition * test: Check skip_wait_on_update * Update resource_search_deployment.go * update changelog * doc: Adds import note * refactor: use OverridenFields * test: Use ProjectIDExecutionWithCluster * doc: Update attribute description * refactor: revert back migration test to use `MONGODB_ATLAS_PROJECT_EAR_PE_AWS_ID` --------- Co-authored-by: rpabasara <[email protected]> Co-authored-by: ridmagroupby <[email protected]>
1 parent e8d2ce4 commit aa06782

File tree

8 files changed

+52
-14
lines changed

8 files changed

+52
-14
lines changed

.changelog/3237.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
resource/mongodbatlas_search_deployment: Adds `skip_wait_on_update` to avoid waiting for completion of update operations
3+
```

docs/resources/search_deployment.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ output "mongodbatlas_search_deployment_encryption_at_rest_provider" {
6868

6969
### Optional
7070

71+
- `skip_wait_on_update` (Boolean) If true, the resource update is executed without waiting until the [state](#state_name-1) is `IDLE`, making the operation faster. This might cause update errors to go unnoticed and lead to non-empty plans at the next terraform execution.
7172
- `timeouts` (Attributes) (see [below for nested schema](#nestedatt--timeouts))
7273

7374
### Read-Only
@@ -101,4 +102,6 @@ Search node resource can be imported using the project ID and cluster name, in t
101102
$ terraform import mongodbatlas_search_deployment.test 650972848269185c55f40ca1-Cluster0
102103
```
103104

105+
After an import, a non-empty plan is expected if the configuration defines the `skip_wait_on_update` attribute. However, the update will not have any effect on the search deployment since `skip_wait_on_update` only relates to the update operations wait time.
106+
104107
For more information see: [MongoDB Atlas API - Search Node](https://www.mongodb.com/docs/atlas/reference/api-resources-spec/#tag/Atlas-Search/operation/createAtlasSearchDeployment) Documentation.

internal/service/searchdeployment/data_source.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66

77
"github.com/hashicorp/terraform-plugin-framework/datasource"
8+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
89
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion"
910
"github.com/mongodb/terraform-provider-mongodbatlas/internal/config"
1011
)
@@ -27,6 +28,9 @@ type searchDeploymentDS struct {
2728
func (d *searchDeploymentDS) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
2829
resp.Schema = conversion.DataSourceSchemaFromResource(ResourceSchema(ctx), &conversion.DataSourceSchemaRequest{
2930
RequiredFields: []string{"project_id", "cluster_name"},
31+
OverridenFields: map[string]schema.Attribute{
32+
"skip_wait_on_update": nil,
33+
},
3034
})
3135
}
3236

internal/service/searchdeployment/resource.go

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ func (r *searchDeploymentRS) Create(ctx context.Context, req resource.CreateRequ
8282
if resp.Diagnostics.HasError() {
8383
return
8484
}
85+
newSearchNodeModel.SkipWaitOnUpdate = searchDeploymentPlan.SkipWaitOnUpdate
8586
resp.Diagnostics.Append(resp.State.Set(ctx, newSearchNodeModel)...)
8687
}
8788

@@ -115,6 +116,7 @@ func (r *searchDeploymentRS) Read(ctx context.Context, req resource.ReadRequest,
115116
if resp.Diagnostics.HasError() {
116117
return
117118
}
119+
newSearchNodeModel.SkipWaitOnUpdate = searchDeploymentPlan.SkipWaitOnUpdate
118120
resp.Diagnostics.Append(resp.State.Set(ctx, newSearchNodeModel)...)
119121
}
120122

@@ -129,7 +131,8 @@ func (r *searchDeploymentRS) Update(ctx context.Context, req resource.UpdateRequ
129131
projectID := searchDeploymentPlan.ProjectID.ValueString()
130132
clusterName := searchDeploymentPlan.ClusterName.ValueString()
131133
searchDeploymentReq := NewSearchDeploymentReq(ctx, &searchDeploymentPlan)
132-
if _, _, err := connV2.AtlasSearchApi.UpdateAtlasSearchDeployment(ctx, projectID, clusterName, &searchDeploymentReq).Execute(); err != nil {
134+
deploymentResp, _, err := connV2.AtlasSearchApi.UpdateAtlasSearchDeployment(ctx, projectID, clusterName, &searchDeploymentReq).Execute()
135+
if err != nil {
133136
resp.Diagnostics.AddError("error during search deployment update", err.Error())
134137
return
135138
}
@@ -139,17 +142,21 @@ func (r *searchDeploymentRS) Update(ctx context.Context, req resource.UpdateRequ
139142
if resp.Diagnostics.HasError() {
140143
return
141144
}
142-
deploymentResp, err := WaitSearchNodeStateTransition(ctx, projectID, clusterName, connV2.AtlasSearchApi,
143-
retryTimeConfig(updateTimeout, minTimeoutCreateUpdate))
144-
if err != nil {
145-
resp.Diagnostics.AddError("error during search deployment update", err.Error())
146-
return
145+
if !searchDeploymentPlan.SkipWaitOnUpdate.ValueBool() {
146+
deploymentResp, err = WaitSearchNodeStateTransition(ctx, projectID, clusterName, connV2.AtlasSearchApi,
147+
retryTimeConfig(updateTimeout, minTimeoutCreateUpdate))
148+
if err != nil {
149+
resp.Diagnostics.AddError("error during search deployment update", err.Error())
150+
return
151+
}
147152
}
153+
148154
newSearchNodeModel, diagnostics := NewTFSearchDeployment(ctx, clusterName, deploymentResp, &searchDeploymentPlan.Timeouts, false)
149155
resp.Diagnostics.Append(diagnostics...)
150156
if resp.Diagnostics.HasError() {
151157
return
152158
}
159+
newSearchNodeModel.SkipWaitOnUpdate = searchDeploymentPlan.SkipWaitOnUpdate
153160
resp.Diagnostics.Append(resp.State.Set(ctx, newSearchNodeModel)...)
154161
}
155162

internal/service/searchdeployment/resource_migration_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ func TestMigSearchDeployment_basic(t *testing.T) {
1616
clusterName = acc.RandomClusterName()
1717
instanceSize = "S30_HIGHCPU_NVME"
1818
searchNodeCount = 3
19-
config = configBasic(projectID, clusterName, instanceSize, searchNodeCount)
19+
config = configBasic(projectID, clusterName, instanceSize, searchNodeCount, false)
2020
)
2121
mig.SkipIfVersionBelow(t, "1.32.0") // enabled_for_search_nodes introduced in this version
2222
resource.ParallelTest(t, resource.TestCase{

internal/service/searchdeployment/resource_schema.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ func ResourceSchema(ctx context.Context) schema.Schema {
6363
Update: true,
6464
Delete: true,
6565
}),
66+
"skip_wait_on_update": schema.BoolAttribute{
67+
Description: "If true, the resource update is executed without waiting until the [state](#state_name-1) is `IDLE`, making the operation faster. This might cause update errors to go unnoticed and lead to non-empty plans at the next terraform execution.",
68+
Optional: true,
69+
},
6670
"encryption_at_rest_provider": schema.StringAttribute{
6771
Computed: true,
6872
MarkdownDescription: "Cloud service provider that manages your customer keys to provide an additional layer of Encryption At Rest for the cluster.",
@@ -78,6 +82,7 @@ type TFSearchDeploymentRSModel struct {
7882
Specs types.List `tfsdk:"specs"`
7983
StateName types.String `tfsdk:"state_name"`
8084
Timeouts timeouts.Value `tfsdk:"timeouts"`
85+
SkipWaitOnUpdate types.Bool `tfsdk:"skip_wait_on_update"`
8186
EncryptionAtRestProvider types.String `tfsdk:"encryption_at_rest_provider"`
8287
}
8388

internal/service/searchdeployment/resource_test.go

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,26 @@ const (
1818

1919
func TestAccSearchDeployment_basic(t *testing.T) {
2020
var (
21-
projectID = acc.ProjectIDExecution(t)
22-
clusterName = acc.RandomClusterName()
21+
projectID, clusterName = acc.ProjectIDExecutionWithCluster(t, 6)
22+
updateStep = newSearchNodeTestStep(resourceID, projectID, clusterName, "S30_HIGHCPU_NVME", 4)
23+
updateStepNoWait = configBasic(projectID, clusterName, "S30_HIGHCPU_NVME", 4, true)
2324
)
2425
resource.ParallelTest(t, resource.TestCase{
2526
PreCheck: func() { acc.PreCheckBasic(t) },
2627
ProtoV6ProviderFactories: acc.TestAccProviderV6Factories,
2728
CheckDestroy: checkDestroy,
2829
Steps: []resource.TestStep{
2930
newSearchNodeTestStep(resourceID, projectID, clusterName, "S20_HIGHCPU_NVME", 3),
30-
newSearchNodeTestStep(resourceID, projectID, clusterName, "S30_HIGHCPU_NVME", 4),
31+
// Do a no-wait update then expect next step to wait for the update to complete
32+
// We cannot check the state_name as the response of a PATCH can be IDLE
3133
{
34+
Config: updateStepNoWait,
35+
Check: updateStep.Check,
36+
},
37+
// Changes: skip_wait_on_update true -> null
38+
updateStep,
39+
{
40+
Config: updateStep.Config,
3241
ResourceName: resourceID,
3342
ImportStateIdFunc: importStateIDFunc(resourceID),
3443
ImportState: true,
@@ -72,7 +81,7 @@ func newSearchNodeTestStep(resourceName, projectID, clusterName, instanceSize st
7281
resourceChecks := searchNodeChecks(resourceName, clusterName, instanceSize, searchNodeCount)
7382
dataSourceChecks := searchNodeChecks(dataSourceID, clusterName, instanceSize, searchNodeCount)
7483
return resource.TestStep{
75-
Config: configBasic(projectID, clusterName, instanceSize, searchNodeCount),
84+
Config: configBasic(projectID, clusterName, instanceSize, searchNodeCount, false),
7685
Check: resource.ComposeAggregateTestCheckFunc(append(resourceChecks, dataSourceChecks...)...),
7786
}
7887
}
@@ -90,27 +99,32 @@ func searchNodeChecks(targetName, clusterName, instanceSize string, searchNodeCo
9099
}
91100
}
92101

93-
func configBasic(projectID, clusterName, instanceSize string, searchNodeCount int) string {
102+
func configBasic(projectID, clusterName, instanceSize string, searchNodeCount int, skipWaitOnUpdate bool) string {
94103
clusterConfig := acc.ConfigBasicDedicated(projectID, clusterName, "")
104+
var skipWaitOnUpdateStr string
105+
if skipWaitOnUpdate {
106+
skipWaitOnUpdateStr = fmt.Sprintf("skip_wait_on_update = %t", skipWaitOnUpdate)
107+
}
95108
return fmt.Sprintf(`
96109
%[1]s
97110
98111
resource "mongodbatlas_search_deployment" "test" {
99112
project_id = %[2]q
100-
cluster_name = mongodbatlas_advanced_cluster.test.name
113+
cluster_name = mongodbatlas_advanced_cluster.test.name # ensure dependency on cluster
101114
specs = [
102115
{
103116
instance_size = %[3]q
104117
node_count = %[4]d
105118
}
106119
]
120+
%[5]s
107121
}
108122
109123
data "mongodbatlas_search_deployment" "test" {
110124
project_id = mongodbatlas_search_deployment.test.project_id
111125
cluster_name = mongodbatlas_search_deployment.test.cluster_name
112126
}
113-
`, clusterConfig, projectID, instanceSize, searchNodeCount)
127+
`, clusterConfig, projectID, instanceSize, searchNodeCount, skipWaitOnUpdateStr)
114128
}
115129

116130
func configSearchDeployment(projectID, clusterNameRef, instanceSize string, searchNodeCount int) string {

templates/resources/search_deployment.md.tmpl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,6 @@ Search node resource can be imported using the project ID and cluster name, in t
1919
$ terraform import mongodbatlas_search_deployment.test 650972848269185c55f40ca1-Cluster0
2020
```
2121

22+
After an import, a non-empty plan is expected if the configuration defines the `skip_wait_on_update` attribute. However, the update will not have any effect on the search deployment since `skip_wait_on_update` only relates to the update operations wait time.
23+
2224
For more information see: [MongoDB Atlas API - Search Node](https://www.mongodb.com/docs/atlas/reference/api-resources-spec/#tag/Atlas-Search/operation/createAtlasSearchDeployment) Documentation.

0 commit comments

Comments
 (0)