diff --git a/builtin/providers/azurerm/resource_arm_storage_account.go b/builtin/providers/azurerm/resource_arm_storage_account.go index fadfd075a..a510f33b0 100644 --- a/builtin/providers/azurerm/resource_arm_storage_account.go +++ b/builtin/providers/azurerm/resource_arm_storage_account.go @@ -14,6 +14,10 @@ import ( "github.com/hashicorp/terraform/helper/signalwrapper" ) +// The KeySource of storage.Encryption appears to require this value +// for Encryption services to work +var storageAccountEncryptionSource = "Microsoft.Storage" + func resourceArmStorageAccount() *schema.Resource { return &schema.Resource{ Create: resourceArmStorageAccountCreate, @@ -51,6 +55,11 @@ func resourceArmStorageAccount() *schema.Resource { ValidateFunc: validateArmStorageAccountType, }, + "enable_blob_encryption": { + Type: schema.TypeBool, + Optional: true, + }, + "primary_location": { Type: schema.TypeString, Computed: true, @@ -121,6 +130,7 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e 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) sku := storage.Sku{ Name: storage.SkuName(accountType), @@ -130,6 +140,16 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e Location: &location, Sku: &sku, Tags: expandTags(tags), + Properties: &storage.AccountPropertiesCreateParameters{ + Encryption: &storage.Encryption{ + Services: &storage.EncryptionServices{ + Blob: &storage.EncryptionService{ + Enabled: &enableBlobEncryption, + }, + }, + KeySource: &storageAccountEncryptionSource, + }, + }, } // Create the storage account. We wrap this so that it is cancellable @@ -240,6 +260,29 @@ func resourceArmStorageAccountUpdate(d *schema.ResourceData, meta interface{}) e d.SetPartial("tags") } + if d.HasChange("enable_blob_encryption") { + enableBlobEncryption := d.Get("enable_blob_encryption").(bool) + + opts := storage.AccountUpdateParameters{ + Properties: &storage.AccountPropertiesUpdateParameters{ + Encryption: &storage.Encryption{ + Services: &storage.EncryptionServices{ + Blob: &storage.EncryptionService{ + Enabled: &enableBlobEncryption, + }, + }, + KeySource: &storageAccountEncryptionSource, + }, + }, + } + _, err := client.Update(resourceGroupName, storageAccountName, opts) + if err != nil { + return fmt.Errorf("Error updating Azure Storage Account enable_blob_encryption %q: %s", storageAccountName, err) + } + + d.SetPartial("enable_blob_encryption") + } + d.Partial(false) return nil } @@ -301,6 +344,12 @@ func resourceArmStorageAccountRead(d *schema.ResourceData, meta interface{}) err } } + if resp.Properties.Encryption != nil { + if resp.Properties.Encryption.Services.Blob != nil { + d.Set("enable_blob_encryption", resp.Properties.Encryption.Services.Blob.Enabled) + } + } + d.Set("name", resp.Name) flattenAndSetTags(d, resp.Tags) diff --git a/builtin/providers/azurerm/resource_arm_storage_account_test.go b/builtin/providers/azurerm/resource_arm_storage_account_test.go index 156734dc8..96ad286a6 100644 --- a/builtin/providers/azurerm/resource_arm_storage_account_test.go +++ b/builtin/providers/azurerm/resource_arm_storage_account_test.go @@ -109,6 +109,36 @@ func TestAccAzureRMStorageAccount_disappears(t *testing.T) { }) } +func TestAccAzureRMStorageAccount_blobEncryption(t *testing.T) { + ri := acctest.RandInt() + rs := acctest.RandString(4) + preConfig := fmt.Sprintf(testAccAzureRMStorageAccount_blobEncryption, ri, rs) + postConfig := fmt.Sprintf(testAccAzureRMStorageAccount_blobEncryptionDisabled, 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", "enable_blob_encryption", "true"), + ), + }, + + resource.TestStep{ + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageAccountExists("azurerm_storage_account.testsa"), + resource.TestCheckResourceAttr("azurerm_storage_account.testsa", "enable_blob_encryption", "false"), + ), + }, + }, + }) +} + func testCheckAzureRMStorageAccountExists(name string) resource.TestCheckFunc { return func(s *terraform.State) error { // Ensure we have enough information in state to look up in API @@ -218,3 +248,41 @@ resource "azurerm_storage_account" "testsa" { environment = "staging" } }` + +var testAccAzureRMStorageAccount_blobEncryption = ` +resource "azurerm_resource_group" "testrg" { + name = "testAccAzureRMSA-%d" + location = "westus" +} + +resource "azurerm_storage_account" "testsa" { + name = "unlikely23exst2acct%s" + resource_group_name = "${azurerm_resource_group.testrg.name}" + + location = "westus" + account_type = "Standard_LRS" + enable_blob_encryption = true + + tags { + environment = "production" + } +}` + +var testAccAzureRMStorageAccount_blobEncryptionDisabled = ` +resource "azurerm_resource_group" "testrg" { + name = "testAccAzureRMSA-%d" + location = "westus" +} + +resource "azurerm_storage_account" "testsa" { + name = "unlikely23exst2acct%s" + resource_group_name = "${azurerm_resource_group.testrg.name}" + + location = "westus" + account_type = "Standard_LRS" + enable_blob_encryption = false + + 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 5fe2c38bc..015fdd34e 100644 --- a/website/source/docs/providers/azurerm/r/storage_account.html.markdown +++ b/website/source/docs/providers/azurerm/r/storage_account.html.markdown @@ -51,6 +51,10 @@ The following arguments are supported: documentation for more information on which types of accounts can be converted into other types. +* `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. + * `tags` - (Optional) A mapping of tags to assign to the resource. Note that although the Azure API supports setting custom domain names for