From 89b49f809bb785a1f859f64212e391bc687f0e02 Mon Sep 17 00:00:00 2001 From: Peter McAtominey Date: Mon, 17 Oct 2016 17:49:07 +0100 Subject: [PATCH] provider/azurerm: add account_kind and access_tier to storage_account resource TF_ACC=1 go test ./builtin/providers/azurerm -v -run TestAccAzureRMStorageAccount -timeout 120m === RUN TestAccAzureRMStorageAccount_importBasic --- PASS: TestAccAzureRMStorageAccount_importBasic (140.06s) === RUN TestAccAzureRMStorageAccount_basic --- PASS: TestAccAzureRMStorageAccount_basic (155.43s) === RUN TestAccAzureRMStorageAccount_disappears --- PASS: TestAccAzureRMStorageAccount_disappears (134.99s) === RUN TestAccAzureRMStorageAccount_blobEncryption --- PASS: TestAccAzureRMStorageAccount_blobEncryption (161.59s) === RUN TestAccAzureRMStorageAccount_blobStorageWithUpdate --- PASS: TestAccAzureRMStorageAccount_blobStorageWithUpdate (131.49s) PASS ok github.com/hashicorp/terraform/builtin/providers/azurerm 723.694s --- .../azurerm/resource_arm_storage_account.go | 60 ++++++++++++++++ .../resource_arm_storage_account_test.go | 71 +++++++++++++++++++ .../azurerm/r/storage_account.html.markdown | 8 +++ 3 files changed, 139 insertions(+) diff --git a/builtin/providers/azurerm/resource_arm_storage_account.go b/builtin/providers/azurerm/resource_arm_storage_account.go index 5c1f9b9b9..e31f3a0db 100644 --- a/builtin/providers/azurerm/resource_arm_storage_account.go +++ b/builtin/providers/azurerm/resource_arm_storage_account.go @@ -12,12 +12,15 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/signalwrapper" + "github.com/hashicorp/terraform/helper/validation" ) // The KeySource of storage.Encryption appears to require this value // for Encryption services to work var storageAccountEncryptionSource = "Microsoft.Storage" +const blobStorageAccountDefaultAccessTier = "Hot" + func resourceArmStorageAccount() *schema.Resource { return &schema.Resource{ Create: resourceArmStorageAccountCreate, @@ -50,12 +53,34 @@ func resourceArmStorageAccount() *schema.Resource { StateFunc: azureRMNormalizeLocation, }, + "account_kind": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + string(storage.Storage), + string(storage.BlobStorage), + }, true), + Default: string(storage.Storage), + }, + "account_type": { Type: schema.TypeString, Required: true, ValidateFunc: validateArmStorageAccountType, }, + // Only valid for BlobStorage accounts, defaults to "Hot" in create function + "access_tier": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{ + string(storage.Cool), + string(storage.Hot), + }, true), + }, + "enable_blob_encryption": { Type: schema.TypeBool, Optional: true, @@ -128,7 +153,9 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e resourceGroupName := d.Get("resource_group_name").(string) storageAccountName := d.Get("name").(string) + accountKind := d.Get("account_kind").(string) accountType := d.Get("account_type").(string) + location := d.Get("location").(string) tags := d.Get("tags").(map[string]interface{}) enableBlobEncryption := d.Get("enable_blob_encryption").(bool) @@ -141,6 +168,7 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e Location: &location, Sku: &sku, Tags: expandTags(tags), + Kind: storage.Kind(accountKind), Properties: &storage.AccountPropertiesCreateParameters{ Encryption: &storage.Encryption{ Services: &storage.EncryptionServices{ @@ -153,6 +181,17 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e }, } + // AccessTier is only valid for BlobStorage accounts + if accountKind == string(storage.BlobStorage) { + accessTier, ok := d.GetOk("access_tier") + if !ok { + // default to "Hot" + accessTier = blobStorageAccountDefaultAccessTier + } + + opts.Properties.AccessTier = storage.AccessTier(accessTier.(string)) + } + // Create the storage account. We wrap this so that it is cancellable // with a Ctrl-C since this can take a LONG time. wrap := signalwrapper.Run(func(cancelCh <-chan struct{}) error { @@ -247,6 +286,22 @@ func resourceArmStorageAccountUpdate(d *schema.ResourceData, meta interface{}) e d.SetPartial("account_type") } + if d.HasChange("access_tier") { + accessTier := d.Get("access_tier").(string) + + opts := storage.AccountUpdateParameters{ + Properties: &storage.AccountPropertiesUpdateParameters{ + AccessTier: storage.AccessTier(accessTier), + }, + } + _, err := client.Update(resourceGroupName, storageAccountName, opts) + if err != nil { + return fmt.Errorf("Error updating Azure Storage Account access_tier %q: %s", storageAccountName, err) + } + + d.SetPartial("access_tier") + } + if d.HasChange("tags") { tags := d.Get("tags").(map[string]interface{}) @@ -317,10 +372,15 @@ func resourceArmStorageAccountRead(d *schema.ResourceData, meta interface{}) err d.Set("primary_access_key", accessKeys[0].Value) d.Set("secondary_access_key", accessKeys[1].Value) d.Set("location", resp.Location) + d.Set("account_kind", resp.Kind) d.Set("account_type", resp.Sku.Name) d.Set("primary_location", resp.Properties.PrimaryLocation) d.Set("secondary_location", resp.Properties.SecondaryLocation) + if resp.Properties.AccessTier != "" { + d.Set("access_tier", resp.Properties.AccessTier) + } + if resp.Properties.PrimaryEndpoints != nil { d.Set("primary_blob_endpoint", resp.Properties.PrimaryEndpoints.Blob) d.Set("primary_queue_endpoint", resp.Properties.PrimaryEndpoints.Queue) diff --git a/builtin/providers/azurerm/resource_arm_storage_account_test.go b/builtin/providers/azurerm/resource_arm_storage_account_test.go index 96ad286a6..a29074766 100644 --- a/builtin/providers/azurerm/resource_arm_storage_account_test.go +++ b/builtin/providers/azurerm/resource_arm_storage_account_test.go @@ -139,6 +139,37 @@ func TestAccAzureRMStorageAccount_blobEncryption(t *testing.T) { }) } +func TestAccAzureRMStorageAccount_blobStorageWithUpdate(t *testing.T) { + ri := acctest.RandInt() + rs := acctest.RandString(4) + preConfig := fmt.Sprintf(testAccAzureRMStorageAccount_blobStorage, ri, rs) + postConfig := fmt.Sprintf(testAccAzureRMStorageAccount_blobStorageUpdate, ri, rs) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageAccountDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageAccountExists("azurerm_storage_account.testsa"), + resource.TestCheckResourceAttr("azurerm_storage_account.testsa", "account_kind", "BlobStorage"), + resource.TestCheckResourceAttr("azurerm_storage_account.testsa", "access_tier", "Hot"), + ), + }, + + resource.TestStep{ + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageAccountExists("azurerm_storage_account.testsa"), + resource.TestCheckResourceAttr("azurerm_storage_account.testsa", "access_tier", "Cool"), + ), + }, + }, + }) +} + func testCheckAzureRMStorageAccountExists(name string) resource.TestCheckFunc { return func(s *terraform.State) error { // Ensure we have enough information in state to look up in API @@ -286,3 +317,43 @@ resource "azurerm_storage_account" "testsa" { environment = "production" } }` + +// BlobStorage accounts are not available in WestUS +var testAccAzureRMStorageAccount_blobStorage = ` +resource "azurerm_resource_group" "testrg" { + name = "testAccAzureRMSA-%d" + location = "northeurope" +} + +resource "azurerm_storage_account" "testsa" { + name = "unlikely23exst2acct%s" + resource_group_name = "${azurerm_resource_group.testrg.name}" + + location = "northeurope" + account_kind = "BlobStorage" + account_type = "Standard_LRS" + + tags { + environment = "production" + } +}` + +var testAccAzureRMStorageAccount_blobStorageUpdate = ` +resource "azurerm_resource_group" "testrg" { + name = "testAccAzureRMSA-%d" + location = "northeurope" +} + +resource "azurerm_storage_account" "testsa" { + name = "unlikely23exst2acct%s" + resource_group_name = "${azurerm_resource_group.testrg.name}" + + location = "northeurope" + account_kind = "BlobStorage" + account_type = "Standard_LRS" + access_tier = "Cool" + + tags { + environment = "production" + } +}` diff --git a/website/source/docs/providers/azurerm/r/storage_account.html.markdown b/website/source/docs/providers/azurerm/r/storage_account.html.markdown index 015fdd34e..8f8cd9cb4 100644 --- a/website/source/docs/providers/azurerm/r/storage_account.html.markdown +++ b/website/source/docs/providers/azurerm/r/storage_account.html.markdown @@ -45,12 +45,20 @@ The following arguments are supported: * `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. +* `account_kind` - (Optional) Defines the Kind of account. Valid options are `Storage` + and `BlobStorage`. Changing this forces a new resource to be created. Defaults + to `Storage`. + * `account_type` - (Required) Defines the type of storage account to be created. Valid options are `Standard_LRS`, `Standard_ZRS`, `Standard_GRS`, `Standard_RAGRS`, `Premium_LRS`. Changing this is sometimes valid - see the Azure documentation for more information on which types of accounts can be converted into other types. +* `access_tier` - (Required for `BlobStorage` accounts) Defines the access tier + for `BlobStorage` accounts. Valid options are `Hot` and `Cold`, defaults to + `Hot`. + * `enable_bool_encryption` - (Optional) Boolean flag which controls if Encryption Services are enabled for Blob storage, see [here](https://azure.microsoft.com/en-us/documentation/articles/storage-service-encryption/) for more information.