Skip to content

Commit 7b73d34

Browse files
authored
INTMDB-503: Configurable cluster timeouts (#951)
* Made timeouts configurable for cluster & advanced_cluster, default is 3 hours * Addressed a lint issue * Added documentation on timeouts arguments to cluster
1 parent 3f5e26d commit 7b73d34

File tree

4 files changed

+47
-22
lines changed

4 files changed

+47
-22
lines changed

mongodbatlas/resource_mongodbatlas_advanced_cluster.go

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,11 @@ func resourceMongoDBAtlasAdvancedCluster() *schema.Resource {
265265
},
266266
"advanced_configuration": clusterAdvancedConfigurationSchema(),
267267
},
268+
Timeouts: &schema.ResourceTimeout{
269+
Create: schema.DefaultTimeout(3 * time.Hour),
270+
Update: schema.DefaultTimeout(3 * time.Hour),
271+
Delete: schema.DefaultTimeout(3 * time.Hour),
272+
},
268273
}
269274
}
270275

@@ -359,11 +364,12 @@ func resourceMongoDBAtlasAdvancedClusterCreate(ctx context.Context, d *schema.Re
359364
return diag.FromErr(fmt.Errorf(errorClusterAdvancedCreate, err))
360365
}
361366

367+
timeout := d.Timeout(schema.TimeoutCreate)
362368
stateConf := &resource.StateChangeConf{
363369
Pending: []string{"CREATING", "UPDATING", "REPAIRING", "REPEATING", "PENDING"},
364370
Target: []string{"IDLE"},
365371
Refresh: resourceClusterAdvancedRefreshFunc(ctx, d.Get("name").(string), projectID, conn),
366-
Timeout: 3 * time.Hour,
372+
Timeout: timeout,
367373
MinTimeout: 1 * time.Minute,
368374
Delay: 3 * time.Minute,
369375
}
@@ -396,7 +402,7 @@ func resourceMongoDBAtlasAdvancedClusterCreate(ctx context.Context, d *schema.Re
396402
Paused: pointy.Bool(v),
397403
}
398404

399-
_, _, err = updateAdvancedCluster(ctx, conn, request, projectID, d.Get("name").(string))
405+
_, _, err = updateAdvancedCluster(ctx, conn, request, projectID, d.Get("name").(string), timeout)
400406
if err != nil {
401407
return diag.FromErr(fmt.Errorf(errorClusterAdvancedUpdate, d.Get("name").(string), err))
402408
}
@@ -547,7 +553,7 @@ func resourceMongoDBAtlasAdvancedClusterUpgrade(ctx context.Context, d *schema.R
547553
return diag.FromErr(fmt.Errorf("upgrade called without %s in ctx", string(upgradeRequestCtxKey)))
548554
}
549555

550-
upgradeResponse, _, err := upgradeCluster(ctx, conn, upgradeRequest, projectID, clusterName)
556+
upgradeResponse, _, err := upgradeCluster(ctx, conn, upgradeRequest, projectID, clusterName, d.Timeout(schema.TimeoutUpdate))
551557

552558
if err != nil {
553559
return diag.FromErr(fmt.Errorf(errorClusterAdvancedUpdate, clusterName, err))
@@ -623,17 +629,19 @@ func resourceMongoDBAtlasAdvancedClusterUpdate(ctx context.Context, d *schema.Re
623629
cluster.VersionReleaseSystem = d.Get("version_release_system").(string)
624630
}
625631

632+
timeout := d.Timeout(schema.TimeoutUpdate)
633+
626634
// Has changes
627635
if !reflect.DeepEqual(cluster, matlas.Cluster{}) {
628-
err := resource.RetryContext(ctx, 3*time.Hour, func() *resource.RetryError {
629-
_, _, err := updateAdvancedCluster(ctx, conn, cluster, projectID, clusterName)
636+
err := resource.RetryContext(ctx, timeout, func() *resource.RetryError {
637+
_, _, err := updateAdvancedCluster(ctx, conn, cluster, projectID, clusterName, timeout)
630638
if err != nil {
631639
var target *matlas.ErrorResponse
632640
if errors.As(err, &target) && target.ErrorCode == "CANNOT_UPDATE_PAUSED_CLUSTER" {
633641
clusterRequest := &matlas.AdvancedCluster{
634642
Paused: pointy.Bool(false),
635643
}
636-
_, _, err := updateAdvancedCluster(ctx, conn, clusterRequest, projectID, clusterName)
644+
_, _, err := updateAdvancedCluster(ctx, conn, clusterRequest, projectID, clusterName, timeout)
637645
if err != nil {
638646
return resource.NonRetryableError(fmt.Errorf(errorClusterAdvancedUpdate, clusterName, err))
639647
}
@@ -670,7 +678,7 @@ func resourceMongoDBAtlasAdvancedClusterUpdate(ctx context.Context, d *schema.Re
670678
Paused: pointy.Bool(true),
671679
}
672680

673-
_, _, err := updateAdvancedCluster(ctx, conn, clusterRequest, projectID, clusterName)
681+
_, _, err := updateAdvancedCluster(ctx, conn, clusterRequest, projectID, clusterName, timeout)
674682
if err != nil {
675683
return diag.FromErr(fmt.Errorf(errorClusterAdvancedUpdate, clusterName, err))
676684
}
@@ -698,7 +706,7 @@ func resourceMongoDBAtlasAdvancedClusterDelete(ctx context.Context, d *schema.Re
698706
Pending: []string{"IDLE", "CREATING", "UPDATING", "REPAIRING", "DELETING"},
699707
Target: []string{"DELETED"},
700708
Refresh: resourceClusterAdvancedRefreshFunc(ctx, clusterName, projectID, conn),
701-
Timeout: 3 * time.Hour,
709+
Timeout: d.Timeout(schema.TimeoutDelete),
702710
MinTimeout: 30 * time.Second,
703711
Delay: 1 * time.Minute, // Wait 30 secs before starting
704712
}
@@ -1198,7 +1206,13 @@ func getUpgradeRequest(d *schema.ResourceData) *matlas.Cluster {
11981206
}
11991207
}
12001208

1201-
func updateAdvancedCluster(ctx context.Context, conn *matlas.Client, request *matlas.AdvancedCluster, projectID, name string) (*matlas.AdvancedCluster, *matlas.Response, error) {
1209+
func updateAdvancedCluster(
1210+
ctx context.Context,
1211+
conn *matlas.Client,
1212+
request *matlas.AdvancedCluster,
1213+
projectID, name string,
1214+
timeout time.Duration,
1215+
) (*matlas.AdvancedCluster, *matlas.Response, error) {
12021216
cluster, resp, err := conn.AdvancedClusters.Update(ctx, projectID, name, request)
12031217
if err != nil {
12041218
return nil, nil, err
@@ -1208,7 +1222,7 @@ func updateAdvancedCluster(ctx context.Context, conn *matlas.Client, request *ma
12081222
Pending: []string{"CREATING", "UPDATING", "REPAIRING"},
12091223
Target: []string{"IDLE"},
12101224
Refresh: resourceClusterAdvancedRefreshFunc(ctx, name, projectID, conn),
1211-
Timeout: 3 * time.Hour,
1225+
Timeout: timeout,
12121226
MinTimeout: 30 * time.Second,
12131227
Delay: 1 * time.Minute,
12141228
}

mongodbatlas/resource_mongodbatlas_cluster.go

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,11 @@ func resourceMongoDBAtlasCluster() *schema.Resource {
359359
},
360360
},
361361
CustomizeDiff: resourceClusterCustomizeDiff,
362+
Timeouts: &schema.ResourceTimeout{
363+
Create: schema.DefaultTimeout(3 * time.Hour),
364+
Update: schema.DefaultTimeout(3 * time.Hour),
365+
Delete: schema.DefaultTimeout(3 * time.Hour),
366+
},
362367
}
363368
}
364369

@@ -547,11 +552,12 @@ func resourceMongoDBAtlasClusterCreate(ctx context.Context, d *schema.ResourceDa
547552
return diag.FromErr(fmt.Errorf(errorClusterCreate, err))
548553
}
549554

555+
timeout := d.Timeout(schema.TimeoutCreate)
550556
stateConf := &resource.StateChangeConf{
551557
Pending: []string{"CREATING", "UPDATING", "REPAIRING", "REPEATING", "PENDING"},
552558
Target: []string{"IDLE"},
553559
Refresh: resourceClusterRefreshFunc(ctx, d.Get("name").(string), projectID, conn),
554-
Timeout: 3 * time.Hour,
560+
Timeout: timeout,
555561
MinTimeout: 1 * time.Minute,
556562
Delay: 3 * time.Minute,
557563
}
@@ -584,7 +590,7 @@ func resourceMongoDBAtlasClusterCreate(ctx context.Context, d *schema.ResourceDa
584590
Paused: pointy.Bool(v),
585591
}
586592

587-
_, _, err = updateCluster(ctx, conn, clusterRequest, projectID, d.Get("name").(string))
593+
_, _, err = updateCluster(ctx, conn, clusterRequest, projectID, d.Get("name").(string), timeout)
588594
if err != nil {
589595
return diag.FromErr(fmt.Errorf(errorClusterUpdate, d.Get("name").(string), err))
590596
}
@@ -918,8 +924,10 @@ func resourceMongoDBAtlasClusterUpdate(ctx context.Context, d *schema.ResourceDa
918924
}
919925
}
920926

927+
timeout := d.Timeout(schema.TimeoutUpdate)
928+
921929
if isUpgradeRequired(d) {
922-
updatedCluster, _, err := upgradeCluster(ctx, conn, cluster, projectID, clusterName)
930+
updatedCluster, _, err := upgradeCluster(ctx, conn, cluster, projectID, clusterName, timeout)
923931

924932
if err != nil {
925933
return diag.FromErr(fmt.Errorf(errorClusterUpdate, clusterName, err))
@@ -932,15 +940,15 @@ func resourceMongoDBAtlasClusterUpdate(ctx context.Context, d *schema.ResourceDa
932940
"provider_name": updatedCluster.ProviderSettings.ProviderName,
933941
}))
934942
} else if !reflect.DeepEqual(cluster, matlas.Cluster{}) {
935-
err := resource.RetryContext(ctx, 3*time.Hour, func() *resource.RetryError {
936-
_, _, err := updateCluster(ctx, conn, cluster, projectID, clusterName)
943+
err := resource.RetryContext(ctx, timeout, func() *resource.RetryError {
944+
_, _, err := updateCluster(ctx, conn, cluster, projectID, clusterName, timeout)
937945

938946
if didErrOnPausedCluster(err) {
939947
clusterRequest := &matlas.Cluster{
940948
Paused: pointy.Bool(false),
941949
}
942950

943-
_, _, err = updateCluster(ctx, conn, clusterRequest, projectID, clusterName)
951+
_, _, err = updateCluster(ctx, conn, clusterRequest, projectID, clusterName, timeout)
944952
}
945953

946954
if err != nil {
@@ -976,7 +984,7 @@ func resourceMongoDBAtlasClusterUpdate(ctx context.Context, d *schema.ResourceDa
976984
Paused: pointy.Bool(true),
977985
}
978986

979-
_, _, err := updateCluster(ctx, conn, clusterRequest, projectID, clusterName)
987+
_, _, err := updateCluster(ctx, conn, clusterRequest, projectID, clusterName, timeout)
980988
if err != nil {
981989
return diag.FromErr(fmt.Errorf(errorClusterUpdate, clusterName, err))
982990
}
@@ -1014,7 +1022,7 @@ func resourceMongoDBAtlasClusterDelete(ctx context.Context, d *schema.ResourceDa
10141022
Pending: []string{"IDLE", "CREATING", "UPDATING", "REPAIRING", "DELETING"},
10151023
Target: []string{"DELETED"},
10161024
Refresh: resourceClusterRefreshFunc(ctx, clusterName, projectID, conn),
1017-
Timeout: 3 * time.Hour,
1025+
Timeout: d.Timeout(schema.TimeoutDelete),
10181026
MinTimeout: 30 * time.Second,
10191027
Delay: 1 * time.Minute, // Wait 30 secs before starting
10201028
}
@@ -1716,7 +1724,7 @@ func clusterAdvancedConfigurationSchema() *schema.Schema {
17161724
}
17171725
}
17181726

1719-
func updateCluster(ctx context.Context, conn *matlas.Client, request *matlas.Cluster, projectID, name string) (*matlas.Cluster, *matlas.Response, error) {
1727+
func updateCluster(ctx context.Context, conn *matlas.Client, request *matlas.Cluster, projectID, name string, timeout time.Duration) (*matlas.Cluster, *matlas.Response, error) {
17201728
cluster, resp, err := conn.Clusters.Update(ctx, projectID, name, request)
17211729
if err != nil {
17221730
return nil, nil, err
@@ -1726,7 +1734,7 @@ func updateCluster(ctx context.Context, conn *matlas.Client, request *matlas.Clu
17261734
Pending: []string{"CREATING", "UPDATING", "REPAIRING"},
17271735
Target: []string{"IDLE"},
17281736
Refresh: resourceClusterRefreshFunc(ctx, name, projectID, conn),
1729-
Timeout: 3 * time.Hour,
1737+
Timeout: timeout,
17301738
MinTimeout: 30 * time.Second,
17311739
Delay: 1 * time.Minute,
17321740
}
@@ -1740,7 +1748,7 @@ func updateCluster(ctx context.Context, conn *matlas.Client, request *matlas.Clu
17401748
return cluster, resp, nil
17411749
}
17421750

1743-
func upgradeCluster(ctx context.Context, conn *matlas.Client, request *matlas.Cluster, projectID, name string) (*matlas.Cluster, *matlas.Response, error) {
1751+
func upgradeCluster(ctx context.Context, conn *matlas.Client, request *matlas.Cluster, projectID, name string, timeout time.Duration) (*matlas.Cluster, *matlas.Response, error) {
17441752
request.Name = name
17451753

17461754
cluster, resp, err := conn.Clusters.Upgrade(ctx, projectID, request)
@@ -1752,7 +1760,7 @@ func upgradeCluster(ctx context.Context, conn *matlas.Client, request *matlas.Cl
17521760
Pending: []string{"CREATING", "UPDATING", "REPAIRING"},
17531761
Target: []string{"IDLE"},
17541762
Refresh: resourceClusterRefreshFunc(ctx, name, projectID, conn),
1755-
Timeout: 3 * time.Hour,
1763+
Timeout: timeout,
17561764
MinTimeout: 30 * time.Second,
17571765
Delay: 1 * time.Minute,
17581766
}

website/docs/r/advanced_cluster.html.markdown

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ This parameter defaults to false.
217217
`lifecycle {
218218
ignore_changes = [paused]
219219
}`
220+
* `timeouts`- (Optional) The duration of time to wait for Cluster to be created, updated, or deleted. The timeout value is defined by a signed sequence of decimal numbers with an time unit suffix such as: `1h45m`, `300s`, `10m`, .... The valid time units are: `ns`, `us` (or `µs`), `ms`, `s`, `m`, `h`. The default timeout for Private Endpoint create & delete is `3h`. Learn more about timeouts [here](https://www.terraform.io/plugin/sdkv2/resources/retries-and-customizable-timeouts).
220221

221222

222223
### bi_connector
@@ -411,6 +412,7 @@ In addition to all arguments above, the following attributes are exported:
411412
- REPAIRING
412413
* `replication_specs` - Set of replication specifications for the cluster. Primary usage is covered under the [replication_specs argument reference](#replication_specs), though there are some computed attributes:
413414
- `replication_specs.#.container_id` - A key-value map of the Network Peering Container ID(s) for the configuration specified in `region_configs`. The Container ID is the id of the container created when the first cluster in the region (AWS/Azure) or project (GCP) was created. The syntax is `"providerName:regionName" = "containerId"`. Example `AWS:US_EAST_1" = "61e0797dde08fb498ca11a71`.
415+
414416
## Import
415417

416418
Clusters can be imported using project ID and cluster name, in the format `PROJECTID-CLUSTERNAME`, e.g.

website/docs/r/cluster.html.markdown

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ But in order to explicitly change `provider_instance_size_name` comment the `lif
378378
* `version_release_system` - (Optional) - Release cadence that Atlas uses for this cluster. This parameter defaults to `LTS`. If you set this field to `CONTINUOUS`, you must omit the `mongo_db_major_version` field. Atlas accepts:
379379
- `CONTINUOUS`: Atlas creates your cluster using the most recent MongoDB release. Atlas automatically updates your cluster to the latest major and rapid MongoDB releases as they become available.
380380
- `LTS`: Atlas creates your cluster using the latest patch release of the MongoDB version that you specify in the mongoDBMajorVersion field. Atlas automatically updates your cluster to subsequent patch releases of this MongoDB version. Atlas doesn't update your cluster to newer rapid or major MongoDB releases as they become available.
381+
* `timeouts`- (Optional) The duration of time to wait for Cluster to be created, updated, or deleted. The timeout value is defined by a signed sequence of decimal numbers with an time unit suffix such as: `1h45m`, `300s`, `10m`, .... The valid time units are: `ns`, `us` (or `µs`), `ms`, `s`, `m`, `h`. The default timeout for Private Endpoint create & delete is `3h`. Learn more about timeouts [here](https://www.terraform.io/plugin/sdkv2/resources/retries-and-customizable-timeouts).
381382

382383
### Multi-Region Cluster
383384

0 commit comments

Comments
 (0)