diff --git a/azuread/helpers/graph/group.go b/azuread/helpers/graph/group.go index 6d5ccc6feb..c22ad79b95 100644 --- a/azuread/helpers/graph/group.go +++ b/azuread/helpers/graph/group.go @@ -134,7 +134,7 @@ func GroupAddMember(client graphrbac.GroupsClient, ctx context.Context, groupId time.Sleep(time.Second * 2) } - if _, err := WaitForListMember(member, func() ([]string, error) { + if _, err := WaitForListAdd(member, func() ([]string, error) { return GroupAllMembers(client, ctx, groupId) }); err != nil { return fmt.Errorf("Error waiting for group membership: %+v", err) diff --git a/azuread/helpers/graph/replication.go b/azuread/helpers/graph/replication.go index 960c2e2d0a..b301d12993 100644 --- a/azuread/helpers/graph/replication.go +++ b/azuread/helpers/graph/replication.go @@ -35,7 +35,7 @@ func WaitForCreationReplication(f func() (interface{}, error)) (interface{}, err }).WaitForState() } -func WaitForListMember(member string, f func() ([]string, error)) (interface{}, error) { +func WaitForListAdd(item string, f func() ([]string, error)) (interface{}, error) { return (&resource.StateChangeConf{ Pending: []string{"404"}, Target: []string{"Found"}, @@ -43,19 +43,44 @@ func WaitForListMember(member string, f func() ([]string, error)) (interface{}, MinTimeout: 1 * time.Second, ContinuousTargetOccurence: 10, Refresh: func() (interface{}, string, error) { - members, err := f() + listItems, err := f() if err != nil { - return members, "Error", err + return listItems, "Error", err } - for _, v := range members { - if v == member { - return members, "Found", nil + for _, v := range listItems { + if v == item { + return listItems, "Found", nil } } - return members, "404", nil + return listItems, "404", nil + }, + }).WaitForState() +} + +func WaitForListRemove(item string, f func() ([]string, error)) (interface{}, error) { + return (&resource.StateChangeConf{ + Pending: []string{"Found"}, + Target: []string{"404"}, + Timeout: 5 * time.Minute, + MinTimeout: 1 * time.Second, + ContinuousTargetOccurence: 10, + Refresh: func() (interface{}, string, error) { + listItems, err := f() + + if err != nil { + return listItems, "Error", err + } + + for _, v := range listItems { + if v == item { + return listItems, "Found", nil + } + } + + return listItems, "404", nil }, }).WaitForState() } diff --git a/azuread/resource_group.go b/azuread/resource_group.go index 6b15e96862..c240b59cd5 100644 --- a/azuread/resource_group.go +++ b/azuread/resource_group.go @@ -2,7 +2,9 @@ package azuread import ( "fmt" + "github.com/Azure/go-autorest/autorest" "log" + "time" "github.com/Azure/azure-sdk-for-go/services/graphrbac/1.6/graphrbac" "github.com/Azure/go-autorest/autorest" @@ -187,11 +189,26 @@ func resourceGroupUpdate(d *schema.ResourceData, meta interface{}) error { membersToAdd := slices.Difference(desiredMembers, existingMembers) for _, existingMember := range membersForRemoval { + var err error + var resp autorest.Response log.Printf("[DEBUG] Removing member with id %q from Azure AD group with id %q", existingMember, d.Id()) - if resp, err := client.RemoveMember(ctx, d.Id(), existingMember); err != nil { - if !ar.ResponseWasNotFound(resp) { + attempts := 10 + for i := 0; i <= attempts; i++ { + if resp, err = client.RemoveMember(ctx, d.Id(), existingMember); err != nil { + if ar.ResponseWasNotFound(resp) { + break + } + } + if i == attempts { return fmt.Errorf("Error Deleting group member %q from Azure AD Group with ID %q: %+v", existingMember, d.Id(), err) } + time.Sleep(time.Second * 2) + } + + if _, err := graph.WaitForListRemove(existingMember, func() ([]string, error) { + return graph.GroupAllMembers(client, ctx, d.Id()) + }); err != nil { + return fmt.Errorf("Error waiting for group membership removal: %+v", err) } }