Skip to content

Commit f0afdb2

Browse files
committed
Adds force_destroy attribute
1 parent 3e9c97f commit f0afdb2

File tree

2 files changed

+71
-4
lines changed

2 files changed

+71
-4
lines changed

internal/service/dsql/cluster.go

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ func (r *clusterResource) Schema(ctx context.Context, request resource.SchemaReq
7070
Default: booldefault.StaticBool(false),
7171
},
7272
"encryption_details": framework.ResourceComputedListOfObjectsAttribute[encryptionDetailsModel](ctx),
73+
names.AttrForceDestroy: schema.BoolAttribute{
74+
Optional: true,
75+
Computed: true,
76+
Default: booldefault.StaticBool(false),
77+
},
7378
names.AttrIdentifier: framework.IDAttribute(),
7479
"kms_encryption_key": schema.StringAttribute{
7580
Optional: true,
@@ -313,6 +318,19 @@ func (r *clusterResource) Delete(ctx context.Context, request resource.DeleteReq
313318

314319
conn := r.Meta().DSQLClient(ctx)
315320

321+
if data.ForceDestroy.ValueBool() {
322+
input := dsql.UpdateClusterInput{
323+
Identifier: data.Identifier.ValueStringPointer(),
324+
DeletionProtectionEnabled: aws.Bool(false),
325+
ClientToken: aws.String(sdkid.UniqueId()),
326+
}
327+
// Changing DeletionProtectionEnabled is instantaneous, no need to wait.
328+
if _, err := conn.UpdateCluster(ctx, &input); err != nil {
329+
response.Diagnostics.AddError(fmt.Sprintf("disabling deletion protection for Aurora DSQL Cluster (%s)", data.Identifier.ValueString()), err.Error())
330+
return
331+
}
332+
}
333+
316334
id := fwflex.StringValueFromFramework(ctx, data.Identifier)
317335
tflog.Debug(ctx, "deleting Aurora DSQL Cluster", map[string]any{
318336
names.AttrIdentifier: id,
@@ -342,6 +360,9 @@ func (r *clusterResource) Delete(ctx context.Context, request resource.DeleteReq
342360

343361
func (r *clusterResource) ImportState(ctx context.Context, request resource.ImportStateRequest, response *resource.ImportStateResponse) {
344362
resource.ImportStatePassthroughID(ctx, path.Root(names.AttrIdentifier), request, response)
363+
364+
// Set force_destroy to false on import to prevent accidental deletion
365+
response.Diagnostics.Append(response.State.SetAttribute(ctx, path.Root(names.AttrForceDestroy), types.BoolValue(false))...)
345366
}
346367

347368
func findClusterByID(ctx context.Context, conn *dsql.Client, id string) (*dsql.GetClusterOutput, error) {
@@ -445,10 +466,12 @@ func waitClusterUpdated(ctx context.Context, conn *dsql.Client, id string, timeo
445466

446467
func waitClusterDeleted(ctx context.Context, conn *dsql.Client, id string, timeout time.Duration) (*dsql.GetClusterOutput, error) {
447468
stateConf := &retry.StateChangeConf{
448-
Pending: enum.Slice(awstypes.ClusterStatusDeleting, awstypes.ClusterStatusPendingDelete),
449-
Target: []string{},
450-
Refresh: statusCluster(ctx, conn, id),
451-
Timeout: timeout,
469+
Pending: enum.Slice(awstypes.ClusterStatusDeleting, awstypes.ClusterStatusPendingDelete),
470+
Target: []string{},
471+
Refresh: statusCluster(ctx, conn, id),
472+
Timeout: timeout,
473+
Delay: 1 * time.Minute,
474+
PollInterval: 10 * time.Second,
452475
}
453476

454477
outputRaw, err := stateConf.WaitForStateContext(ctx)
@@ -526,6 +549,7 @@ type clusterResourceModel struct {
526549
ARN types.String `tfsdk:"arn"`
527550
DeletionProtectionEnabled types.Bool `tfsdk:"deletion_protection_enabled"`
528551
EncryptionDetails fwtypes.ListNestedObjectValueOf[encryptionDetailsModel] `tfsdk:"encryption_details"`
552+
ForceDestroy types.Bool `tfsdk:"force_destroy"`
529553
Identifier types.String `tfsdk:"identifier"`
530554
KMSEncryptionKey types.String `tfsdk:"kms_encryption_key"`
531555
MultiRegionProperties fwtypes.ListNestedObjectValueOf[multiRegionPropertiesModel] `tfsdk:"multi_region_properties"`

internal/service/dsql/cluster_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ func TestAccDSQLCluster_basic(t *testing.T) {
5959
"encryption_type": tfknownvalue.StringExact(awstypes.EncryptionTypeAwsOwnedKmsKey),
6060
}),
6161
})),
62+
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("force_destroy"), knownvalue.Bool(false)),
6263
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("kms_encryption_key"), knownvalue.StringExact("AWS_OWNED_KMS_KEY")),
6364
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.Null()),
6465
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("vpc_endpoint_service_name"), knownvalue.NotNull()),
@@ -154,6 +155,39 @@ func TestAccDSQLCluster_deletionProtection(t *testing.T) {
154155
})
155156
}
156157

158+
func TestAccDSQLCluster_forceDestroy(t *testing.T) {
159+
ctx := acctest.Context(t)
160+
var cluster dsql.GetClusterOutput
161+
resourceName := "aws_dsql_cluster.test"
162+
163+
resource.ParallelTest(t, resource.TestCase{
164+
PreCheck: func() {
165+
acctest.PreCheck(ctx, t)
166+
testAccPreCheck(ctx, t)
167+
},
168+
ErrorCheck: acctest.ErrorCheck(t, names.DSQLServiceID),
169+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
170+
CheckDestroy: testAccCheckClusterDestroy(ctx),
171+
Steps: []resource.TestStep{
172+
{
173+
Config: testAccClusterConfig_forceDestroy(true),
174+
Check: resource.ComposeAggregateTestCheckFunc(
175+
testAccCheckClusterExists(ctx, resourceName, &cluster),
176+
),
177+
ConfigPlanChecks: resource.ConfigPlanChecks{
178+
PreApply: []plancheck.PlanCheck{
179+
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionCreate),
180+
},
181+
},
182+
ConfigStateChecks: []statecheck.StateCheck{
183+
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("deletion_protection_enabled"), knownvalue.Bool(true)),
184+
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("force_destroy"), knownvalue.Bool(true)),
185+
},
186+
},
187+
},
188+
})
189+
}
190+
157191
func TestAccDSQLCluster_encryption(t *testing.T) {
158192
ctx := acctest.Context(t)
159193
var cluster dsql.GetClusterOutput
@@ -296,6 +330,15 @@ resource "aws_dsql_cluster" "test" {
296330
`, deletionProtection)
297331
}
298332

333+
func testAccClusterConfig_forceDestroy(deletionProtection bool) string {
334+
return fmt.Sprintf(`
335+
resource "aws_dsql_cluster" "test" {
336+
deletion_protection_enabled = %[1]t
337+
force_destroy = true
338+
}
339+
`, deletionProtection)
340+
}
341+
299342
func testAccClusterConfig_baseEncryptionDetails(rName string) string {
300343
return fmt.Sprintf(`
301344
resource "aws_kms_key" "test" {

0 commit comments

Comments
 (0)