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
This commit is contained in:
Peter McAtominey 2016-10-17 17:49:07 +01:00
parent f86198c155
commit 89b49f809b
3 changed files with 139 additions and 0 deletions

View File

@ -12,12 +12,15 @@ import (
"github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/signalwrapper" "github.com/hashicorp/terraform/helper/signalwrapper"
"github.com/hashicorp/terraform/helper/validation"
) )
// The KeySource of storage.Encryption appears to require this value // The KeySource of storage.Encryption appears to require this value
// for Encryption services to work // for Encryption services to work
var storageAccountEncryptionSource = "Microsoft.Storage" var storageAccountEncryptionSource = "Microsoft.Storage"
const blobStorageAccountDefaultAccessTier = "Hot"
func resourceArmStorageAccount() *schema.Resource { func resourceArmStorageAccount() *schema.Resource {
return &schema.Resource{ return &schema.Resource{
Create: resourceArmStorageAccountCreate, Create: resourceArmStorageAccountCreate,
@ -50,12 +53,34 @@ func resourceArmStorageAccount() *schema.Resource {
StateFunc: azureRMNormalizeLocation, 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": { "account_type": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
ValidateFunc: validateArmStorageAccountType, 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": { "enable_blob_encryption": {
Type: schema.TypeBool, Type: schema.TypeBool,
Optional: true, Optional: true,
@ -128,7 +153,9 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e
resourceGroupName := d.Get("resource_group_name").(string) resourceGroupName := d.Get("resource_group_name").(string)
storageAccountName := d.Get("name").(string) storageAccountName := d.Get("name").(string)
accountKind := d.Get("account_kind").(string)
accountType := d.Get("account_type").(string) accountType := d.Get("account_type").(string)
location := d.Get("location").(string) location := d.Get("location").(string)
tags := d.Get("tags").(map[string]interface{}) tags := d.Get("tags").(map[string]interface{})
enableBlobEncryption := d.Get("enable_blob_encryption").(bool) enableBlobEncryption := d.Get("enable_blob_encryption").(bool)
@ -141,6 +168,7 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e
Location: &location, Location: &location,
Sku: &sku, Sku: &sku,
Tags: expandTags(tags), Tags: expandTags(tags),
Kind: storage.Kind(accountKind),
Properties: &storage.AccountPropertiesCreateParameters{ Properties: &storage.AccountPropertiesCreateParameters{
Encryption: &storage.Encryption{ Encryption: &storage.Encryption{
Services: &storage.EncryptionServices{ 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 // Create the storage account. We wrap this so that it is cancellable
// with a Ctrl-C since this can take a LONG time. // with a Ctrl-C since this can take a LONG time.
wrap := signalwrapper.Run(func(cancelCh <-chan struct{}) error { wrap := signalwrapper.Run(func(cancelCh <-chan struct{}) error {
@ -247,6 +286,22 @@ func resourceArmStorageAccountUpdate(d *schema.ResourceData, meta interface{}) e
d.SetPartial("account_type") 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") { if d.HasChange("tags") {
tags := d.Get("tags").(map[string]interface{}) 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("primary_access_key", accessKeys[0].Value)
d.Set("secondary_access_key", accessKeys[1].Value) d.Set("secondary_access_key", accessKeys[1].Value)
d.Set("location", resp.Location) d.Set("location", resp.Location)
d.Set("account_kind", resp.Kind)
d.Set("account_type", resp.Sku.Name) d.Set("account_type", resp.Sku.Name)
d.Set("primary_location", resp.Properties.PrimaryLocation) d.Set("primary_location", resp.Properties.PrimaryLocation)
d.Set("secondary_location", resp.Properties.SecondaryLocation) d.Set("secondary_location", resp.Properties.SecondaryLocation)
if resp.Properties.AccessTier != "" {
d.Set("access_tier", resp.Properties.AccessTier)
}
if resp.Properties.PrimaryEndpoints != nil { if resp.Properties.PrimaryEndpoints != nil {
d.Set("primary_blob_endpoint", resp.Properties.PrimaryEndpoints.Blob) d.Set("primary_blob_endpoint", resp.Properties.PrimaryEndpoints.Blob)
d.Set("primary_queue_endpoint", resp.Properties.PrimaryEndpoints.Queue) d.Set("primary_queue_endpoint", resp.Properties.PrimaryEndpoints.Queue)

View File

@ -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 { func testCheckAzureRMStorageAccountExists(name string) resource.TestCheckFunc {
return func(s *terraform.State) error { return func(s *terraform.State) error {
// Ensure we have enough information in state to look up in API // Ensure we have enough information in state to look up in API
@ -286,3 +317,43 @@ resource "azurerm_storage_account" "testsa" {
environment = "production" 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"
}
}`

View File

@ -45,12 +45,20 @@ The following arguments are supported:
* `location` - (Required) Specifies the supported Azure location where the * `location` - (Required) Specifies the supported Azure location where the
resource exists. Changing this forces a new resource to be created. 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 * `account_type` - (Required) Defines the type of storage account to be
created. Valid options are `Standard_LRS`, `Standard_ZRS`, `Standard_GRS`, created. Valid options are `Standard_LRS`, `Standard_ZRS`, `Standard_GRS`,
`Standard_RAGRS`, `Premium_LRS`. Changing this is sometimes valid - see the Azure `Standard_RAGRS`, `Premium_LRS`. Changing this is sometimes valid - see the Azure
documentation for more information on which types of accounts can be converted documentation for more information on which types of accounts can be converted
into other types. 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 * `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/) Services are enabled for Blob storage, see [here](https://azure.microsoft.com/en-us/documentation/articles/storage-service-encryption/)
for more information. for more information.