diff --git a/builtin/providers/azurerm/config.go b/builtin/providers/azurerm/config.go index eb6b0d4dc0c5..0a84852d0b01 100644 --- a/builtin/providers/azurerm/config.go +++ b/builtin/providers/azurerm/config.go @@ -314,44 +314,55 @@ func (c *Config) getArmClient() (*ArmClient, error) { return &client, nil } -func (armClient *ArmClient) getKeyForStorageAccount(resourceGroupName, storageAccountName string) (string, error) { +func (armClient *ArmClient) getKeyForStorageAccount(resourceGroupName, storageAccountName string) (string, bool, error) { keys, err := armClient.storageServiceClient.ListKeys(resourceGroupName, storageAccountName) + if keys.StatusCode == http.StatusNotFound { + return "", false, nil + } if err != nil { - return "", fmt.Errorf("Error retrieving keys for storage account %q: %s", storageAccountName, err) + // We assume this is a transient error rather than a 404 (which is caught above), so assume the + // account still exists. + return "", true, fmt.Errorf("Error retrieving keys for storage account %q: %s", storageAccountName, err) } if keys.Key1 == nil { - return "", fmt.Errorf("Nil key returned for storage account %q", storageAccountName) + return "", false, fmt.Errorf("Nil key returned for storage account %q", storageAccountName) } - return *keys.Key1, nil + return *keys.Key1, true, nil } -func (armClient *ArmClient) getBlobStorageClientForStorageAccount(resourceGroupName, storageAccountName string) (*mainStorage.BlobStorageClient, error) { - key, err := armClient.getKeyForStorageAccount(resourceGroupName, storageAccountName) +func (armClient *ArmClient) getBlobStorageClientForStorageAccount(resourceGroupName, storageAccountName string) (*mainStorage.BlobStorageClient, bool, error) { + key, accountExists, err := armClient.getKeyForStorageAccount(resourceGroupName, storageAccountName) if err != nil { - return nil, err + return nil, accountExists, err + } + if accountExists == false { + return nil, false, nil } storageClient, err := mainStorage.NewBasicClient(storageAccountName, key) if err != nil { - return nil, fmt.Errorf("Error creating storage client for storage account %q: %s", storageAccountName, err) + return nil, true, fmt.Errorf("Error creating storage client for storage account %q: %s", storageAccountName, err) } blobClient := storageClient.GetBlobService() - return &blobClient, nil + return &blobClient, true, nil } -func (armClient *ArmClient) getQueueServiceClientForStorageAccount(resourceGroupName, storageAccountName string) (*mainStorage.QueueServiceClient, error) { - key, err := armClient.getKeyForStorageAccount(resourceGroupName, storageAccountName) +func (armClient *ArmClient) getQueueServiceClientForStorageAccount(resourceGroupName, storageAccountName string) (*mainStorage.QueueServiceClient, bool, error) { + key, accountExists, err := armClient.getKeyForStorageAccount(resourceGroupName, storageAccountName) if err != nil { - return nil, err + return nil, accountExists, err + } + if accountExists == false { + return nil, false, nil } storageClient, err := mainStorage.NewBasicClient(storageAccountName, key) if err != nil { - return nil, fmt.Errorf("Error creating storage client for storage account %q: %s", storageAccountName, err) + return nil, true, fmt.Errorf("Error creating storage client for storage account %q: %s", storageAccountName, err) } queueClient := storageClient.GetQueueService() - return &queueClient, nil + return &queueClient, true, nil } diff --git a/builtin/providers/azurerm/resource_arm_storage_blob.go b/builtin/providers/azurerm/resource_arm_storage_blob.go index 5e17d915a4d0..9889f4398a89 100644 --- a/builtin/providers/azurerm/resource_arm_storage_blob.go +++ b/builtin/providers/azurerm/resource_arm_storage_blob.go @@ -86,10 +86,13 @@ func resourceArmStorageBlobCreate(d *schema.ResourceData, meta interface{}) erro resourceGroupName := d.Get("resource_group_name").(string) storageAccountName := d.Get("storage_account_name").(string) - blobClient, err := armClient.getBlobStorageClientForStorageAccount(resourceGroupName, storageAccountName) + blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(resourceGroupName, storageAccountName) if err != nil { return err } + if !accountExists { + return fmt.Errorf("Storage Account %q Not Found", storageAccountName) + } name := d.Get("name").(string) blobType := d.Get("type").(string) @@ -117,10 +120,15 @@ func resourceArmStorageBlobRead(d *schema.ResourceData, meta interface{}) error resourceGroupName := d.Get("resource_group_name").(string) storageAccountName := d.Get("storage_account_name").(string) - blobClient, err := armClient.getBlobStorageClientForStorageAccount(resourceGroupName, storageAccountName) + blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(resourceGroupName, storageAccountName) if err != nil { return err } + if !accountExists { + log.Printf("[DEBUG] Storage account %q not found, removing blob %q from state", storageAccountName, d.Id()) + d.SetId("") + return nil + } exists, err := resourceArmStorageBlobExists(d, meta) if err != nil { @@ -150,10 +158,15 @@ func resourceArmStorageBlobExists(d *schema.ResourceData, meta interface{}) (boo resourceGroupName := d.Get("resource_group_name").(string) storageAccountName := d.Get("storage_account_name").(string) - blobClient, err := armClient.getBlobStorageClientForStorageAccount(resourceGroupName, storageAccountName) + blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(resourceGroupName, storageAccountName) if err != nil { return false, err } + if !accountExists { + log.Printf("[DEBUG] Storage account %q not found, removing blob %q from state", storageAccountName, d.Id()) + d.SetId("") + return false, nil + } name := d.Get("name").(string) storageContainerName := d.Get("storage_container_name").(string) @@ -178,10 +191,14 @@ func resourceArmStorageBlobDelete(d *schema.ResourceData, meta interface{}) erro resourceGroupName := d.Get("resource_group_name").(string) storageAccountName := d.Get("storage_account_name").(string) - blobClient, err := armClient.getBlobStorageClientForStorageAccount(resourceGroupName, storageAccountName) + blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(resourceGroupName, storageAccountName) if err != nil { return err } + if !accountExists { + log.Printf("[INFO]Storage Account %q doesn't exist so the blob won't exist", storageAccountName) + return nil + } name := d.Get("name").(string) storageContainerName := d.Get("storage_container_name").(string) diff --git a/builtin/providers/azurerm/resource_arm_storage_blob_test.go b/builtin/providers/azurerm/resource_arm_storage_blob_test.go index 57ef9af01ad6..bbea47d7abe4 100644 --- a/builtin/providers/azurerm/resource_arm_storage_blob_test.go +++ b/builtin/providers/azurerm/resource_arm_storage_blob_test.go @@ -120,10 +120,13 @@ func testCheckAzureRMStorageBlobExists(name string) resource.TestCheckFunc { } armClient := testAccProvider.Meta().(*ArmClient) - blobClient, err := armClient.getBlobStorageClientForStorageAccount(resourceGroup, storageAccountName) + blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(resourceGroup, storageAccountName) if err != nil { return err } + if !accountExists { + return fmt.Errorf("Bad: Storage Account %q does not exist", storageAccountName) + } exists, err := blobClient.BlobExists(storageContainerName, name) if err != nil { @@ -153,10 +156,13 @@ func testCheckAzureRMStorageBlobDestroy(s *terraform.State) error { } armClient := testAccProvider.Meta().(*ArmClient) - blobClient, err := armClient.getBlobStorageClientForStorageAccount(resourceGroup, storageAccountName) + blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(resourceGroup, storageAccountName) if err != nil { return nil } + if !accountExists { + return nil + } exists, err := blobClient.BlobExists(storageContainerName, name) if err != nil { diff --git a/builtin/providers/azurerm/resource_arm_storage_container.go b/builtin/providers/azurerm/resource_arm_storage_container.go index a87e44ec3562..da3a2b0be928 100644 --- a/builtin/providers/azurerm/resource_arm_storage_container.go +++ b/builtin/providers/azurerm/resource_arm_storage_container.go @@ -67,10 +67,13 @@ func resourceArmStorageContainerCreate(d *schema.ResourceData, meta interface{}) resourceGroupName := d.Get("resource_group_name").(string) storageAccountName := d.Get("storage_account_name").(string) - blobClient, err := armClient.getBlobStorageClientForStorageAccount(resourceGroupName, storageAccountName) + blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(resourceGroupName, storageAccountName) if err != nil { return err } + if !accountExists { + return fmt.Errorf("Storage Account %q Not Found", storageAccountName) + } name := d.Get("name").(string) @@ -99,10 +102,15 @@ func resourceArmStorageContainerRead(d *schema.ResourceData, meta interface{}) e resourceGroupName := d.Get("resource_group_name").(string) storageAccountName := d.Get("storage_account_name").(string) - blobClient, err := armClient.getBlobStorageClientForStorageAccount(resourceGroupName, storageAccountName) + blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(resourceGroupName, storageAccountName) if err != nil { return err } + if !accountExists { + log.Printf("[DEBUG] Storage account %q not found, removing container %q from state", storageAccountName, d.Id()) + d.SetId("") + return nil + } name := d.Get("name").(string) containers, err := blobClient.ListContainers(storage.ListContainersParameters{ @@ -142,10 +150,15 @@ func resourceArmStorageContainerExists(d *schema.ResourceData, meta interface{}) resourceGroupName := d.Get("resource_group_name").(string) storageAccountName := d.Get("storage_account_name").(string) - blobClient, err := armClient.getBlobStorageClientForStorageAccount(resourceGroupName, storageAccountName) + blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(resourceGroupName, storageAccountName) if err != nil { return false, err } + if !accountExists { + log.Printf("[DEBUG] Storage account %q not found, removing container %q from state", storageAccountName, d.Id()) + d.SetId("") + return false, nil + } name := d.Get("name").(string) @@ -171,10 +184,14 @@ func resourceArmStorageContainerDelete(d *schema.ResourceData, meta interface{}) resourceGroupName := d.Get("resource_group_name").(string) storageAccountName := d.Get("storage_account_name").(string) - blobClient, err := armClient.getBlobStorageClientForStorageAccount(resourceGroupName, storageAccountName) + blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(resourceGroupName, storageAccountName) if err != nil { return err } + if !accountExists { + log.Printf("[INFO]Storage Account %q doesn't exist so the container won't exist", storageAccountName) + return nil + } name := d.Get("name").(string) diff --git a/builtin/providers/azurerm/resource_arm_storage_container_test.go b/builtin/providers/azurerm/resource_arm_storage_container_test.go index cd6dcb07d994..0bdc5f8c3875 100644 --- a/builtin/providers/azurerm/resource_arm_storage_container_test.go +++ b/builtin/providers/azurerm/resource_arm_storage_container_test.go @@ -2,6 +2,7 @@ package azurerm import ( "fmt" + "log" "strings" "testing" @@ -12,6 +13,8 @@ import ( ) func TestAccAzureRMStorageContainer_basic(t *testing.T) { + var c storage.Container + ri := acctest.RandInt() rs := strings.ToLower(acctest.RandString(11)) config := fmt.Sprintf(testAccAzureRMStorageContainer_basic, ri, rs) @@ -24,14 +27,38 @@ func TestAccAzureRMStorageContainer_basic(t *testing.T) { resource.TestStep{ Config: config, Check: resource.ComposeTestCheckFunc( - testCheckAzureRMStorageContainerExists("azurerm_storage_container.test"), + testCheckAzureRMStorageContainerExists("azurerm_storage_container.test", &c), ), }, }, }) } -func testCheckAzureRMStorageContainerExists(name string) resource.TestCheckFunc { +func TestAccAzureRMStorageContainer_disappears(t *testing.T) { + var c storage.Container + + ri := acctest.RandInt() + rs := strings.ToLower(acctest.RandString(11)) + config := fmt.Sprintf(testAccAzureRMStorageContainer_basic, ri, rs) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageContainerDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageContainerExists("azurerm_storage_container.test", &c), + testAccARMStorageContainerDisappears("azurerm_storage_container.test", &c), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testCheckAzureRMStorageContainerExists(name string, c *storage.Container) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[name] @@ -47,10 +74,13 @@ func testCheckAzureRMStorageContainerExists(name string) resource.TestCheckFunc } armClient := testAccProvider.Meta().(*ArmClient) - blobClient, err := armClient.getBlobStorageClientForStorageAccount(resourceGroup, storageAccountName) + blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(resourceGroup, storageAccountName) if err != nil { return err } + if !accountExists { + return fmt.Errorf("Bad: Storage Account %q does not exist", storageAccountName) + } containers, err := blobClient.ListContainers(storage.ListContainersParameters{ Prefix: name, @@ -65,6 +95,7 @@ func testCheckAzureRMStorageContainerExists(name string) resource.TestCheckFunc for _, container := range containers.Containers { if container.Name == name { found = true + *c = container } } @@ -76,6 +107,39 @@ func testCheckAzureRMStorageContainerExists(name string) resource.TestCheckFunc } } +func testAccARMStorageContainerDisappears(name string, c *storage.Container) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + armClient := testAccProvider.Meta().(*ArmClient) + + storageAccountName := rs.Primary.Attributes["storage_account_name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for storage container: %s", c.Name) + } + + blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(resourceGroup, storageAccountName) + if err != nil { + return err + } + if !accountExists { + log.Printf("[INFO]Storage Account %q doesn't exist so the container won't exist", storageAccountName) + return nil + } + + _, err = blobClient.DeleteContainerIfExists(c.Name) + if err != nil { + return err + } + + return nil + } +} + func testCheckAzureRMStorageContainerDestroy(s *terraform.State) error { for _, rs := range s.RootModule().Resources { if rs.Type != "azurerm_storage_container" { @@ -90,11 +154,14 @@ func testCheckAzureRMStorageContainerDestroy(s *terraform.State) error { } armClient := testAccProvider.Meta().(*ArmClient) - blobClient, err := armClient.getBlobStorageClientForStorageAccount(resourceGroup, storageAccountName) + blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(resourceGroup, storageAccountName) if err != nil { //If we can't get keys then the blob can't exist return nil } + if !accountExists { + return nil + } containers, err := blobClient.ListContainers(storage.ListContainersParameters{ Prefix: name, diff --git a/builtin/providers/azurerm/resource_arm_storage_queue.go b/builtin/providers/azurerm/resource_arm_storage_queue.go index 9488395bc152..f1bd4e644dd0 100644 --- a/builtin/providers/azurerm/resource_arm_storage_queue.go +++ b/builtin/providers/azurerm/resource_arm_storage_queue.go @@ -71,10 +71,13 @@ func resourceArmStorageQueueCreate(d *schema.ResourceData, meta interface{}) err resourceGroupName := d.Get("resource_group_name").(string) storageAccountName := d.Get("storage_account_name").(string) - queueClient, err := armClient.getQueueServiceClientForStorageAccount(resourceGroupName, storageAccountName) + queueClient, accountExists, err := armClient.getQueueServiceClientForStorageAccount(resourceGroupName, storageAccountName) if err != nil { return err } + if !accountExists { + return fmt.Errorf("Storage Account %q Not Found", storageAccountName) + } name := d.Get("name").(string) @@ -109,10 +112,15 @@ func resourceArmStorageQueueExists(d *schema.ResourceData, meta interface{}) (bo resourceGroupName := d.Get("resource_group_name").(string) storageAccountName := d.Get("storage_account_name").(string) - queueClient, err := armClient.getQueueServiceClientForStorageAccount(resourceGroupName, storageAccountName) + queueClient, accountExists, err := armClient.getQueueServiceClientForStorageAccount(resourceGroupName, storageAccountName) if err != nil { return false, err } + if !accountExists { + log.Printf("[DEBUG] Storage account %q not found, removing queue %q from state", storageAccountName, d.Id()) + d.SetId("") + return false, nil + } name := d.Get("name").(string) @@ -136,10 +144,14 @@ func resourceArmStorageQueueDelete(d *schema.ResourceData, meta interface{}) err resourceGroupName := d.Get("resource_group_name").(string) storageAccountName := d.Get("storage_account_name").(string) - queueClient, err := armClient.getQueueServiceClientForStorageAccount(resourceGroupName, storageAccountName) + queueClient, accountExists, err := armClient.getQueueServiceClientForStorageAccount(resourceGroupName, storageAccountName) if err != nil { return err } + if !accountExists { + log.Printf("[INFO]Storage Account %q doesn't exist so the blob won't exist", storageAccountName) + return nil + } name := d.Get("name").(string) diff --git a/builtin/providers/azurerm/resource_arm_storage_queue_test.go b/builtin/providers/azurerm/resource_arm_storage_queue_test.go index cba82de61cc0..a71f6e5a7080 100644 --- a/builtin/providers/azurerm/resource_arm_storage_queue_test.go +++ b/builtin/providers/azurerm/resource_arm_storage_queue_test.go @@ -87,10 +87,13 @@ func testCheckAzureRMStorageQueueExists(name string) resource.TestCheckFunc { } armClient := testAccProvider.Meta().(*ArmClient) - queueClient, err := armClient.getQueueServiceClientForStorageAccount(resourceGroup, storageAccountName) + queueClient, accountExists, err := armClient.getQueueServiceClientForStorageAccount(resourceGroup, storageAccountName) if err != nil { return err } + if !accountExists { + return fmt.Errorf("Bad: Storage Account %q does not exist", storageAccountName) + } exists, err := queueClient.QueueExists(name) if err != nil { @@ -119,10 +122,13 @@ func testCheckAzureRMStorageQueueDestroy(s *terraform.State) error { } armClient := testAccProvider.Meta().(*ArmClient) - queueClient, err := armClient.getQueueServiceClientForStorageAccount(resourceGroup, storageAccountName) + queueClient, accountExists, err := armClient.getQueueServiceClientForStorageAccount(resourceGroup, storageAccountName) if err != nil { return nil } + if !accountExists { + return nil + } exists, err := queueClient.QueueExists(name) if err != nil {