From 630de403cec7064cf0ed3cd8288bf57bc9ba6bce Mon Sep 17 00:00:00 2001 From: Paul Stack Date: Wed, 27 Jul 2016 22:57:02 +0100 Subject: [PATCH] provider/azurerm: Wait for `azurerm_storage_account` to be available (#7329) Fixes #7005 where a container tried to provision *before* the storage account was available. We now wait for the Storage Account to be in the `Succeeded` state before returning ``` make testacc TEST=./builtin/providers/azurerm TESTARGS='-run=TestAccAzureRMStorageAccount_' ==> Checking that code complies with gofmt requirements... go generate $(go list ./... | grep -v /vendor/) TF_ACC=1 go test ./builtin/providers/azurerm -v -run=TestAccAzureRMStorageAccount_ -timeout 120m === RUN TestAccAzureRMStorageAccount_basic --- PASS: TestAccAzureRMStorageAccount_basic (163.68s) PASS ok github.com/hashicorp/terraform/builtin/providers/azurerm 163.695s ``` --- .../azurerm/resource_arm_storage_account.go | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/builtin/providers/azurerm/resource_arm_storage_account.go b/builtin/providers/azurerm/resource_arm_storage_account.go index 2d01952cf8..059e92ecbb 100644 --- a/builtin/providers/azurerm/resource_arm_storage_account.go +++ b/builtin/providers/azurerm/resource_arm_storage_account.go @@ -2,11 +2,14 @@ package azurerm import ( "fmt" + "log" "net/http" "regexp" "strings" + "time" "github.com/Azure/azure-sdk-for-go/arm/storage" + "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" ) @@ -109,7 +112,8 @@ func resourceArmStorageAccount() *schema.Resource { } func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).storageServiceClient + client := meta.(*ArmClient) + storageClient := client.storageServiceClient resourceGroupName := d.Get("resource_group_name").(string) storageAccountName := d.Get("name").(string) @@ -127,13 +131,13 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e Tags: expandTags(tags), } - _, err := client.Create(resourceGroupName, storageAccountName, opts, make(chan struct{})) + _, err := storageClient.Create(resourceGroupName, storageAccountName, opts, make(chan struct{})) if err != nil { return fmt.Errorf("Error creating Azure Storage Account '%s': %s", storageAccountName, err) } // The only way to get the ID back apparently is to read the resource again - read, err := client.GetProperties(resourceGroupName, storageAccountName) + read, err := storageClient.GetProperties(resourceGroupName, storageAccountName) if err != nil { return err } @@ -142,6 +146,18 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e storageAccountName, resourceGroupName) } + log.Printf("[DEBUG] Waiting for Storage Account (%s) to become available", storageAccountName) + stateConf := &resource.StateChangeConf{ + Pending: []string{"Updating", "Creating"}, + Target: []string{"Succeeded"}, + Refresh: storageAccountStateRefreshFunc(client, resourceGroupName, storageAccountName), + Timeout: 30 * time.Minute, + MinTimeout: 15 * time.Second, + } + if _, err := stateConf.WaitForState(); err != nil { + return fmt.Errorf("Error waiting for Storage Account (%s) to become available: %s", storageAccountName, err) + } + d.SetId(*read.ID) return resourceArmStorageAccountRead(d, meta) @@ -305,3 +321,14 @@ func validateArmStorageAccountType(v interface{}, k string) (ws []string, es []e es = append(es, fmt.Errorf("Invalid storage account type %q", input)) return } + +func storageAccountStateRefreshFunc(client *ArmClient, resourceGroupName string, storageAccountName string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + res, err := client.storageServiceClient.GetProperties(resourceGroupName, storageAccountName) + if err != nil { + return nil, "", fmt.Errorf("Error issuing read request in storageAccountStateRefreshFunc to Azure ARM for Storage Account '%s' (RG: '%s'): %s", storageAccountName, resourceGroupName, err) + } + + return res, string(res.Properties.ProvisioningState), nil + } +}