Skip to content

Commit

Permalink
Merge pull request #7473 from terraform-providers/b/managementgroup-c…
Browse files Browse the repository at this point in the history
…reate-race

add retry logic on managementgroup creation
  • Loading branch information
tombuildsstuff committed Jun 25, 2020
2 parents 70e9ef4 + 32dff25 commit 2061d8a
Showing 1 changed file with 34 additions and 0 deletions.
@@ -1,6 +1,7 @@
package managementgroup

import (
"context"
"fmt"
"log"
"strings"
Expand All @@ -9,6 +10,7 @@ import (
"github.com/Azure/azure-sdk-for-go/services/preview/resources/mgmt/2018-03-01-preview/managementgroups"
"github.com/google/uuid"
"github.com/hashicorp/go-azure-helpers/response"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
Expand Down Expand Up @@ -148,6 +150,24 @@ func resourceArmManagementGroupCreateUpdate(d *schema.ResourceData, meta interfa
return fmt.Errorf("failed when waiting for creation of Management Group %q: %+v", groupName, err)
}

// We have a potential race condition / consistency issue whereby the implicit role assignment for the SP may not be
// completed before the read-back here or an eventually consistent read is creating a temporary 403 error.
stateConf := &resource.StateChangeConf{
Pending: []string{
"pending",
},
Target: []string{
"succeeded",
},
Refresh: managementgroupCreateStateRefreshFunc(ctx, client, groupName),
Timeout: d.Timeout(schema.TimeoutCreate),
ContinuousTargetOccurence: 5,
}

if _, err := stateConf.WaitForState(); err != nil {
return fmt.Errorf("failed waiting for read on Managementgroup %q", groupName)
}

resp, err := client.Get(ctx, groupName, "children", &recurse, "", managementGroupCacheControl)
if err != nil {
return fmt.Errorf("unable to retrieve Management Group %q: %+v", groupName, err)
Expand Down Expand Up @@ -398,3 +418,17 @@ func determineManagementGroupSubscriptionsIdsToRemove(existing *[]managementgrou

return &subscriptionIdsToRemove, nil
}

func managementgroupCreateStateRefreshFunc(ctx context.Context, client *managementgroups.Client, groupName string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
resp, err := client.Get(ctx, groupName, "children", utils.Bool(true), "", managementGroupCacheControl)
if err != nil {
if utils.ResponseWasForbidden(resp.Response) {
return resp, "pending", nil
}
return resp, "failed", err
}

return resp, "succeeded", nil
}
}

0 comments on commit 2061d8a

Please sign in to comment.