Skip to content

Commit a8a32f8

Browse files
authored
feat: Long-running operation improvements for mongodbatlas_cloud_backup_snapshot resource (#3536)
* rename * implement delete_on_create_timeout * fix delete_on_create_timeout due to lack of update * refactor test * rename test * improve var naming
1 parent e2e475b commit a8a32f8

File tree

9 files changed

+68
-8
lines changed

9 files changed

+68
-8
lines changed

.changelog/3536.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_cloud_backup_snapshot: Adds `delete_on_create_timeout` attribute to indicate whether to delete the resource if its creation times out
3+
```

docs/resources/cloud_backup_snapshot.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ resource "mongodbatlas_cloud_backup_snapshot_restore_job" "test" {
5757
* `description` - (Required) Description of the on-demand snapshot.
5858
* `retention_in_days` - (Required) The number of days that Atlas should retain the on-demand snapshot. Must be at least 1.
5959
* `timeouts`- (Optional) The duration of time to wait for Atlas to create a Cloud Backup Snapshot. The timeout value is defined by a signed sequence of decimal numbers with a time unit suffix such as: `1h45m`, `300s`, `10m`, etc. The valid time units are: `ns`, `us` (or `µs`), `ms`, `s`, `m`, `h`. Defaults to `1h`. Learn more about timeouts [here](https://www.terraform.io/plugin/sdkv2/resources/retries-and-customizable-timeouts).
60+
* `delete_on_create_timeout`- (Optional) Flag that indicates whether to delete the resource if creation times out. Default is `true`. When Terraform apply fails, it returns immediately without waiting for cleanup to complete. If you suspect a transient error, wait before retrying to allow resource deletion to finish.
6061

6162
## Attributes Reference
6263

internal/service/cloudbackupsnapshot/resource_cloud_backup_snapshot.go renamed to internal/service/cloudbackupsnapshot/resource.go

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
1111
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1212
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
13+
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/cleanup"
1314
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion"
1415
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/validate"
1516
"github.com/mongodb/terraform-provider-mongodbatlas/internal/config"
@@ -19,9 +20,9 @@ import (
1920

2021
func Resource() *schema.Resource {
2122
return &schema.Resource{
22-
CreateContext: resourceCreate,
23-
ReadContext: resourceRead,
24-
DeleteContext: resourceDelete,
23+
CreateWithoutTimeout: resourceCreate,
24+
ReadWithoutTimeout: resourceRead,
25+
DeleteWithoutTimeout: resourceDelete,
2526
Importer: &schema.ResourceImporter{
2627
StateContext: resourceImport,
2728
},
@@ -121,10 +122,20 @@ func Resource() *schema.Resource {
121122
Type: schema.TypeString,
122123
},
123124
},
125+
"delete_on_create_timeout": { // Don't use Default: true to avoid unplanned changes when upgrading from previous versions.
126+
Type: schema.TypeBool,
127+
Optional: true,
128+
ForceNew: true,
129+
Description: "Flag that indicates whether to delete the resource if creation times out. Default is true.",
130+
},
124131
},
125132
}
126133
}
127134

135+
const (
136+
oneMinute = 1 * time.Minute
137+
)
138+
128139
func resourceCreate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
129140
connV2 := meta.(*config.MongoDBClient).AtlasV2
130141
groupID := d.Get("project_id").(string)
@@ -155,12 +166,20 @@ func resourceCreate(ctx context.Context, d *schema.ResourceData, meta any) diag.
155166
Target: []string{"completed", "failed"},
156167
Refresh: resourceRefreshFunc(ctx, requestParams, connV2),
157168
Timeout: d.Timeout(schema.TimeoutCreate) - time.Minute,
158-
MinTimeout: 60 * time.Second,
159-
Delay: 1 * time.Minute,
169+
MinTimeout: oneMinute,
170+
Delay: oneMinute,
160171
}
161-
_, err = stateConf.WaitForStateContext(ctx)
162-
if err != nil {
163-
return diag.FromErr(err)
172+
_, errWait := stateConf.WaitForStateContext(ctx)
173+
deleteOnCreateTimeout := true // default value when not set
174+
if v, ok := d.GetOkExists("delete_on_create_timeout"); ok {
175+
deleteOnCreateTimeout = v.(bool)
176+
}
177+
errWait = cleanup.HandleCreateTimeout(deleteOnCreateTimeout, errWait, func(ctxCleanup context.Context) error {
178+
_, errCleanup := connV2.CloudBackupsApi.DeleteReplicaSetBackup(ctxCleanup, groupID, clusterName, snapshot.GetId()).Execute()
179+
return errCleanup
180+
})
181+
if errWait != nil {
182+
return diag.Errorf("error creating a snapshot: %s", errWait)
164183
}
165184

166185
d.SetId(conversion.EncodeStateID(map[string]string{

internal/service/cloudbackupsnapshot/resource_cloud_backup_snapshot_test.go renamed to internal/service/cloudbackupsnapshot/resource_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package cloudbackupsnapshot_test
33
import (
44
"context"
55
"fmt"
6+
"regexp"
67
"testing"
78

89
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
@@ -99,6 +100,26 @@ func TestAccBackupRSCloudBackupSnapshot_sharded(t *testing.T) {
99100
})
100101
}
101102

103+
func TestAccBackupRSCloudBackupSnapshot_deleteOnCreateTimeout(t *testing.T) {
104+
var (
105+
clusterInfo = acc.GetClusterInfo(t, &acc.ClusterRequest{CloudBackup: true})
106+
description = "Timeout test snapshot"
107+
retentionInDays = "1"
108+
)
109+
110+
resource.ParallelTest(t, resource.TestCase{
111+
PreCheck: acc.PreCheckBasicSleep(t, &clusterInfo, "", ""),
112+
ProtoV6ProviderFactories: acc.TestAccProviderV6Factories,
113+
CheckDestroy: checkDestroy,
114+
Steps: []resource.TestStep{
115+
{
116+
Config: configCreateTimeoutAndDeleteOnCreateTimeout(&clusterInfo, description, retentionInDays),
117+
ExpectError: regexp.MustCompile("will run cleanup because delete_on_create_timeout is true"),
118+
},
119+
},
120+
})
121+
}
122+
102123
func checkExists(resourceName string) resource.TestCheckFunc {
103124
return func(s *terraform.State) error {
104125
rs, ok := s.RootModule().Resources[resourceName]
@@ -220,3 +241,19 @@ func configSharded(projectID, clusterName, description, retentionInDays string)
220241
221242
`, projectID, clusterName, description, retentionInDays)
222243
}
244+
245+
func configCreateTimeoutAndDeleteOnCreateTimeout(info *acc.ClusterInfo, description, retentionInDays string) string {
246+
return info.TerraformStr + fmt.Sprintf(`
247+
resource "mongodbatlas_cloud_backup_snapshot" "test" {
248+
cluster_name = %[1]s
249+
project_id = %[2]q
250+
description = %[3]q
251+
retention_in_days = %[4]q
252+
delete_on_create_timeout = true
253+
254+
timeouts {
255+
create = "10s"
256+
}
257+
}
258+
`, info.TerraformNameRef, info.ProjectID, description, retentionInDays)
259+
}

0 commit comments

Comments
 (0)