diff --git a/azuread/provider.go b/azuread/provider.go index 1daa67313..4144e8118 100644 --- a/azuread/provider.go +++ b/azuread/provider.go @@ -2,6 +2,7 @@ package azuread import ( "fmt" + "time" "github.com/hashicorp/go-azure-helpers/authentication" "github.com/hashicorp/terraform/helper/mutexkv" @@ -12,6 +13,9 @@ import ( // armMutexKV is the instance of MutexKV for ARM resources var armMutexKV = mutexkv.NewMutexKV() +const azureAdReplicationTimeout = 5 * time.Minute +const azureAdReplicationTargetOccurence = 10 + // Provider returns a terraform.ResourceProvider. func Provider() terraform.ResourceProvider { p := &schema.Provider{ diff --git a/azuread/resource_application.go b/azuread/resource_application.go index 53fde6760..c6734886a 100644 --- a/azuread/resource_application.go +++ b/azuread/resource_application.go @@ -229,16 +229,28 @@ func resourceApplicationCreate(d *schema.ResourceData, meta interface{}) error { } d.SetId(*app.ObjectID) - // mimicking the behaviour of az tool retry until a successful get - if err := resource.Retry(3*time.Minute, func() *resource.RetryError { - if _, err := client.Get(ctx, *app.ObjectID); err != nil { - return resource.RetryableError(err) - } - - return nil - }); err != nil { - return fmt.Errorf("Error waiting for Application %q to become available: %+v", name, err) + i, err := (&resource.StateChangeConf{ + Pending: []string{"404"}, + Target: []string{"Found"}, + Timeout: azureAdReplicationTimeout, + MinTimeout: 1 * time.Second, + ContinuousTargetOccurence: azureAdReplicationTargetOccurence, + Refresh: func() (interface{}, string, error) { + resp, err2 := client.Get(ctx, *app.ObjectID) + if err2 != nil { + if ar.ResponseWasNotFound(resp.Response) { + return resp, "404", nil + } + return resp, "Error", fmt.Errorf("Error retrieving Application ID %q: %+v", *app.ObjectID, err2) + } + + return resp, "Found", nil + }, + }).WaitForState() + if err != nil { + return fmt.Errorf("Error waiting for application: %+v", err) } + app = i.(graphrbac.Application) // follow suggested hack for azure-cli // AAD graph doesn't have the API to create a native app, aka public client, the recommended hack is diff --git a/azuread/resource_service_principal.go b/azuread/resource_service_principal.go index db189a055..c405cd905 100644 --- a/azuread/resource_service_principal.go +++ b/azuread/resource_service_principal.go @@ -80,16 +80,28 @@ func resourceServicePrincipalCreate(d *schema.ResourceData, meta interface{}) er } d.SetId(*sp.ObjectID) - // mimicking the behaviour of az tool retry until a successful get - if err := resource.Retry(3*time.Minute, func() *resource.RetryError { - if _, err := client.Get(ctx, *sp.ObjectID); err != nil { - return resource.RetryableError(err) - } + i, err := (&resource.StateChangeConf{ + Pending: []string{"404"}, + Target: []string{"Found"}, + Timeout: azureAdReplicationTimeout, + MinTimeout: 1 * time.Second, + ContinuousTargetOccurence: azureAdReplicationTargetOccurence, + Refresh: func() (interface{}, string, error) { + resp, err2 := client.Get(ctx, *sp.ObjectID) + if err2 != nil { + if ar.ResponseWasNotFound(resp.Response) { + return resp, "404", nil + } + return resp, "Error", fmt.Errorf("Error retrieving Service Principal ID %q: %+v", *sp.ObjectID, err2) + } - return nil - }); err != nil { - return fmt.Errorf("Error waiting for Service Principal %q to become available: %+v", applicationId, err) + return resp, "Found", nil + }, + }).WaitForState() + if err != nil { + return fmt.Errorf("Error waiting for application: %+v", err) } + sp = i.(graphrbac.ServicePrincipal) return resourceServicePrincipalRead(d, meta) }