diff --git a/internal/services/appconfiguration/app_configuration_resource.go b/internal/services/appconfiguration/app_configuration_resource.go index 64e13ce095f9..12a1f3ad3e57 100644 --- a/internal/services/appconfiguration/app_configuration_resource.go +++ b/internal/services/appconfiguration/app_configuration_resource.go @@ -1,6 +1,7 @@ package appconfiguration import ( + "context" "fmt" "log" "net/http" @@ -15,6 +16,8 @@ import ( "github.com/hashicorp/go-azure-helpers/resourcemanager/tags" "github.com/hashicorp/go-azure-sdk/resource-manager/appconfiguration/2023-03-01/configurationstores" "github.com/hashicorp/go-azure-sdk/resource-manager/appconfiguration/2023-03-01/deletedconfigurationstores" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/client/pollers" "github.com/hashicorp/terraform-provider-azurerm/helpers/azure" "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" @@ -551,15 +554,20 @@ func resourceAppConfigurationDelete(d *pluginsdk.ResourceData, meta interface{}) } log.Printf("[DEBUG] %q marked for purge - executing purge", id.ConfigurationStoreName) - poller, err := deletedConfigurationStoresClient.ConfigurationStoresPurgeDeleted(ctx, deletedId) - if err != nil { + + if _, err := deletedConfigurationStoresClient.ConfigurationStoresPurgeDeleted(ctx, deletedId); err != nil { return fmt.Errorf("purging %s: %+v", *id, err) } - // NOTE: the PurgeDeleted method is a POST which eventually returns a 404 from the LRO, so we need to handle that - if err := poller.Poller.PollUntilDone(ctx); err != nil { - if resp := poller.Poller.LatestResponse(); resp == nil || !response.WasNotFound(resp.Response) { - return fmt.Errorf("polling after purging for %s: %+v", *id, err) - } + + // The PurgeDeleted API is a POST which returns a 200 with no body and nothing to poll on, so we'll need + // a custom poller to poll until the LRO returns a 404 + pollerType := &purgeDeletedPoller{ + client: deletedConfigurationStoresClient, + id: deletedId, + } + poller := pollers.NewPoller(pollerType, 10*time.Second, pollers.DefaultNumberOfDroppedConnectionsToAllow) + if err := poller.PollUntilDone(ctx); err != nil { + return fmt.Errorf("polling after purging for %s: %+v", *id, err) } // TODO: retry checkNameAvailability after deletion when SDK is ready, see https://github.com/Azure/AppConfiguration/issues/677 @@ -569,6 +577,42 @@ func resourceAppConfigurationDelete(d *pluginsdk.ResourceData, meta interface{}) return nil } +var _ pollers.PollerType = &purgeDeletedPoller{} + +type purgeDeletedPoller struct { + client *deletedconfigurationstores.DeletedConfigurationStoresClient + id deletedconfigurationstores.DeletedConfigurationStoreId +} + +func (p *purgeDeletedPoller) Poll(ctx context.Context) (*pollers.PollResult, error) { + resp, err := p.client.ConfigurationStoresGetDeleted(ctx, p.id) + + status := "dropped connection" + if resp.HttpResponse != nil { + status = fmt.Sprintf("%d", resp.HttpResponse.StatusCode) + } + + if response.WasNotFound(resp.HttpResponse) { + return &pollers.PollResult{ + HttpResponse: &client.Response{ + Response: resp.HttpResponse, + }, + Status: pollers.PollingStatusSucceeded, + }, nil + } + + if response.WasStatusCode(resp.HttpResponse, http.StatusOK) { + return &pollers.PollResult{ + HttpResponse: &client.Response{ + Response: resp.HttpResponse, + }, + Status: pollers.PollingStatusInProgress, + }, nil + } + + return nil, fmt.Errorf("unexpected status %q: %+v", status, err) +} + type flattenedAccessKeys struct { primaryReadKey []interface{} primaryWriteKey []interface{}