Skip to content

Commit 39d4229

Browse files
committed
azurerm_subscription - Reorder delete operations to cancel subscription then delete alias
1 parent 00b35eb commit 39d4229

File tree

1 file changed

+31
-21
lines changed

1 file changed

+31
-21
lines changed

internal/services/subscription/subscription_resource.go

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"context"
88
"fmt"
99
"log"
10+
"slices"
1011
"time"
1112

1213
"github.com/google/uuid"
@@ -405,6 +406,36 @@ func resourceSubscriptionDelete(d *pluginsdk.ResourceData, meta interface{}) err
405406
if subscriptionName == "" || subscriptionId == "" {
406407
return fmt.Errorf("one or both of Subscription Name (%q) and Subscription ID (%q) could not be determined", subscriptionName, subscriptionId)
407408
}
409+
410+
// The below order matters: Cancel the subscription, then removing the alias.
411+
// The alias is the *main* handle of this terraform resource, we shall only delete it as the last step to avoid trailing partial state,
412+
// which otherwise can't be mitigated by a second `terraform run` (the Read() regards this resource is gone since alias is deleted).
413+
414+
// Cancel the Subscription
415+
if !meta.(*clients.Client).Features.Subscription.PreventCancellationOnDestroy {
416+
if slices.Contains([]subscriptions.SubscriptionState{subscriptions.SubscriptionStateDisabled, subscriptions.SubscriptionStateWarned}, pointer.From(sub.Model.State)) {
417+
log.Printf("[DEBUG] Subscription %s is already cancelled", subscriptionId)
418+
} else {
419+
log.Printf("[DEBUG] Cancelling subscription %s", subscriptionId)
420+
421+
opts := subscriptionAlias.DefaultSubscriptionCancelOperationOptions()
422+
// TODO: support a Provider `features` flag to enable deleting a Subscription containing Resources
423+
// This is a dangerous operation, and likely wants a similar default value as to that for Resource Groups
424+
if _, err := aliasClient.SubscriptionCancel(ctx, subscriptionResourceId, opts); err != nil {
425+
return fmt.Errorf("failed to cancel Subscription: %+v", err)
426+
}
427+
428+
deadline, _ := ctx.Deadline()
429+
deleteDeadline := time.Until(deadline)
430+
431+
if err := waitForSubscriptionStateToSettle(ctx, client, subscriptionResourceId, "Cancelled", deleteDeadline); err != nil {
432+
return fmt.Errorf("failed to cancel Subscription %q (Alias %q): %+v", subscriptionId, id.AliasName, err)
433+
}
434+
}
435+
} else {
436+
log.Printf("[DEBUG] Skipping subscription %s cancellation due to feature flag.", *id)
437+
}
438+
408439
// remove the alias
409440
if _, count, err := checkExistingAliases(ctx, *aliasClient, subscriptionId); err != nil {
410441
if count > 1 {
@@ -419,27 +450,6 @@ func resourceSubscriptionDelete(d *pluginsdk.ResourceData, meta interface{}) err
419450
}
420451
}
421452

422-
// Cancel the Subscription
423-
if !meta.(*clients.Client).Features.Subscription.PreventCancellationOnDestroy {
424-
log.Printf("[DEBUG] Cancelling subscription %s", subscriptionId)
425-
426-
opts := subscriptionAlias.DefaultSubscriptionCancelOperationOptions()
427-
// TODO: support a Provider `features` flag to enable deleting a Subscription containing Resources
428-
// This is a dangerous operation, and likely wants a similar default value as to that for Resource Groups
429-
if _, err := aliasClient.SubscriptionCancel(ctx, subscriptionResourceId, opts); err != nil {
430-
return fmt.Errorf("failed to cancel Subscription: %+v", err)
431-
}
432-
433-
deadline, _ := ctx.Deadline()
434-
deleteDeadline := time.Until(deadline)
435-
436-
if err := waitForSubscriptionStateToSettle(ctx, client, subscriptionResourceId, "Cancelled", deleteDeadline); err != nil {
437-
return fmt.Errorf("failed to cancel Subscription %q (Alias %q): %+v", subscriptionId, id.AliasName, err)
438-
}
439-
} else {
440-
log.Printf("[DEBUG] Skipping subscription %s cancellation due to feature flag.", *id)
441-
}
442-
443453
return nil
444454
}
445455

0 commit comments

Comments
 (0)