From 65df0916082fc3d79d1f5b3f9b78829174cd302e Mon Sep 17 00:00:00 2001 From: Liem Phan Date: Tue, 9 Oct 2018 23:35:08 +0100 Subject: [PATCH 01/16] Add storage account key vault properties * Add key_vault_properties optional parameter to storage account. * Add test for storage account with custom key for SSE. * Update docs. --- azurerm/resource_arm_storage_account.go | 90 ++++++++++- azurerm/resource_arm_storage_account_test.go | 160 +++++++++++++++++-- website/docs/r/storage_account.html.markdown | 10 ++ 3 files changed, 244 insertions(+), 16 deletions(-) diff --git a/azurerm/resource_arm_storage_account.go b/azurerm/resource_arm_storage_account.go index b1740bcc0714..0ab0e21321a3 100644 --- a/azurerm/resource_arm_storage_account.go +++ b/azurerm/resource_arm_storage_account.go @@ -106,6 +106,28 @@ func resourceArmStorageAccount() *schema.Resource { DiffSuppressFunc: ignoreCaseDiffSuppressFunc, }, + "key_vault_properties": { + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key_name": { + Type: schema.TypeString, + Required: true, + }, + "key_version": { + Type: schema.TypeString, + Required: true, + }, + "key_vault_uri": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "custom_domain": { Type: schema.TypeList, Optional: true, @@ -341,6 +363,7 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e storageAccountEncryptionSource := d.Get("account_encryption_source").(string) networkRules := expandStorageAccountNetworkRules(d) + keyVaultProperties := expandAzureRmStorageAccountKeyVaultProperties(d) parameters := storage.AccountCreateParameters{ Location: &location, @@ -358,7 +381,8 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e File: &storage.EncryptionService{ Enabled: utils.Bool(enableFileEncryption), }}, - KeySource: storage.KeySource(storageAccountEncryptionSource), + KeySource: storage.KeySource(storageAccountEncryptionSource), + KeyVaultProperties: keyVaultProperties, }, EnableHTTPSTrafficOnly: &enableHTTPSTrafficOnly, NetworkRuleSet: networkRules, @@ -585,6 +609,27 @@ func resourceArmStorageAccountUpdate(d *schema.ResourceData, meta interface{}) e d.SetPartial("network_rules") } + if d.HasChange("account_encryption_source") { + accountEncryptionSource := d.Get("account_encryption_source").(string) + keyVaultProperties := expandAzureRmStorageAccountKeyVaultProperties(d) + opts := storage.AccountUpdateParameters{ + AccountPropertiesUpdateParameters: &storage.AccountPropertiesUpdateParameters{ + Encryption: &storage.Encryption{ + KeySource: storage.KeySource(accountEncryptionSource), + KeyVaultProperties: keyVaultProperties, + }, + }, + } + + _, err := client.Update(ctx, resourceGroupName, storageAccountName, opts) + if err != nil { + return fmt.Errorf("Error updating Azure Storage Account account_encryption_source and key_vault_properties %q: %+v", storageAccountName, err) + } + + d.SetPartial("account_encryption_source") + d.SetPartial("key_vault_properties") + } + d.Partial(false) return resourceArmStorageAccountRead(d, meta) } @@ -649,6 +694,12 @@ func resourceArmStorageAccountRead(d *schema.ResourceData, meta interface{}) err } } d.Set("account_encryption_source", string(encryption.KeySource)) + + if keyVaultProperties := encryption.KeyVaultProperties; keyVaultProperties != nil { + if err := d.Set("key_vault_properties", flattenAzureRmStorageAccountKeyVaultProperties(keyVaultProperties)); err != nil { + return fmt.Errorf("Error flattening `key_vault_properties`: %+v", err) + } + } } // Computed @@ -928,3 +979,40 @@ func flattenAzureRmStorageAccountIdentity(identity *storage.Identity) []interfac return []interface{}{result} } + +func expandAzureRmStorageAccountKeyVaultProperties(d *schema.ResourceData) *storage.KeyVaultProperties { + vs := d.Get("key_vault_properties").([]interface{}) + if vs == nil || len(vs) == 0 { + return &storage.KeyVaultProperties{} + } + + v := vs[0].(map[string]interface{}) + keyName := v["key_name"].(string) + keyVersion := v["key_version"].(string) + keyVaultURI := v["key_vault_uri"].(string) + + return &storage.KeyVaultProperties{ + KeyName: utils.String(keyName), + KeyVersion: utils.String(keyVersion), + KeyVaultURI: utils.String(keyVaultURI), + } +} + +func flattenAzureRmStorageAccountKeyVaultProperties(keyVaultProperties *storage.KeyVaultProperties) []interface{} { + if keyVaultProperties == nil { + return make([]interface{}, 0) + } + + result := make(map[string]interface{}) + if keyVaultProperties.KeyName != nil { + result["key_name"] = *keyVaultProperties.KeyName + } + if keyVaultProperties.KeyVersion != nil { + result["key_version"] = *keyVaultProperties.KeyVersion + } + if keyVaultProperties.KeyVaultURI != nil { + result["key_vault_uri"] = *keyVaultProperties.KeyVaultURI + } + + return []interface{}{result} +} diff --git a/azurerm/resource_arm_storage_account_test.go b/azurerm/resource_arm_storage_account_test.go index 3b8a167f275b..46ed889888b7 100644 --- a/azurerm/resource_arm_storage_account_test.go +++ b/azurerm/resource_arm_storage_account_test.go @@ -475,6 +475,41 @@ func TestAccAzureRMStorageAccount_networkRulesDeleted(t *testing.T) { }) } +func TestAccAzureRMStorageAccount_keyVault(t *testing.T) { + resourceName := "azurerm_storage_account.testsa" + ri := acctest.RandInt() + rs := acctest.RandString(4) + location := testLocation() + preConfig := testAccAzureRMStorageAccount_identity(ri, rs, location) + postConfig := testAccAzureRMStorageAccount_keyvault(ri, rs, location) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageAccountDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageAccountExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "account_encryption_source", "Microsoft.Storage"), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageAccountExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "account_encryption_source", "Microsoft.KeyVault"), + resource.TestCheckResourceAttr(resourceName, "key_vault_properties.#", "1"), + resource.TestCheckResourceAttrSet(resourceName, "key_vault_properties.0.key_name"), + resource.TestCheckResourceAttrSet(resourceName, "key_vault_properties.0.key_version"), + resource.TestCheckResourceAttrSet(resourceName, "key_vault_properties.0.key_vault_uri"), + ), + }, + }, + }) +} + func testCheckAzureRMStorageAccountExists(name string) resource.TestCheckFunc { return func(s *terraform.State) error { // Ensure we have enough information in state to look up in API @@ -884,9 +919,9 @@ resource "azurerm_storage_account" "testsa" { account_tier = "Standard" account_replication_type = "LRS" - identity { - type = "SystemAssigned" - } + identity { + type = "SystemAssigned" + } tags { environment = "production" @@ -908,11 +943,11 @@ resource "azurerm_virtual_network" "test" { resource_group_name = "${azurerm_resource_group.testrg.name}" } resource "azurerm_subnet" "test" { - name = "acctestsubnet%d" - resource_group_name = "${azurerm_resource_group.testrg.name}" - virtual_network_name = "${azurerm_virtual_network.test.name}" - address_prefix = "10.0.2.0/24" - service_endpoints = ["Microsoft.Storage"] + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.testrg.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" + service_endpoints = ["Microsoft.Storage"] } resource "azurerm_storage_account" "testsa" { name = "unlikely23exst2acct%s" @@ -920,7 +955,7 @@ resource "azurerm_storage_account" "testsa" { location = "${azurerm_resource_group.testrg.location}" account_tier = "Standard" account_replication_type = "LRS" - + network_rules { ip_rules = ["127.0.0.1"] virtual_network_subnet_ids = ["${azurerm_subnet.test.id}"] @@ -945,11 +980,11 @@ resource "azurerm_virtual_network" "test" { resource_group_name = "${azurerm_resource_group.testrg.name}" } resource "azurerm_subnet" "test" { - name = "acctestsubnet%d" - resource_group_name = "${azurerm_resource_group.testrg.name}" - virtual_network_name = "${azurerm_virtual_network.test.name}" - address_prefix = "10.0.2.0/24" - service_endpoints = ["Microsoft.Storage"] + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.testrg.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" + service_endpoints = ["Microsoft.Storage"] } resource "azurerm_storage_account" "testsa" { name = "unlikely23exst2acct%s" @@ -957,7 +992,7 @@ resource "azurerm_storage_account" "testsa" { location = "${azurerm_resource_group.testrg.location}" account_tier = "Standard" account_replication_type = "LRS" - + network_rules { ip_rules = ["127.0.0.1", "127.0.0.2"] bypass = ["Logging", "Metrics"] @@ -968,3 +1003,98 @@ resource "azurerm_storage_account" "testsa" { } `, rInt, location, rInt, rInt, rString) } + +func testAccAzureRMStorageAccount_keyvault(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "testrg" { + name = "testAccAzureRMSA-%d" + location = "%s" +} + +data "azurerm_client_config" "current" {} + +resource "azurerm_key_vault" "test" { + name = "testAccKv-%s" + location = "${azurerm_resource_group.testrg.location}" + resource_group_name = "${azurerm_resource_group.testrg.name}" + + sku { + name = "standard" + } + + tenant_id = "${data.azurerm_client_config.current.tenant_id}" +} + +resource "azurerm_key_vault_access_policy" "sp" { + vault_name = "${azurerm_key_vault.test.name}" + resource_group_name = "${azurerm_resource_group.testrg.name}" + + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + object_id = "${data.azurerm_client_config.current.service_principal_object_id}" + + key_permissions = [ + "get", + "create", + "list", + "delete", + ] + + secret_permissions = [] +} + +resource "azurerm_key_vault_access_policy" "storage" { + vault_name = "${azurerm_key_vault.test.name}" + resource_group_name = "${azurerm_resource_group.testrg.name}" + + tenant_id = "${azurerm_storage_account.testsa.identity.0.tenant_id}" + object_id = "${azurerm_storage_account.testsa.identity.0.principal_id}" + + key_permissions = [ + "get", + "wrapKey", + "unwrapKey", + ] + + secret_permissions = [] + } + +resource "azurerm_key_vault_key" "test" { + depends_on = ["azurerm_key_vault_access_policy.sp"] + + name = "testAccKey-%d" + vault_uri = "${azurerm_key_vault.test.vault_uri}" + key_type = "RSA" + key_size = 2048 + + key_opts = [ + "decrypt", + "encrypt", + "sign", + "unwrapKey", + "verify", + "wrapKey", + ] +} + +resource "azurerm_storage_account" "testsa" { + name = "unlikely23exst2acct%s" + resource_group_name = "${azurerm_resource_group.testrg.name}" + location = "${azurerm_resource_group.testrg.location}" + + account_tier = "Standard" + account_replication_type = "LRS" + + account_encryption_source = "Microsoft.KeyVault" + + key_vault_properties { + key_name = "${azurerm_key_vault_key.test.name}" + key_version = "${azurerm_key_vault_key.test.version}" + key_vault_uri = "${azurerm_key_vault.test.vault_uri}" + } + + tags { + environment = "production" + } +} +`, rInt, location, rString, rInt, rString) +} diff --git a/website/docs/r/storage_account.html.markdown b/website/docs/r/storage_account.html.markdown index cf7500014c38..1c428bf758cd 100644 --- a/website/docs/r/storage_account.html.markdown +++ b/website/docs/r/storage_account.html.markdown @@ -106,6 +106,8 @@ The following arguments are supported: * `account_encryption_source` - (Optional) The Encryption Source for this Storage Account. Possible values are `Microsoft.Keyvault` and `Microsoft.Storage`. Defaults to `Microsoft.Storage`. +* `key_vault_properties` - (Optional) A `key_vault_properties` block as documented below. + * `custom_domain` - (Optional) A `custom_domain` block as documented below. * `network_rules` - (Optional) A `network_rules` block as documented below. @@ -116,6 +118,14 @@ The following arguments are supported: --- +* `key_vault_properties` supports the following: + +* `key_name` - (Required) The name of Key Vault key. +* `key_version` - (Required) The version of Key Vault key. +* `key_vault_uri` - (Required) The Uri of Key Vault. + +--- + * `custom_domain` supports the following: * `name` - (Optional) The Custom Domain Name to use for the Storage Account, which will be validated by Azure. From f300b4889f79d0f41682d494c85c2430eaa3597a Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Thu, 7 Feb 2019 15:47:55 -0800 Subject: [PATCH 02/16] Pull Master to Fork --- azurerm/resource_arm_storage_account.go | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/azurerm/resource_arm_storage_account.go b/azurerm/resource_arm_storage_account.go index 0dabe8569e93..17ea7cb11415 100644 --- a/azurerm/resource_arm_storage_account.go +++ b/azurerm/resource_arm_storage_account.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -113,16 +114,19 @@ func resourceArmStorageAccount() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "key_name": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + ValidationFunc: validate.NoEmptyStrings, }, "key_version": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + ValidationFunc: validate.NoEmptyStrings, }, "key_vault_uri": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + ValidationFunc: validate.NoEmptyStrings, }, }, }, @@ -520,8 +524,9 @@ func resourceArmStorageAccountUpdate(d *schema.ResourceData, meta interface{}) e opts := storage.AccountUpdateParameters{ AccountPropertiesUpdateParameters: &storage.AccountPropertiesUpdateParameters{ Encryption: &storage.Encryption{ - Services: &storage.EncryptionServices{}, - KeySource: storage.KeySource(encryptionSource), + Services: &storage.EncryptionServices{}, + KeySource: storage.KeySource(encryptionSource), + KeyVaultProperties: &storage.KeyVaultProperties, }, }, } @@ -543,6 +548,10 @@ func resourceArmStorageAccountUpdate(d *schema.ResourceData, meta interface{}) e d.SetPartial("enable_file_encryption") } + // ********************************************* + // Add Properties here + // ********************************************* + _, err := client.Update(ctx, resourceGroupName, storageAccountName, opts) if err != nil { return fmt.Errorf("Error updating Azure Storage Account Encryption %q: %+v", storageAccountName, err) From 105fc2fad8b0976d25835fa1049b72b8e6d8f634 Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Thu, 7 Feb 2019 18:46:40 -0800 Subject: [PATCH 03/16] Initial split of the storage account resource into two --- azurerm/resource_arm_storage_account.go | 265 +++----------- ...m_storage_account_key_vault_custom_keys.go | 345 ++++++++++++++++++ 2 files changed, 389 insertions(+), 221 deletions(-) create mode 100644 azurerm/resource_arm_storage_account_key_vault_custom_keys.go diff --git a/azurerm/resource_arm_storage_account.go b/azurerm/resource_arm_storage_account.go index f94c3b9ea28c..90a39393e9d8 100644 --- a/azurerm/resource_arm_storage_account.go +++ b/azurerm/resource_arm_storage_account.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -59,7 +60,7 @@ func resourceArmStorageAccount() *schema.Resource { Computed: true, Deprecated: "This field has been split into `account_tier` and `account_replication_type`", ValidateFunc: validateArmStorageAccountType, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "account_tier": { @@ -70,7 +71,7 @@ func resourceArmStorageAccount() *schema.Resource { "Standard", "Premium", }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "account_replication_type": { @@ -82,7 +83,7 @@ func resourceArmStorageAccount() *schema.Resource { "GRS", "RAGRS", }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, // Only valid for BlobStorage & StorageV2 accounts, defaults to "Hot" in create function @@ -96,42 +97,6 @@ func resourceArmStorageAccount() *schema.Resource { }, true), }, - "account_encryption_source": { - Type: schema.TypeString, - Optional: true, - Default: string(storage.MicrosoftStorage), - ValidateFunc: validation.StringInSlice([]string{ - string(storage.MicrosoftKeyvault), - string(storage.MicrosoftStorage), - }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, - }, - - "key_vault_properties": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "key_name": { - Type: schema.TypeString, - Required: true, - ValidationFunc: validate.NoEmptyStrings, - }, - "key_version": { - Type: schema.TypeString, - Required: true, - ValidationFunc: validate.NoEmptyStrings, - }, - "key_vault_uri": { - Type: schema.TypeString, - Required: true, - ValidationFunc: validate.NoEmptyStrings, - }, - }, - }, - }, - "custom_domain": { Type: schema.TypeList, Optional: true, @@ -152,18 +117,6 @@ func resourceArmStorageAccount() *schema.Resource { }, }, - "enable_blob_encryption": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - - "enable_file_encryption": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "enable_https_traffic_only": { Type: schema.TypeBool, Optional: true, @@ -298,7 +251,7 @@ func resourceArmStorageAccount() *schema.Resource { "type": { Type: schema.TypeString, Required: true, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ "SystemAssigned", }, true), @@ -371,8 +324,6 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e accountKind := d.Get("account_kind").(string) location := azureRMNormalizeLocation(d.Get("location").(string)) tags := d.Get("tags").(map[string]interface{}) - enableBlobEncryption := d.Get("enable_blob_encryption").(bool) - enableFileEncryption := d.Get("enable_file_encryption").(bool) enableHTTPSTrafficOnly := d.Get("enable_https_traffic_only").(bool) accountTier := d.Get("account_tier").(string) @@ -381,7 +332,6 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e storageAccountEncryptionSource := d.Get("account_encryption_source").(string) networkRules := expandStorageAccountNetworkRules(d) - keyVaultProperties := expandAzureRmStorageAccountKeyVaultProperties(d) parameters := storage.AccountCreateParameters{ Location: &location, @@ -391,17 +341,6 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e Tags: expandTags(tags), Kind: storage.Kind(accountKind), AccountPropertiesCreateParameters: &storage.AccountPropertiesCreateParameters{ - Encryption: &storage.Encryption{ - Services: &storage.EncryptionServices{ - Blob: &storage.EncryptionService{ - Enabled: utils.Bool(enableBlobEncryption), - }, - File: &storage.EncryptionService{ - Enabled: utils.Bool(enableFileEncryption), - }}, - KeySource: storage.KeySource(storageAccountEncryptionSource), - KeyVaultProperties: keyVaultProperties, - }, EnableHTTPSTrafficOnly: &enableHTTPSTrafficOnly, NetworkRuleSet: networkRules, }, @@ -531,46 +470,6 @@ func resourceArmStorageAccountUpdate(d *schema.ResourceData, meta interface{}) e d.SetPartial("tags") } - if d.HasChange("enable_blob_encryption") || d.HasChange("enable_file_encryption") { - encryptionSource := d.Get("account_encryption_source").(string) - - opts := storage.AccountUpdateParameters{ - AccountPropertiesUpdateParameters: &storage.AccountPropertiesUpdateParameters{ - Encryption: &storage.Encryption{ - Services: &storage.EncryptionServices{}, - KeySource: storage.KeySource(encryptionSource), - KeyVaultProperties: &storage.KeyVaultProperties, - }, - }, - } - - if d.HasChange("enable_blob_encryption") { - enableEncryption := d.Get("enable_blob_encryption").(bool) - opts.Encryption.Services.Blob = &storage.EncryptionService{ - Enabled: utils.Bool(enableEncryption), - } - - d.SetPartial("enable_blob_encryption") - } - - if d.HasChange("enable_file_encryption") { - enableEncryption := d.Get("enable_file_encryption").(bool) - opts.Encryption.Services.File = &storage.EncryptionService{ - Enabled: utils.Bool(enableEncryption), - } - d.SetPartial("enable_file_encryption") - } - - // ********************************************* - // Add Properties here - // ********************************************* - - _, err := client.Update(ctx, resourceGroupName, storageAccountName, opts) - if err != nil { - return fmt.Errorf("Error updating Azure Storage Account Encryption %q: %+v", storageAccountName, err) - } - } - if d.HasChange("custom_domain") { customDomain := expandStorageAccountCustomDomain(d) opts := storage.AccountUpdateParameters{ @@ -628,27 +527,6 @@ func resourceArmStorageAccountUpdate(d *schema.ResourceData, meta interface{}) e d.SetPartial("network_rules") } - if d.HasChange("account_encryption_source") { - accountEncryptionSource := d.Get("account_encryption_source").(string) - keyVaultProperties := expandAzureRmStorageAccountKeyVaultProperties(d) - opts := storage.AccountUpdateParameters{ - AccountPropertiesUpdateParameters: &storage.AccountPropertiesUpdateParameters{ - Encryption: &storage.Encryption{ - KeySource: storage.KeySource(accountEncryptionSource), - KeyVaultProperties: keyVaultProperties, - }, - }, - } - - _, err := client.Update(ctx, resourceGroupName, storageAccountName, opts) - if err != nil { - return fmt.Errorf("Error updating Azure Storage Account account_encryption_source and key_vault_properties %q: %+v", storageAccountName, err) - } - - d.SetPartial("account_encryption_source") - d.SetPartial("key_vault_properties") - } - d.Partial(false) return resourceArmStorageAccountRead(d, meta) } @@ -703,24 +581,6 @@ func resourceArmStorageAccountRead(d *schema.ResourceData, meta interface{}) err } } - if encryption := props.Encryption; encryption != nil { - if services := encryption.Services; services != nil { - if blob := services.Blob; blob != nil { - d.Set("enable_blob_encryption", blob.Enabled) - } - if file := services.File; file != nil { - d.Set("enable_file_encryption", file.Enabled) - } - } - d.Set("account_encryption_source", string(encryption.KeySource)) - - if keyVaultProperties := encryption.KeyVaultProperties; keyVaultProperties != nil { - if err := d.Set("key_vault_properties", flattenAzureRmStorageAccountKeyVaultProperties(keyVaultProperties)); err != nil { - return fmt.Errorf("Error flattening `key_vault_properties`: %+v", err) - } - } - } - // Computed d.Set("primary_location", props.PrimaryLocation) d.Set("secondary_location", props.SecondaryLocation) @@ -863,17 +723,6 @@ func expandStorageAccountCustomDomain(d *schema.ResourceData) *storage.CustomDom } } -func flattenStorageAccountCustomDomain(input *storage.CustomDomain) []interface{} { - domain := make(map[string]interface{}) - - if v := input.Name; v != nil { - domain["name"] = *v - } - - // use_subdomain isn't returned - return []interface{}{domain} -} - func expandStorageAccountNetworkRules(d *schema.ResourceData) *storage.NetworkRuleSet { networkRules := d.Get("network_rules").([]interface{}) if len(networkRules) == 0 { @@ -936,6 +785,45 @@ func expandStorageAccountBypass(networkRule map[string]interface{}) storage.Bypa return storage.Bypass(strings.Join(bypassValues, ", ")) } +func expandAzureRmStorageAccountIdentity(d *schema.ResourceData) *storage.Identity { + identities := d.Get("identity").([]interface{}) + identity := identities[0].(map[string]interface{}) + identityType := identity["type"].(string) + return &storage.Identity{ + Type: &identityType, + } +} + +func flattenAzureRmStorageAccountIdentity(identity *storage.Identity) []interface{} { + if identity == nil { + return make([]interface{}, 0) + } + + result := make(map[string]interface{}) + if identity.Type != nil { + result["type"] = *identity.Type + } + if identity.PrincipalID != nil { + result["principal_id"] = *identity.PrincipalID + } + if identity.TenantID != nil { + result["tenant_id"] = *identity.TenantID + } + + return []interface{}{result} +} + +func flattenStorageAccountCustomDomain(input *storage.CustomDomain) []interface{} { + domain := make(map[string]interface{}) + + if v := input.Name; v != nil { + domain["name"] = *v + } + + // use_subdomain isn't returned + return []interface{}{domain} +} + func flattenStorageAccountNetworkRules(input *storage.NetworkRuleSet) []interface{} { if len(*input.IPRules) == 0 && len(*input.VirtualNetworkRules) == 0 { return []interface{}{} @@ -1008,68 +896,3 @@ func validateArmStorageAccountType(v interface{}, _ string) (warnings []string, errors = append(errors, fmt.Errorf("Invalid storage account type %q", input)) return warnings, errors } - -func expandAzureRmStorageAccountIdentity(d *schema.ResourceData) *storage.Identity { - identities := d.Get("identity").([]interface{}) - identity := identities[0].(map[string]interface{}) - identityType := identity["type"].(string) - return &storage.Identity{ - Type: &identityType, - } -} - -func flattenAzureRmStorageAccountIdentity(identity *storage.Identity) []interface{} { - if identity == nil { - return make([]interface{}, 0) - } - - result := make(map[string]interface{}) - if identity.Type != nil { - result["type"] = *identity.Type - } - if identity.PrincipalID != nil { - result["principal_id"] = *identity.PrincipalID - } - if identity.TenantID != nil { - result["tenant_id"] = *identity.TenantID - } - - return []interface{}{result} -} - -func expandAzureRmStorageAccountKeyVaultProperties(d *schema.ResourceData) *storage.KeyVaultProperties { - vs := d.Get("key_vault_properties").([]interface{}) - if vs == nil || len(vs) == 0 { - return &storage.KeyVaultProperties{} - } - - v := vs[0].(map[string]interface{}) - keyName := v["key_name"].(string) - keyVersion := v["key_version"].(string) - keyVaultURI := v["key_vault_uri"].(string) - - return &storage.KeyVaultProperties{ - KeyName: utils.String(keyName), - KeyVersion: utils.String(keyVersion), - KeyVaultURI: utils.String(keyVaultURI), - } -} - -func flattenAzureRmStorageAccountKeyVaultProperties(keyVaultProperties *storage.KeyVaultProperties) []interface{} { - if keyVaultProperties == nil { - return make([]interface{}, 0) - } - - result := make(map[string]interface{}) - if keyVaultProperties.KeyName != nil { - result["key_name"] = *keyVaultProperties.KeyName - } - if keyVaultProperties.KeyVersion != nil { - result["key_version"] = *keyVaultProperties.KeyVersion - } - if keyVaultProperties.KeyVaultURI != nil { - result["key_vault_uri"] = *keyVaultProperties.KeyVaultURI - } - - return []interface{}{result} -} diff --git a/azurerm/resource_arm_storage_account_key_vault_custom_keys.go b/azurerm/resource_arm_storage_account_key_vault_custom_keys.go new file mode 100644 index 000000000000..6ef77b3b25af --- /dev/null +++ b/azurerm/resource_arm_storage_account_key_vault_custom_keys.go @@ -0,0 +1,345 @@ +package azurerm + +import ( + "fmt" + + "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2017-10-01/storage" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmStorageAccountKeyVaultCustomKeys() *schema.Resource { + return &schema.Resource{ + Create: resourceArmStorageAccountCreate, + Read: resourceArmStorageAccountRead, + Update: resourceArmStorageAccountUpdate, + Delete: resourceArmStorageAccountDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + MigrateState: resourceStorageAccountMigrateState, + SchemaVersion: 2, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateArmStorageAccountName, + }, + + "resource_group_name": resourceGroupNameDiffSuppressSchema(), + + "location": locationSchema(), + + "account_encryption_source": { + Type: schema.TypeString, + Optional: true, + Default: string(storage.MicrosoftStorage), + ValidateFunc: validation.StringInSlice([]string{ + string(storage.MicrosoftKeyvault), + string(storage.MicrosoftStorage), + }, true), + DiffSuppressFunc: suppress.CaseDifference, + }, + + "key_vault_properties": { + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "key_version": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "key_vault_uri": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + }, + }, + }, + } +} + +func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) error { + ctx := meta.(*ArmClient).StopContext + client := meta.(*ArmClient).storageServiceClient + + storageAccountName := d.Get("name").(string) + resourceGroupName := d.Get("resource_group_name").(string) + + if requireResourcesToBeImported { + existing, err := client.GetProperties(ctx, resourceGroupName, storageAccountName) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Storage Account %q (Resource Group %q): %s", storageAccountName, resourceGroupName, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_storage_account", *existing.ID) + } + } + + location := azureRMNormalizeLocation(d.Get("location").(string)) + tags := d.Get("tags").(map[string]interface{}) + enableBlobEncryption := d.Get("enable_blob_encryption").(bool) + enableFileEncryption := d.Get("enable_file_encryption").(bool) + keyVaultProperties := expandAzureRmStorageAccountKeyVaultProperties(d) + + parameters := storage.AccountCreateParameters{ + Location: &location, + Sku: &storage.Sku{ + Name: storage.SkuName(storageType), + }, + Tags: expandTags(tags), + Kind: storage.Kind(accountKind), + AccountPropertiesCreateParameters: &storage.AccountPropertiesCreateParameters{ + Encryption: &storage.Encryption{ + Services: &storage.EncryptionServices{ + Blob: &storage.EncryptionService{ + Enabled: utils.Bool(enableBlobEncryption), + }, + File: &storage.EncryptionService{ + Enabled: utils.Bool(enableFileEncryption), + }}, + KeySource: storage.KeySource(storageAccountEncryptionSource), + KeyVaultProperties: keyVaultProperties, + }, + EnableHTTPSTrafficOnly: &enableHTTPSTrafficOnly, + NetworkRuleSet: networkRules, + }, + } + + // Create + future, err := client.Create(ctx, resourceGroupName, storageAccountName, parameters) + if err != nil { + return fmt.Errorf("Error creating Azure Storage Account %q: %+v", storageAccountName, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for Azure Storage Account %q to be created: %+v", storageAccountName, err) + } + + account, err := client.GetProperties(ctx, resourceGroupName, storageAccountName) + if err != nil { + return fmt.Errorf("Error retrieving Azure Storage Account %q: %+v", storageAccountName, err) + } + + return resourceArmStorageAccountRead(d, meta) +} + +// resourceArmStorageAccountUpdate is unusual in the ARM API where most resources have a combined +// and idempotent operation for CreateOrUpdate. In particular updating all of the parameters +// available requires a call to Update per parameter... +func resourceArmStorageAccountUpdate(d *schema.ResourceData, meta interface{}) error { + ctx := meta.(*ArmClient).StopContext + client := meta.(*ArmClient).storageServiceClient + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + storageAccountName := id.Path["storageAccounts"] + resourceGroupName := id.ResourceGroup + + d.Partial(true) + + if d.HasChange("enable_blob_encryption") || d.HasChange("enable_file_encryption") { + encryptionSource := d.Get("account_encryption_source").(string) + + opts := storage.AccountUpdateParameters{ + AccountPropertiesUpdateParameters: &storage.AccountPropertiesUpdateParameters{ + Encryption: &storage.Encryption{ + Services: &storage.EncryptionServices{}, + KeySource: storage.KeySource(encryptionSource), + }, + }, + } + + if d.HasChange("enable_blob_encryption") { + enableEncryption := d.Get("enable_blob_encryption").(bool) + opts.Encryption.Services.Blob = &storage.EncryptionService{ + Enabled: utils.Bool(enableEncryption), + } + + d.SetPartial("enable_blob_encryption") + } + + if d.HasChange("enable_file_encryption") { + enableEncryption := d.Get("enable_file_encryption").(bool) + opts.Encryption.Services.File = &storage.EncryptionService{ + Enabled: utils.Bool(enableEncryption), + } + d.SetPartial("enable_file_encryption") + } + + _, err := client.Update(ctx, resourceGroupName, storageAccountName, opts) + if err != nil { + return fmt.Errorf("Error updating Azure Storage Account Encryption %q: %+v", storageAccountName, err) + } + } + + if d.HasChange("account_encryption_source") { + accountEncryptionSource := d.Get("account_encryption_source").(string) + keyVaultProperties := expandAzureRmStorageAccountKeyVaultProperties(d) + opts := storage.AccountUpdateParameters{ + AccountPropertiesUpdateParameters: &storage.AccountPropertiesUpdateParameters{ + Encryption: &storage.Encryption{ + KeySource: storage.KeySource(accountEncryptionSource), + KeyVaultProperties: keyVaultProperties, + }, + }, + } + + _, err := client.Update(ctx, resourceGroupName, storageAccountName, opts) + if err != nil { + return fmt.Errorf("Error updating Azure Storage Account account_encryption_source and key_vault_properties %q: %+v", storageAccountName, err) + } + + d.SetPartial("account_encryption_source") + d.SetPartial("key_vault_properties") + } + + d.Partial(false) + return resourceArmStorageAccountRead(d, meta) +} + +func resourceArmStorageAccountRead(d *schema.ResourceData, meta interface{}) error { + ctx := meta.(*ArmClient).StopContext + client := meta.(*ArmClient).storageServiceClient + endpointSuffix := meta.(*ArmClient).environment.StorageEndpointSuffix + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + name := id.Path["storageAccounts"] + resGroup := id.ResourceGroup + + resp, err := client.GetProperties(ctx, resGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + return fmt.Errorf("Error reading the state of AzureRM Storage Account %q: %+v", name, err) + } + + keys, err := client.ListKeys(ctx, resGroup, name) + if err != nil { + return err + } + + accessKeys := *keys.Keys + d.Set("name", resp.Name) + d.Set("resource_group_name", resGroup) + if location := resp.Location; location != nil { + d.Set("location", azureRMNormalizeLocation(*location)) + } + + if props := resp.AccountProperties; props != nil { + if encryption := props.Encryption; encryption != nil { + if services := encryption.Services; services != nil { + if blob := services.Blob; blob != nil { + d.Set("enable_blob_encryption", blob.Enabled) + } + if file := services.File; file != nil { + d.Set("enable_file_encryption", file.Enabled) + } + } + d.Set("account_encryption_source", string(encryption.KeySource)) + + if keyVaultProperties := encryption.KeyVaultProperties; keyVaultProperties != nil { + if err := d.Set("key_vault_properties", flattenAzureRmStorageAccountKeyVaultProperties(keyVaultProperties)); err != nil { + return fmt.Errorf("Error flattening `key_vault_properties`: %+v", err) + } + } + } + } + + return nil +} + +func resourceArmStorageAccountDelete(d *schema.ResourceData, meta interface{}) error { + // Not sure what to do here... + + // ctx := meta.(*ArmClient).StopContext + // client := meta.(*ArmClient).storageServiceClient + + // id, err := parseAzureResourceID(d.Id()) + // if err != nil { + // return err + // } + // name := id.Path["storageAccounts"] + // resourceGroup := id.ResourceGroup + + // read, err := client.GetProperties(ctx, resourceGroup, name) + // if err != nil { + // if utils.ResponseWasNotFound(read.Response) { + // return nil + // } + + // return fmt.Errorf("Error retrieving Storage Account %q (Resource Group %q): %+v", name, resourceGroup, err) + // } + + // resp, err := client.Delete(ctx, resourceGroup, name) + // if err != nil { + // if !response.WasNotFound(resp.Response) { + // return fmt.Errorf("Error issuing delete request for Storage Account %q (Resource Group %q): %+v", name, resourceGroup, err) + // } + // } + + return nil +} + +func expandAzureRmStorageAccountKeyVaultProperties(d *schema.ResourceData) *storage.KeyVaultProperties { + vs := d.Get("key_vault_properties").([]interface{}) + if vs == nil || len(vs) == 0 { + return &storage.KeyVaultProperties{} + } + + v := vs[0].(map[string]interface{}) + keyName := v["key_name"].(string) + keyVersion := v["key_version"].(string) + keyVaultURI := v["key_vault_uri"].(string) + + return &storage.KeyVaultProperties{ + KeyName: utils.String(keyName), + KeyVersion: utils.String(keyVersion), + KeyVaultURI: utils.String(keyVaultURI), + } +} + +func flattenAzureRmStorageAccountKeyVaultProperties(keyVaultProperties *storage.KeyVaultProperties) []interface{} { + if keyVaultProperties == nil { + return make([]interface{}, 0) + } + + result := make(map[string]interface{}) + if keyVaultProperties.KeyName != nil { + result["key_name"] = *keyVaultProperties.KeyName + } + if keyVaultProperties.KeyVersion != nil { + result["key_version"] = *keyVaultProperties.KeyVersion + } + if keyVaultProperties.KeyVaultURI != nil { + result["key_vault_uri"] = *keyVaultProperties.KeyVaultURI + } + + return []interface{}{result} +} From 71ae14a746dd69c1209e4a5833fdd673337005bb Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Thu, 14 Feb 2019 17:14:48 -0800 Subject: [PATCH 04/16] Pulled apart resources got it to compile --- azurerm/resource_arm_storage_account.go | 2 - ...m_storage_account_key_vault_custom_keys.go | 155 ++++-------------- 2 files changed, 33 insertions(+), 124 deletions(-) diff --git a/azurerm/resource_arm_storage_account.go b/azurerm/resource_arm_storage_account.go index 90a39393e9d8..9d0cf8f28476 100644 --- a/azurerm/resource_arm_storage_account.go +++ b/azurerm/resource_arm_storage_account.go @@ -329,8 +329,6 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e accountTier := d.Get("account_tier").(string) replicationType := d.Get("account_replication_type").(string) storageType := fmt.Sprintf("%s_%s", accountTier, replicationType) - storageAccountEncryptionSource := d.Get("account_encryption_source").(string) - networkRules := expandStorageAccountNetworkRules(d) parameters := storage.AccountCreateParameters{ diff --git a/azurerm/resource_arm_storage_account_key_vault_custom_keys.go b/azurerm/resource_arm_storage_account_key_vault_custom_keys.go index 6ef77b3b25af..51db53f07084 100644 --- a/azurerm/resource_arm_storage_account_key_vault_custom_keys.go +++ b/azurerm/resource_arm_storage_account_key_vault_custom_keys.go @@ -6,18 +6,16 @@ import ( "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2017-10-01/storage" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) func resourceArmStorageAccountKeyVaultCustomKeys() *schema.Resource { return &schema.Resource{ - Create: resourceArmStorageAccountCreate, - Read: resourceArmStorageAccountRead, - Update: resourceArmStorageAccountUpdate, - Delete: resourceArmStorageAccountDelete, + Read: resourceArmStorageAccountVaultCustomKeysRead, + Update: resourceArmStorageAccountVaultCustomKeysUpdate, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, @@ -26,21 +24,29 @@ func resourceArmStorageAccountKeyVaultCustomKeys() *schema.Resource { SchemaVersion: 2, Schema: map[string]*schema.Schema{ - "name": { + "storage_account_id": { Type: schema.TypeString, Required: true, ForceNew: true, - ValidateFunc: validateArmStorageAccountName, + ValidateFunc: azure.ValidateResourceID, }, - "resource_group_name": resourceGroupNameDiffSuppressSchema(), + "enable_blob_encryption": { + Type: schema.TypeBool, + Required: true, + Default: true, + }, - "location": locationSchema(), + "enable_file_encryption": { + Type: schema.TypeBool, + Required: true, + Default: true, + }, "account_encryption_source": { Type: schema.TypeString, - Optional: true, - Default: string(storage.MicrosoftStorage), + Required: true, + Default: string(storage.MicrosoftKeyvault), ValidateFunc: validation.StringInSlice([]string{ string(storage.MicrosoftKeyvault), string(storage.MicrosoftStorage), @@ -76,84 +82,20 @@ func resourceArmStorageAccountKeyVaultCustomKeys() *schema.Resource { } } -func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) error { - ctx := meta.(*ArmClient).StopContext - client := meta.(*ArmClient).storageServiceClient - - storageAccountName := d.Get("name").(string) - resourceGroupName := d.Get("resource_group_name").(string) - - if requireResourcesToBeImported { - existing, err := client.GetProperties(ctx, resourceGroupName, storageAccountName) - if err != nil { - if !utils.ResponseWasNotFound(existing.Response) { - return fmt.Errorf("Error checking for presence of existing Storage Account %q (Resource Group %q): %s", storageAccountName, resourceGroupName, err) - } - } - - if existing.ID != nil && *existing.ID != "" { - return tf.ImportAsExistsError("azurerm_storage_account", *existing.ID) - } - } - - location := azureRMNormalizeLocation(d.Get("location").(string)) - tags := d.Get("tags").(map[string]interface{}) - enableBlobEncryption := d.Get("enable_blob_encryption").(bool) - enableFileEncryption := d.Get("enable_file_encryption").(bool) - keyVaultProperties := expandAzureRmStorageAccountKeyVaultProperties(d) - - parameters := storage.AccountCreateParameters{ - Location: &location, - Sku: &storage.Sku{ - Name: storage.SkuName(storageType), - }, - Tags: expandTags(tags), - Kind: storage.Kind(accountKind), - AccountPropertiesCreateParameters: &storage.AccountPropertiesCreateParameters{ - Encryption: &storage.Encryption{ - Services: &storage.EncryptionServices{ - Blob: &storage.EncryptionService{ - Enabled: utils.Bool(enableBlobEncryption), - }, - File: &storage.EncryptionService{ - Enabled: utils.Bool(enableFileEncryption), - }}, - KeySource: storage.KeySource(storageAccountEncryptionSource), - KeyVaultProperties: keyVaultProperties, - }, - EnableHTTPSTrafficOnly: &enableHTTPSTrafficOnly, - NetworkRuleSet: networkRules, - }, - } - - // Create - future, err := client.Create(ctx, resourceGroupName, storageAccountName, parameters) - if err != nil { - return fmt.Errorf("Error creating Azure Storage Account %q: %+v", storageAccountName, err) - } - - if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { - return fmt.Errorf("Error waiting for Azure Storage Account %q to be created: %+v", storageAccountName, err) - } - - account, err := client.GetProperties(ctx, resourceGroupName, storageAccountName) - if err != nil { - return fmt.Errorf("Error retrieving Azure Storage Account %q: %+v", storageAccountName, err) - } - - return resourceArmStorageAccountRead(d, meta) -} - // resourceArmStorageAccountUpdate is unusual in the ARM API where most resources have a combined // and idempotent operation for CreateOrUpdate. In particular updating all of the parameters // available requires a call to Update per parameter... -func resourceArmStorageAccountUpdate(d *schema.ResourceData, meta interface{}) error { +func resourceArmStorageAccountVaultCustomKeysUpdate(d *schema.ResourceData, meta interface{}) error { ctx := meta.(*ArmClient).StopContext client := meta.(*ArmClient).storageServiceClient - id, err := parseAzureResourceID(d.Id()) + + storageAccountId := d.Get("storage_account_id").(string) + + id, err := azure.ParseAzureResourceID(storageAccountId) if err != nil { return err } + storageAccountName := id.Path["storageAccounts"] resourceGroupName := id.ResourceGroup @@ -216,15 +158,16 @@ func resourceArmStorageAccountUpdate(d *schema.ResourceData, meta interface{}) e } d.Partial(false) - return resourceArmStorageAccountRead(d, meta) + return resourceArmStorageAccountVaultCustomKeysRead(d, meta) } -func resourceArmStorageAccountRead(d *schema.ResourceData, meta interface{}) error { +func resourceArmStorageAccountVaultCustomKeysRead(d *schema.ResourceData, meta interface{}) error { ctx := meta.(*ArmClient).StopContext client := meta.(*ArmClient).storageServiceClient - endpointSuffix := meta.(*ArmClient).environment.StorageEndpointSuffix - id, err := parseAzureResourceID(d.Id()) + storageAccountId := d.Get("storage_account_id").(string) + + id, err := parseAzureResourceID(storageAccountId) if err != nil { return err } @@ -240,12 +183,12 @@ func resourceArmStorageAccountRead(d *schema.ResourceData, meta interface{}) err return fmt.Errorf("Error reading the state of AzureRM Storage Account %q: %+v", name, err) } - keys, err := client.ListKeys(ctx, resGroup, name) - if err != nil { - return err - } + // keys, err := client.ListKeys(ctx, resGroup, name) + // if err != nil { + // return err + // } - accessKeys := *keys.Keys + //accessKeys := *keys.Keys d.Set("name", resp.Name) d.Set("resource_group_name", resGroup) if location := resp.Location; location != nil { @@ -275,38 +218,6 @@ func resourceArmStorageAccountRead(d *schema.ResourceData, meta interface{}) err return nil } -func resourceArmStorageAccountDelete(d *schema.ResourceData, meta interface{}) error { - // Not sure what to do here... - - // ctx := meta.(*ArmClient).StopContext - // client := meta.(*ArmClient).storageServiceClient - - // id, err := parseAzureResourceID(d.Id()) - // if err != nil { - // return err - // } - // name := id.Path["storageAccounts"] - // resourceGroup := id.ResourceGroup - - // read, err := client.GetProperties(ctx, resourceGroup, name) - // if err != nil { - // if utils.ResponseWasNotFound(read.Response) { - // return nil - // } - - // return fmt.Errorf("Error retrieving Storage Account %q (Resource Group %q): %+v", name, resourceGroup, err) - // } - - // resp, err := client.Delete(ctx, resourceGroup, name) - // if err != nil { - // if !response.WasNotFound(resp.Response) { - // return fmt.Errorf("Error issuing delete request for Storage Account %q (Resource Group %q): %+v", name, resourceGroup, err) - // } - // } - - return nil -} - func expandAzureRmStorageAccountKeyVaultProperties(d *schema.ResourceData) *storage.KeyVaultProperties { vs := d.Get("key_vault_properties").([]interface{}) if vs == nil || len(vs) == 0 { From 3fb32d41c896f95e79c842cfb7b1d07c8141bd76 Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Tue, 19 Feb 2019 13:21:59 -0800 Subject: [PATCH 05/16] Got it working --- azurerm/provider.go | 1 + ...m_storage_account_key_vault_custom_keys.go | 42 ++++++++++++------- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/azurerm/provider.go b/azurerm/provider.go index 5af4de2cbf80..e64dc8ef6a17 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -332,6 +332,7 @@ func Provider() terraform.ResourceProvider { "azurerm_sql_server": resourceArmSqlServer(), "azurerm_sql_virtual_network_rule": resourceArmSqlVirtualNetworkRule(), "azurerm_storage_account": resourceArmStorageAccount(), + "azurerm_storage_account_key_vault_custom_keys": resourceArmStorageAccountKeyVaultCustomKeys(), "azurerm_storage_blob": resourceArmStorageBlob(), "azurerm_storage_container": resourceArmStorageContainer(), "azurerm_storage_queue": resourceArmStorageQueue(), diff --git a/azurerm/resource_arm_storage_account_key_vault_custom_keys.go b/azurerm/resource_arm_storage_account_key_vault_custom_keys.go index 51db53f07084..c2254be8fe64 100644 --- a/azurerm/resource_arm_storage_account_key_vault_custom_keys.go +++ b/azurerm/resource_arm_storage_account_key_vault_custom_keys.go @@ -15,7 +15,9 @@ import ( func resourceArmStorageAccountKeyVaultCustomKeys() *schema.Resource { return &schema.Resource{ Read: resourceArmStorageAccountVaultCustomKeysRead, + Create: resourceArmStorageAccountVaultCustomKeysUpdate, Update: resourceArmStorageAccountVaultCustomKeysUpdate, + Delete: resourceArmStorageAccountVaultCustomKeysDelete, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, @@ -27,25 +29,22 @@ func resourceArmStorageAccountKeyVaultCustomKeys() *schema.Resource { "storage_account_id": { Type: schema.TypeString, Required: true, - ForceNew: true, ValidateFunc: azure.ValidateResourceID, }, "enable_blob_encryption": { Type: schema.TypeBool, Required: true, - Default: true, }, "enable_file_encryption": { Type: schema.TypeBool, Required: true, - Default: true, }, "account_encryption_source": { Type: schema.TypeString, - Required: true, + Optional: true, Default: string(storage.MicrosoftKeyvault), ValidateFunc: validation.StringInSlice([]string{ string(storage.MicrosoftKeyvault), @@ -98,17 +97,17 @@ func resourceArmStorageAccountVaultCustomKeysUpdate(d *schema.ResourceData, meta storageAccountName := id.Path["storageAccounts"] resourceGroupName := id.ResourceGroup + encryptionSource := d.Get("account_encryption_source").(string) d.Partial(true) if d.HasChange("enable_blob_encryption") || d.HasChange("enable_file_encryption") { - encryptionSource := d.Get("account_encryption_source").(string) opts := storage.AccountUpdateParameters{ AccountPropertiesUpdateParameters: &storage.AccountPropertiesUpdateParameters{ Encryption: &storage.Encryption{ Services: &storage.EncryptionServices{}, - KeySource: storage.KeySource(encryptionSource), + KeySource: storage.KeySource(storage.MicrosoftStorage), }, }, } @@ -119,6 +118,11 @@ func resourceArmStorageAccountVaultCustomKeysUpdate(d *schema.ResourceData, meta Enabled: utils.Bool(enableEncryption), } + _, err := client.Update(ctx, resourceGroupName, storageAccountName, opts) + if err != nil { + return fmt.Errorf("Error updating Azure Storage Account Encryption %q: %+v", storageAccountName, err) + } + d.SetPartial("enable_blob_encryption") } @@ -127,22 +131,24 @@ func resourceArmStorageAccountVaultCustomKeysUpdate(d *schema.ResourceData, meta opts.Encryption.Services.File = &storage.EncryptionService{ Enabled: utils.Bool(enableEncryption), } - d.SetPartial("enable_file_encryption") - } - _, err := client.Update(ctx, resourceGroupName, storageAccountName, opts) - if err != nil { - return fmt.Errorf("Error updating Azure Storage Account Encryption %q: %+v", storageAccountName, err) + _, err := client.Update(ctx, resourceGroupName, storageAccountName, opts) + if err != nil { + return fmt.Errorf("Error updating Azure Storage Account Encryption %q: %+v", storageAccountName, err) + } + + d.SetPartial("enable_file_encryption") } } - if d.HasChange("account_encryption_source") { - accountEncryptionSource := d.Get("account_encryption_source").(string) + // NOTE: If KeySource is KeyVault you also need to send key vault properties + if encryptionSource == "Microsoft.Keyvault" { keyVaultProperties := expandAzureRmStorageAccountKeyVaultProperties(d) + opts := storage.AccountUpdateParameters{ AccountPropertiesUpdateParameters: &storage.AccountPropertiesUpdateParameters{ Encryption: &storage.Encryption{ - KeySource: storage.KeySource(accountEncryptionSource), + KeySource: storage.KeySource(storage.MicrosoftKeyvault), KeyVaultProperties: keyVaultProperties, }, }, @@ -150,7 +156,7 @@ func resourceArmStorageAccountVaultCustomKeysUpdate(d *schema.ResourceData, meta _, err := client.Update(ctx, resourceGroupName, storageAccountName, opts) if err != nil { - return fmt.Errorf("Error updating Azure Storage Account account_encryption_source and key_vault_properties %q: %+v", storageAccountName, err) + return fmt.Errorf("Error updating Azure Storage Account Encryption %q: %+v", storageAccountName, err) } d.SetPartial("account_encryption_source") @@ -158,6 +164,7 @@ func resourceArmStorageAccountVaultCustomKeysUpdate(d *schema.ResourceData, meta } d.Partial(false) + return resourceArmStorageAccountVaultCustomKeysRead(d, meta) } @@ -218,6 +225,11 @@ func resourceArmStorageAccountVaultCustomKeysRead(d *schema.ResourceData, meta i return nil } +func resourceArmStorageAccountVaultCustomKeysDelete(d *schema.ResourceData, meta interface{}) error { + // Thnik what to do here? + return nil +} + func expandAzureRmStorageAccountKeyVaultProperties(d *schema.ResourceData) *storage.KeyVaultProperties { vs := d.Get("key_vault_properties").([]interface{}) if vs == nil || len(vs) == 0 { From 8abbf23d8d05d15c77c704bfa2c361ad367a0ad6 Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Thu, 21 Feb 2019 14:34:53 -0800 Subject: [PATCH 06/16] Updated to encryption settings --- azurerm/provider.go | 2 +- ...rm_storage_account_encryption_settings.go} | 183 +++++++++--------- 2 files changed, 89 insertions(+), 96 deletions(-) rename azurerm/{resource_arm_storage_account_key_vault_custom_keys.go => resource_arm_storage_account_encryption_settings.go} (55%) diff --git a/azurerm/provider.go b/azurerm/provider.go index e64dc8ef6a17..c47a6accaac8 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -332,7 +332,7 @@ func Provider() terraform.ResourceProvider { "azurerm_sql_server": resourceArmSqlServer(), "azurerm_sql_virtual_network_rule": resourceArmSqlVirtualNetworkRule(), "azurerm_storage_account": resourceArmStorageAccount(), - "azurerm_storage_account_key_vault_custom_keys": resourceArmStorageAccountKeyVaultCustomKeys(), + "azurerm_storage_account_encryption_settings": resourceArmStorageAccountEncryptionSettings(), "azurerm_storage_blob": resourceArmStorageBlob(), "azurerm_storage_container": resourceArmStorageContainer(), "azurerm_storage_queue": resourceArmStorageQueue(), diff --git a/azurerm/resource_arm_storage_account_key_vault_custom_keys.go b/azurerm/resource_arm_storage_account_encryption_settings.go similarity index 55% rename from azurerm/resource_arm_storage_account_key_vault_custom_keys.go rename to azurerm/resource_arm_storage_account_encryption_settings.go index c2254be8fe64..e9e3bb0cb984 100644 --- a/azurerm/resource_arm_storage_account_key_vault_custom_keys.go +++ b/azurerm/resource_arm_storage_account_encryption_settings.go @@ -12,17 +12,16 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) -func resourceArmStorageAccountKeyVaultCustomKeys() *schema.Resource { +func resourceArmStorageAccountEncryptionSettings() *schema.Resource { return &schema.Resource{ - Read: resourceArmStorageAccountVaultCustomKeysRead, - Create: resourceArmStorageAccountVaultCustomKeysUpdate, - Update: resourceArmStorageAccountVaultCustomKeysUpdate, - Delete: resourceArmStorageAccountVaultCustomKeysDelete, + Read: resourceArmStorageAccountEncryptionSettingsRead, + Create: resourceArmStorageAccountEncryptionSettingsCreateUpdate, + Update: resourceArmStorageAccountEncryptionSettingsCreateUpdate, + Delete: resourceArmStorageAccountEncryptionSettingsDelete, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, - MigrateState: resourceStorageAccountMigrateState, SchemaVersion: 2, Schema: map[string]*schema.Schema{ @@ -32,20 +31,33 @@ func resourceArmStorageAccountKeyVaultCustomKeys() *schema.Resource { ValidateFunc: azure.ValidateResourceID, }, + "key_vault_policy_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: azure.ValidateResourceID, + }, + + "key_vault_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: azure.ValidateResourceID, + }, + "enable_blob_encryption": { Type: schema.TypeBool, - Required: true, + Optional: true, + Default: true, }, "enable_file_encryption": { Type: schema.TypeBool, - Required: true, + Optional: true, + Default: true, }, "account_encryption_source": { Type: schema.TypeString, - Optional: true, - Default: string(storage.MicrosoftKeyvault), + Required: true, ValidateFunc: validation.StringInSlice([]string{ string(storage.MicrosoftKeyvault), string(storage.MicrosoftStorage), @@ -56,7 +68,7 @@ func resourceArmStorageAccountKeyVaultCustomKeys() *schema.Resource { "key_vault_properties": { Type: schema.TypeList, MaxItems: 1, - Optional: true, + Required: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "key_name": { @@ -70,9 +82,8 @@ func resourceArmStorageAccountKeyVaultCustomKeys() *schema.Resource { ValidateFunc: validate.NoEmptyStrings, }, "key_vault_uri": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validate.NoEmptyStrings, + Type: schema.TypeString, + Computed: true, }, }, }, @@ -81,11 +92,9 @@ func resourceArmStorageAccountKeyVaultCustomKeys() *schema.Resource { } } -// resourceArmStorageAccountUpdate is unusual in the ARM API where most resources have a combined -// and idempotent operation for CreateOrUpdate. In particular updating all of the parameters -// available requires a call to Update per parameter... -func resourceArmStorageAccountVaultCustomKeysUpdate(d *schema.ResourceData, meta interface{}) error { +func resourceArmStorageAccountEncryptionSettingsCreateUpdate(d *schema.ResourceData, meta interface{}) error { ctx := meta.(*ArmClient).StopContext + vaultClient := meta.(*ArmClient).keyVaultClient client := meta.(*ArmClient).storageServiceClient storageAccountId := d.Get("storage_account_id").(string) @@ -97,78 +106,47 @@ func resourceArmStorageAccountVaultCustomKeysUpdate(d *schema.ResourceData, meta storageAccountName := id.Path["storageAccounts"] resourceGroupName := id.ResourceGroup + enableBlobEncryption := d.Get("enable_blob_encryption").(bool) + enableFileEncryption := d.Get("enable_file_encryption").(bool) encryptionSource := d.Get("account_encryption_source").(string) + keyVaultId := d.Get("key_vault_id").(string) - d.Partial(true) + pKeyVaultBaseUrl, err := azure.GetKeyVaultBaseUrlFromID(ctx, vaultClient, keyVaultId) - if d.HasChange("enable_blob_encryption") || d.HasChange("enable_file_encryption") { - - opts := storage.AccountUpdateParameters{ - AccountPropertiesUpdateParameters: &storage.AccountPropertiesUpdateParameters{ - Encryption: &storage.Encryption{ - Services: &storage.EncryptionServices{}, - KeySource: storage.KeySource(storage.MicrosoftStorage), - }, - }, - } - - if d.HasChange("enable_blob_encryption") { - enableEncryption := d.Get("enable_blob_encryption").(bool) - opts.Encryption.Services.Blob = &storage.EncryptionService{ - Enabled: utils.Bool(enableEncryption), - } - - _, err := client.Update(ctx, resourceGroupName, storageAccountName, opts) - if err != nil { - return fmt.Errorf("Error updating Azure Storage Account Encryption %q: %+v", storageAccountName, err) - } - - d.SetPartial("enable_blob_encryption") - } - - if d.HasChange("enable_file_encryption") { - enableEncryption := d.Get("enable_file_encryption").(bool) - opts.Encryption.Services.File = &storage.EncryptionService{ - Enabled: utils.Bool(enableEncryption), - } - - _, err := client.Update(ctx, resourceGroupName, storageAccountName, opts) - if err != nil { - return fmt.Errorf("Error updating Azure Storage Account Encryption %q: %+v", storageAccountName, err) - } - - d.SetPartial("enable_file_encryption") - } + if err != nil { + return fmt.Errorf("Error looking up Key Vault URI from id %q: %+v", keyVaultId, err) } - // NOTE: If KeySource is KeyVault you also need to send key vault properties - if encryptionSource == "Microsoft.Keyvault" { - keyVaultProperties := expandAzureRmStorageAccountKeyVaultProperties(d) + keyVaultProperties := expandAzureRmStorageAccountKeyVaultProperties(d) + keyVaultProperties.KeyVaultURI = utils.String(pKeyVaultBaseUrl) - opts := storage.AccountUpdateParameters{ - AccountPropertiesUpdateParameters: &storage.AccountPropertiesUpdateParameters{ - Encryption: &storage.Encryption{ - KeySource: storage.KeySource(storage.MicrosoftKeyvault), - KeyVaultProperties: keyVaultProperties, - }, + opts := storage.AccountUpdateParameters{ + AccountPropertiesUpdateParameters: &storage.AccountPropertiesUpdateParameters{ + Encryption: &storage.Encryption{ + Services: &storage.EncryptionServices{ + Blob: &storage.EncryptionService{ + Enabled: utils.Bool(enableBlobEncryption), + }, + File: &storage.EncryptionService{ + Enabled: utils.Bool(enableFileEncryption), + }}, + KeySource: storage.KeySource(encryptionSource), + KeyVaultProperties: keyVaultProperties, }, - } - - _, err := client.Update(ctx, resourceGroupName, storageAccountName, opts) - if err != nil { - return fmt.Errorf("Error updating Azure Storage Account Encryption %q: %+v", storageAccountName, err) - } + }, + } - d.SetPartial("account_encryption_source") - d.SetPartial("key_vault_properties") + _, err = client.Update(ctx, resourceGroupName, storageAccountName, opts) + if err != nil { + return fmt.Errorf("Error updating Azure Storage Account Encryption %q: %+v", storageAccountName, err) } - d.Partial(false) + d.SetId(storageAccountId) - return resourceArmStorageAccountVaultCustomKeysRead(d, meta) + return resourceArmStorageAccountEncryptionSettingsRead(d, meta) } -func resourceArmStorageAccountVaultCustomKeysRead(d *schema.ResourceData, meta interface{}) error { +func resourceArmStorageAccountEncryptionSettingsRead(d *schema.ResourceData, meta interface{}) error { ctx := meta.(*ArmClient).StopContext client := meta.(*ArmClient).storageServiceClient @@ -190,18 +168,6 @@ func resourceArmStorageAccountVaultCustomKeysRead(d *schema.ResourceData, meta i return fmt.Errorf("Error reading the state of AzureRM Storage Account %q: %+v", name, err) } - // keys, err := client.ListKeys(ctx, resGroup, name) - // if err != nil { - // return err - // } - - //accessKeys := *keys.Keys - d.Set("name", resp.Name) - d.Set("resource_group_name", resGroup) - if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) - } - if props := resp.AccountProperties; props != nil { if encryption := props.Encryption; encryption != nil { if services := encryption.Services; services != nil { @@ -225,8 +191,37 @@ func resourceArmStorageAccountVaultCustomKeysRead(d *schema.ResourceData, meta i return nil } -func resourceArmStorageAccountVaultCustomKeysDelete(d *schema.ResourceData, meta interface{}) error { - // Thnik what to do here? +func resourceArmStorageAccountEncryptionSettingsDelete(d *schema.ResourceData, meta interface{}) error { + ctx := meta.(*ArmClient).StopContext + client := meta.(*ArmClient).storageServiceClient + + storageAccountId := d.Get("storage_account_id").(string) + + id, err := azure.ParseAzureResourceID(storageAccountId) + if err != nil { + return err + } + + storageAccountName := id.Path["storageAccounts"] + resourceGroupName := id.ResourceGroup + + // Since this isn't a real object, just modifying an existing object + // "Delete" doesn't really make sense it should really be a "Revert to Default" + // So instead of the Delete func actually deleting the Storage Account I am + // making it reset the Storage Account to it's default state + opts := storage.AccountUpdateParameters{ + AccountPropertiesUpdateParameters: &storage.AccountPropertiesUpdateParameters{ + Encryption: &storage.Encryption{ + KeySource: storage.KeySource(storage.MicrosoftStorage), + }, + }, + } + + _, err = client.Update(ctx, resourceGroupName, storageAccountName, opts) + if err != nil { + return fmt.Errorf("Error updating Azure Storage Account Encryption %q: %+v", storageAccountName, err) + } + return nil } @@ -239,12 +234,10 @@ func expandAzureRmStorageAccountKeyVaultProperties(d *schema.ResourceData) *stor v := vs[0].(map[string]interface{}) keyName := v["key_name"].(string) keyVersion := v["key_version"].(string) - keyVaultURI := v["key_vault_uri"].(string) return &storage.KeyVaultProperties{ - KeyName: utils.String(keyName), - KeyVersion: utils.String(keyVersion), - KeyVaultURI: utils.String(keyVaultURI), + KeyName: utils.String(keyName), + KeyVersion: utils.String(keyVersion), } } From f0c4568dae4996e25f3ce878d6472efec02326da Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Thu, 21 Feb 2019 14:56:41 -0800 Subject: [PATCH 07/16] Updated resource id generation --- azurerm/resource_arm_storage_account_encryption_settings.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/azurerm/resource_arm_storage_account_encryption_settings.go b/azurerm/resource_arm_storage_account_encryption_settings.go index e9e3bb0cb984..71e96ce2b622 100644 --- a/azurerm/resource_arm_storage_account_encryption_settings.go +++ b/azurerm/resource_arm_storage_account_encryption_settings.go @@ -141,7 +141,8 @@ func resourceArmStorageAccountEncryptionSettingsCreateUpdate(d *schema.ResourceD return fmt.Errorf("Error updating Azure Storage Account Encryption %q: %+v", storageAccountName, err) } - d.SetId(storageAccountId) + resourceId := fmt.Sprintf("%s/encryptionSettings", storageAccountId) + d.SetId(resourceId) return resourceArmStorageAccountEncryptionSettingsRead(d, meta) } From 4a4c53135092c604b2fb89520a028e379b2c3c93 Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Thu, 21 Feb 2019 19:04:10 -0800 Subject: [PATCH 08/16] Changed the schema to make more sense --- ...arm_storage_account_encryption_settings.go | 102 ++++++++++-------- 1 file changed, 58 insertions(+), 44 deletions(-) diff --git a/azurerm/resource_arm_storage_account_encryption_settings.go b/azurerm/resource_arm_storage_account_encryption_settings.go index 71e96ce2b622..0a1fe64f5559 100644 --- a/azurerm/resource_arm_storage_account_encryption_settings.go +++ b/azurerm/resource_arm_storage_account_encryption_settings.go @@ -5,9 +5,7 @@ import ( "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2017-10-01/storage" "github.com/hashicorp/terraform/helper/schema" - "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -30,19 +28,6 @@ func resourceArmStorageAccountEncryptionSettings() *schema.Resource { Required: true, ValidateFunc: azure.ValidateResourceID, }, - - "key_vault_policy_id": { - Type: schema.TypeString, - Required: true, - ValidateFunc: azure.ValidateResourceID, - }, - - "key_vault_id": { - Type: schema.TypeString, - Required: true, - ValidateFunc: azure.ValidateResourceID, - }, - "enable_blob_encryption": { Type: schema.TypeBool, Optional: true, @@ -55,22 +40,27 @@ func resourceArmStorageAccountEncryptionSettings() *schema.Resource { Default: true, }, - "account_encryption_source": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringInSlice([]string{ - string(storage.MicrosoftKeyvault), - string(storage.MicrosoftStorage), - }, true), - DiffSuppressFunc: suppress.CaseDifference, - }, - - "key_vault_properties": { + "key_vault": { Type: schema.TypeList, MaxItems: 1, - Required: true, + Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ + // This attribute is not used, it was only added + // to create a dependancy between this resource + // and the key vault policy + "key_vault_policy_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: azure.ValidateResourceID, + }, + + "key_vault_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: azure.ValidateResourceID, + }, + "key_name": { Type: schema.TypeString, Required: true, @@ -106,20 +96,13 @@ func resourceArmStorageAccountEncryptionSettingsCreateUpdate(d *schema.ResourceD storageAccountName := id.Path["storageAccounts"] resourceGroupName := id.ResourceGroup - enableBlobEncryption := d.Get("enable_blob_encryption").(bool) - enableFileEncryption := d.Get("enable_file_encryption").(bool) - encryptionSource := d.Get("account_encryption_source").(string) - keyVaultId := d.Get("key_vault_id").(string) - - pKeyVaultBaseUrl, err := azure.GetKeyVaultBaseUrlFromID(ctx, vaultClient, keyVaultId) - - if err != nil { - return fmt.Errorf("Error looking up Key Vault URI from id %q: %+v", keyVaultId, err) - } - keyVaultProperties := expandAzureRmStorageAccountKeyVaultProperties(d) - keyVaultProperties.KeyVaultURI = utils.String(pKeyVaultBaseUrl) + // set default values for the attributes + enableBlobEncryption := true + enableFileEncryption := true + encryptionSource := storage.MicrosoftStorage + // create the update object with the default values opts := storage.AccountUpdateParameters{ AccountPropertiesUpdateParameters: &storage.AccountPropertiesUpdateParameters{ Encryption: &storage.Encryption{ @@ -131,11 +114,32 @@ func resourceArmStorageAccountEncryptionSettingsCreateUpdate(d *schema.ResourceD Enabled: utils.Bool(enableFileEncryption), }}, KeySource: storage.KeySource(encryptionSource), - KeyVaultProperties: keyVaultProperties, + KeyVaultProperties: &storage.KeyVaultProperties{}, }, }, } + if d.HasChange("enable_blob_encryption") || d.HasChange("enable_file_encryption") { + opts.Encryption.Services.Blob.Enabled = utils.Bool(d.Get("enable_blob_encryption").(bool)) + opts.Encryption.Services.File.Enabled = utils.Bool(d.Get("enable_file_encryption").(bool)) + } + + if keyVaultProperties := expandAzureRmStorageAccountKeyVaultProperties(d); keyVaultProperties.KeyName != utils.String("") { + if v, ok := d.GetOk("key_vault.0.key_vault_id"); ok { + // Get the key vault base URL from the key vault + keyVaultId := v.(string) + pKeyVaultBaseUrl, err := azure.GetKeyVaultBaseUrlFromID(ctx, vaultClient, keyVaultId) + + if err != nil { + return fmt.Errorf("Error looking up Key Vault URI from id %q: %+v", keyVaultId, err) + } + + keyVaultProperties.KeyVaultURI = utils.String(pKeyVaultBaseUrl) + opts.Encryption.KeyVaultProperties = keyVaultProperties + opts.Encryption.KeySource = storage.KeySource(storage.MicrosoftKeyvault) + } + } + _, err = client.Update(ctx, resourceGroupName, storageAccountName, opts) if err != nil { return fmt.Errorf("Error updating Azure Storage Account Encryption %q: %+v", storageAccountName, err) @@ -179,10 +183,12 @@ func resourceArmStorageAccountEncryptionSettingsRead(d *schema.ResourceData, met d.Set("enable_file_encryption", file.Enabled) } } - d.Set("account_encryption_source", string(encryption.KeySource)) if keyVaultProperties := encryption.KeyVaultProperties; keyVaultProperties != nil { - if err := d.Set("key_vault_properties", flattenAzureRmStorageAccountKeyVaultProperties(keyVaultProperties)); err != nil { + keyVaultId := d.Get("key_vault.0.key_vault_id").(string) + keyVaultPolicyId := d.Get("key_vault.0.key_vault_policy_id").(string) + + if err := d.Set("key_vault", flattenAzureRmStorageAccountKeyVaultProperties(keyVaultProperties, keyVaultId, keyVaultPolicyId)); err != nil { return fmt.Errorf("Error flattening `key_vault_properties`: %+v", err) } } @@ -227,7 +233,7 @@ func resourceArmStorageAccountEncryptionSettingsDelete(d *schema.ResourceData, m } func expandAzureRmStorageAccountKeyVaultProperties(d *schema.ResourceData) *storage.KeyVaultProperties { - vs := d.Get("key_vault_properties").([]interface{}) + vs := d.Get("key_vault").([]interface{}) if vs == nil || len(vs) == 0 { return &storage.KeyVaultProperties{} } @@ -242,12 +248,20 @@ func expandAzureRmStorageAccountKeyVaultProperties(d *schema.ResourceData) *stor } } -func flattenAzureRmStorageAccountKeyVaultProperties(keyVaultProperties *storage.KeyVaultProperties) []interface{} { +func flattenAzureRmStorageAccountKeyVaultProperties(keyVaultProperties *storage.KeyVaultProperties, keyVaultId string, keyVaultPolicyId string) []interface{} { if keyVaultProperties == nil { return make([]interface{}, 0) } result := make(map[string]interface{}) + if keyVaultId != "" { + result["key_vault_id"] = keyVaultId + } + + if keyVaultPolicyId != "" { + result["key_vault_policy_id"] = keyVaultPolicyId + } + if keyVaultProperties.KeyName != nil { result["key_name"] = *keyVaultProperties.KeyName } From e19cfe62c895628d021163ab6ae4c62f8d2022db Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Thu, 21 Feb 2019 19:21:13 -0800 Subject: [PATCH 09/16] Fixed lint errors --- ...esource_arm_storage_account_encryption_settings.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/azurerm/resource_arm_storage_account_encryption_settings.go b/azurerm/resource_arm_storage_account_encryption_settings.go index 0a1fe64f5559..1cd1359bc084 100644 --- a/azurerm/resource_arm_storage_account_encryption_settings.go +++ b/azurerm/resource_arm_storage_account_encryption_settings.go @@ -47,7 +47,7 @@ func resourceArmStorageAccountEncryptionSettings() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ // This attribute is not used, it was only added - // to create a dependancy between this resource + // to create a dependency between this resource // and the key vault policy "key_vault_policy_id": { Type: schema.TypeString, @@ -100,7 +100,6 @@ func resourceArmStorageAccountEncryptionSettingsCreateUpdate(d *schema.ResourceD // set default values for the attributes enableBlobEncryption := true enableFileEncryption := true - encryptionSource := storage.MicrosoftStorage // create the update object with the default values opts := storage.AccountUpdateParameters{ @@ -113,7 +112,7 @@ func resourceArmStorageAccountEncryptionSettingsCreateUpdate(d *schema.ResourceD File: &storage.EncryptionService{ Enabled: utils.Bool(enableFileEncryption), }}, - KeySource: storage.KeySource(encryptionSource), + KeySource: storage.MicrosoftStorage, KeyVaultProperties: &storage.KeyVaultProperties{}, }, }, @@ -136,7 +135,7 @@ func resourceArmStorageAccountEncryptionSettingsCreateUpdate(d *schema.ResourceD keyVaultProperties.KeyVaultURI = utils.String(pKeyVaultBaseUrl) opts.Encryption.KeyVaultProperties = keyVaultProperties - opts.Encryption.KeySource = storage.KeySource(storage.MicrosoftKeyvault) + opts.Encryption.KeySource = storage.MicrosoftKeyvault } } @@ -219,7 +218,7 @@ func resourceArmStorageAccountEncryptionSettingsDelete(d *schema.ResourceData, m opts := storage.AccountUpdateParameters{ AccountPropertiesUpdateParameters: &storage.AccountPropertiesUpdateParameters{ Encryption: &storage.Encryption{ - KeySource: storage.KeySource(storage.MicrosoftStorage), + KeySource: storage.MicrosoftStorage, }, }, } @@ -234,7 +233,7 @@ func resourceArmStorageAccountEncryptionSettingsDelete(d *schema.ResourceData, m func expandAzureRmStorageAccountKeyVaultProperties(d *schema.ResourceData) *storage.KeyVaultProperties { vs := d.Get("key_vault").([]interface{}) - if vs == nil || len(vs) == 0 { + if len(vs) == 0 { return &storage.KeyVaultProperties{} } From 9e3e253f1f174f2219822ca79f489b7192d25664 Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Fri, 22 Feb 2019 12:36:09 -0800 Subject: [PATCH 10/16] Updating the documentation --- website/azurerm.erb | 4 + website/docs/r/storage_account.html.markdown | 16 --- ..._account_encryption_settings.html.markdown | 133 ++++++++++++++++++ 3 files changed, 137 insertions(+), 16 deletions(-) create mode 100644 website/docs/r/storage_account_encryption_settings.html.markdown diff --git a/website/azurerm.erb b/website/azurerm.erb index 3d1150a68e3c..6665d279ad9f 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -1211,6 +1211,10 @@ azurerm_storage_account + > + azurerm_storage_account_encryption_settings + + > azurerm_storage_blob diff --git a/website/docs/r/storage_account.html.markdown b/website/docs/r/storage_account.html.markdown index ad649e411b6d..7464d447bfce 100644 --- a/website/docs/r/storage_account.html.markdown +++ b/website/docs/r/storage_account.html.markdown @@ -97,17 +97,9 @@ The following arguments are supported: * `access_tier` - (Optional) Defines the access tier for `BlobStorage` and `StorageV2` accounts. Valid options are `Hot` and `Cool`, defaults to `Hot`. -* `enable_blob_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. Defaults to `true`. - -* `enable_file_encryption` - (Optional) Boolean flag which controls if Encryption Services are enabled for File storage, see [here](https://azure.microsoft.com/en-us/documentation/articles/storage-service-encryption/) for more information. Defaults to `true`. - * `enable_https_traffic_only` - (Optional) Boolean flag which forces HTTPS if enabled, see [here](https://docs.microsoft.com/en-us/azure/storage/storage-require-secure-transfer/) for more information. -* `account_encryption_source` - (Optional) The Encryption Source for this Storage Account. Possible values are `Microsoft.Keyvault` and `Microsoft.Storage`. Defaults to `Microsoft.Storage`. - -* `key_vault_properties` - (Optional) A `key_vault_properties` block as documented below. - * `custom_domain` - (Optional) A `custom_domain` block as documented below. * `network_rules` - (Optional) A `network_rules` block as documented below. @@ -118,14 +110,6 @@ The following arguments are supported: --- -* `key_vault_properties` supports the following: - -* `key_name` - (Required) The name of Key Vault key. -* `key_version` - (Required) The version of Key Vault key. -* `key_vault_uri` - (Required) The Uri of Key Vault. - ---- - * `custom_domain` supports the following: * `name` - (Optional) The Custom Domain Name to use for the Storage Account, which will be validated by Azure. diff --git a/website/docs/r/storage_account_encryption_settings.html.markdown b/website/docs/r/storage_account_encryption_settings.html.markdown new file mode 100644 index 000000000000..1a5b1c3e9e5b --- /dev/null +++ b/website/docs/r/storage_account_encryption_settings.html.markdown @@ -0,0 +1,133 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_storage_account_encryption_settings" +sidebar_current: "docs-azurerm-resource-storage-account-encryption-settings" +description: |- + Manages the encryption settings of an Azure Storage Account. +--- + +# azurerm_storage_account_encryption_settings + +Manages the encryption settings of an Azure Storage Account. + +## Example Usage + +```hcl +resource "azurerm_storage_account_encryption_settings" "custom" { + storage_account_id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfex-RG/providers/Microsoft.Storage/storageAccounts/tfexstorageaccount" + + key_vault { + key_vault_policy_id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfex-RG/providers/Microsoft.KeyVault/vaults/tfex-key-vault/objectId/00000000-0000-0000-0000-000000000000" + key_vault_id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfex-RG/providers/Microsoft.KeyVault/vaults/tfex-key-vault" + key_name = "tfex-key" + key_version = "955b9ad9579e4501a311df5493bacd02" + } +} +``` + +## Example Usage with User Managed Key Vault Key + +```hcl +resource "azurerm_resource_group" "tfex" { + name = "tfex-RG" + location = "westeurope" +} + +resource "azurerm_key_vault" "tfex" { + name = "tfex-key-vault" + location = "${azurerm_resource_group.tfex.location}" + resource_group_name = "${azurerm_resource_group.tfex.name}" + enabled_for_disk_encryption = true + tenant_id = "00000000-0000-0000-0000-000000000000" + + sku { + name = "standard" + } + + tags { + environment = "testing" + } +} + +resource "azurerm_key_vault_key" "tfex" { + name = "tfex-key" + key_vault_id = "${azurerm_key_vault.tfex.id}" + key_type = "RSA" + key_size = 2048 + key_opts = ["decrypt", "encrypt", "sign", "unwrapKey", "verify", "wrapKey"] +} + +resource "azurerm_key_vault_access_policy" "tfex" { + key_vault_id = "${azurerm_key_vault.tfex.id}" + tenant_id = "00000000-0000-0000-0000-000000000000" + object_id = "${azurerm_storage_account.tfex.identity.0.principal_id}" + + key_permissions = ["get","create","delete","list","restore","recover","unwrapkey","wrapkey","purge","encrypt","decrypt","sign","verify"] + secret_permissions = ["get"] +} + +resource "azurerm_storage_account" "tfex" { + name = "tfexstorageaccount" + resource_group_name = "${azurerm_resource_group.tfex.name}" + location = "${azurerm_resource_group.tfex.location}" + account_tier = "Standard" + account_replication_type = "GRS" + + identity { + type = "SystemAssigned" + } + + tags { + environment = "testing" + } +} + +resource "azurerm_storage_account_encryption_settings" "custom" { + storage_account_id = "${azurerm_storage_account.tfex.id}" + + key_vault { + key_vault_policy_id = "${azurerm_key_vault_access_policy.tfex.id}" + key_vault_id = "${azurerm_key_vault.tfex.id}" + key_name = "${azurerm_key_vault_key.tfex.name}" + key_version = "${azurerm_key_vault_key.tfex.version}" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `storage_account_id` - (Required) The id of the storage account to manage the encryption settings for. + +* `enable_blob_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. Defaults to `true`. + +* `enable_file_encryption` - (Optional) Boolean flag which controls if Encryption Services are enabled for File storage, see [here](https://azure.microsoft.com/en-us/documentation/articles/storage-service-encryption/) for more information. Defaults to `true`. + +* `key_vault` - (Optional) A `key_vault` block as documented below. + +--- + +* `key_vault` supports the following: + +* `key_vault_id` - (Required) The id of the Key Vault. +* `key_vault_policy_id` - (Required) The id of the `azurerm_key_vault_access_policy` resource granting the service account access to the key vault. +* `key_name` - (Required) The name of Key Vault key. +* `key_version` - (Required) The version of Key Vault key. + +## Attributes Reference + +The following attributes are exported in addition to the arguments listed above: + +* `id` - The storage account encryption settings Resource ID. +* `key_vault_uri` - The base URI of the Key Vault. + +--- + +## Import + +Storage Accounts Encryption Settings can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_storage_account_encryption_settings.tfex /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myresourcegroup/providers/Microsoft.Storage/storageAccounts/myaccount +``` From ab76c5d9e306f15fad51b61d134957642a6d6edf Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Fri, 22 Feb 2019 12:43:42 -0800 Subject: [PATCH 11/16] Updated documentation --- .../docs/r/storage_account_encryption_settings.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/r/storage_account_encryption_settings.html.markdown b/website/docs/r/storage_account_encryption_settings.html.markdown index 1a5b1c3e9e5b..310b66aae56e 100644 --- a/website/docs/r/storage_account_encryption_settings.html.markdown +++ b/website/docs/r/storage_account_encryption_settings.html.markdown @@ -110,8 +110,8 @@ The following arguments are supported: * `key_vault` supports the following: -* `key_vault_id` - (Required) The id of the Key Vault. -* `key_vault_policy_id` - (Required) The id of the `azurerm_key_vault_access_policy` resource granting the service account access to the key vault. +* `key_vault_id` - (Required) The ID of the Key Vault. +* `key_vault_policy_id` - (Required) The resource ID of the `azurerm_key_vault_access_policy` granting the storage account access to the key vault. * `key_name` - (Required) The name of Key Vault key. * `key_version` - (Required) The version of Key Vault key. From 5a8c2023b6de11384ba3608f7d266605ee4e16f4 Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Fri, 22 Feb 2019 17:01:57 -0800 Subject: [PATCH 12/16] Updated storage account data source and added import function --- azurerm/data_source_storage_account.go | 27 ---------- ...arm_storage_account_encryption_settings.go | 54 ++++++++++++++++++- 2 files changed, 53 insertions(+), 28 deletions(-) diff --git a/azurerm/data_source_storage_account.go b/azurerm/data_source_storage_account.go index c205d36fbba0..4fb9ebf2c84b 100644 --- a/azurerm/data_source_storage_account.go +++ b/azurerm/data_source_storage_account.go @@ -42,11 +42,6 @@ func dataSourceArmStorageAccount() *schema.Resource { Computed: true, }, - "account_encryption_source": { - Type: schema.TypeString, - Computed: true, - }, - "custom_domain": { Type: schema.TypeList, Computed: true, @@ -61,16 +56,6 @@ func dataSourceArmStorageAccount() *schema.Resource { }, }, - "enable_blob_encryption": { - Type: schema.TypeBool, - Computed: true, - }, - - "enable_file_encryption": { - Type: schema.TypeBool, - Computed: true, - }, - "enable_https_traffic_only": { Type: schema.TypeBool, Computed: true, @@ -208,18 +193,6 @@ func dataSourceArmStorageAccountRead(d *schema.ResourceData, meta interface{}) e } } - if encryption := props.Encryption; encryption != nil { - if services := encryption.Services; services != nil { - if blob := services.Blob; blob != nil { - d.Set("enable_blob_encryption", blob.Enabled) - } - if file := services.File; file != nil { - d.Set("enable_file_encryption", file.Enabled) - } - } - d.Set("account_encryption_source", string(encryption.KeySource)) - } - // Computed d.Set("primary_location", props.PrimaryLocation) d.Set("secondary_location", props.SecondaryLocation) diff --git a/azurerm/resource_arm_storage_account_encryption_settings.go b/azurerm/resource_arm_storage_account_encryption_settings.go index 1cd1359bc084..d536707a7398 100644 --- a/azurerm/resource_arm_storage_account_encryption_settings.go +++ b/azurerm/resource_arm_storage_account_encryption_settings.go @@ -18,7 +18,7 @@ func resourceArmStorageAccountEncryptionSettings() *schema.Resource { Delete: resourceArmStorageAccountEncryptionSettingsDelete, Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + State: resourceArmStorageAccountEncryptionSettingsImportState, }, SchemaVersion: 2, @@ -231,6 +231,58 @@ func resourceArmStorageAccountEncryptionSettingsDelete(d *schema.ResourceData, m return nil } +func resourceArmStorageAccountEncryptionSettingsImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + ctx := meta.(*ArmClient).StopContext + client := meta.(*ArmClient).storageServiceClient + + id := d.Id() + + d.Set("storage_account_id", id) + + saId, err := parseAzureResourceID(id) + if err != nil { + return nil, err + } + name := saId.Path["storageAccounts"] + resGroup := saId.ResourceGroup + + resp, err := client.GetProperties(ctx, resGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil, nil + } + return nil, fmt.Errorf("Error importing the state of AzureRM Storage Account %q: %+v", name, err) + } + + if props := resp.AccountProperties; props != nil { + if encryption := props.Encryption; encryption != nil { + if services := encryption.Services; services != nil { + if blob := services.Blob; blob != nil { + d.Set("enable_blob_encryption", blob.Enabled) + } + if file := services.File; file != nil { + d.Set("enable_file_encryption", file.Enabled) + } + } + + if keyVaultProperties := encryption.KeyVaultProperties; keyVaultProperties != nil { + if err := d.Set("key_vault", flattenAzureRmStorageAccountKeyVaultProperties(keyVaultProperties, "", "")); err != nil { + return nil, fmt.Errorf("Error flattening `key_vault_properties` on import: %+v", err) + } + } + } + } + + resourceId := fmt.Sprintf("%s/encryptionSettings", id) + d.SetId(resourceId) + + results := make([]*schema.ResourceData, 1) + + results[0] = d + return results, nil +} + func expandAzureRmStorageAccountKeyVaultProperties(d *schema.ResourceData) *storage.KeyVaultProperties { vs := d.Get("key_vault").([]interface{}) if len(vs) == 0 { From 17b78064a371b9158da376050877fb279ebda1b0 Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Tue, 26 Feb 2019 17:57:09 -0800 Subject: [PATCH 13/16] Added test cases --- ...torage_account_encryption_settings_test.go | 389 ++++++++++++++++++ azurerm/resource_arm_storage_account_test.go | 305 -------------- ..._account_encryption_settings.html.markdown | 4 +- 3 files changed, 391 insertions(+), 307 deletions(-) create mode 100644 azurerm/resource_arm_storage_account_encryption_settings_test.go diff --git a/azurerm/resource_arm_storage_account_encryption_settings_test.go b/azurerm/resource_arm_storage_account_encryption_settings_test.go new file mode 100644 index 000000000000..ea3ccdce1c2f --- /dev/null +++ b/azurerm/resource_arm_storage_account_encryption_settings_test.go @@ -0,0 +1,389 @@ +package azurerm + +import ( + "fmt" + "net/http" + "os" + "testing" + + "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2017-10-01/storage" + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func TestAccAzureRMStorageAccountEncryptionSettings_basic(t *testing.T) { + parentResourceName := "azurerm_storage_account.testsa" + resourceName := "azurerm_storage_account_encryption_settings.custom" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + location := testLocation() + preConfig := testAccAzureRMStorageAccountEncryptionSettings_basic(ri, rs, location) + postConfig := testAccAzureRMStorageAccountEncryptionSettings_basicDelete(ri, rs, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageAccountDestroyed, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageAccountEncryptionSettingsExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "enable_blob_encryption", "true"), + resource.TestCheckResourceAttr(resourceName, "enable_file_encryption", "true"), + ), + }, + { + // Delete the encryption settings resource and verify it is gone + // Whilst making sure the encryption settings on the storage account + // have been reverted to their default state + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageAccountExistsWithDefaultSettings(parentResourceName), + testCheckAzureRMStorageAccountEncryptionSettingsDestroyed(resourceName), + ), + }, + }, + }) +} + +func TestAccAzureRMStorageAccountEncryptionSettings_blobEncryptionDisable(t *testing.T) { + _, exists := os.LookupEnv("TF_ACC_STORAGE_ENCRYPTION_DISABLE") + if !exists { + t.Skip("`TF_ACC_STORAGE_ENCRYPTION_DISABLE` isn't specified - skipping since disabling encryption is generally disabled") + } + + resourceName := "azurerm_storage_account_encryption_settings.custom" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + location := testLocation() + config := testAccAzureRMStorageAccountEncryptionSettings_blobEncryptionDisabled(ri, rs, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageAccountDestroyed, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageAccountEncryptionSettingsExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "enable_blob_encryption", "false"), + ), + }, + }, + }) +} + +func TestAccAzureRMStorageAccountEncryptionSettings_fileEncryptionDisable(t *testing.T) { + _, exists := os.LookupEnv("TF_ACC_STORAGE_ENCRYPTION_DISABLE") + if !exists { + t.Skip("`TF_ACC_STORAGE_ENCRYPTION_DISABLE` isn't specified - skipping since disabling encryption is generally disabled") + } + + resourceName := "azurerm_storage_account_encryption_settings.custom" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + location := testLocation() + config := testAccAzureRMStorageAccountEncryptionSettings_fileEncryptionDisabled(ri, rs, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageAccountDestroyed, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageAccountEncryptionSettingsExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "enable_file_encryption", "false"), + ), + }, + }, + }) +} + +func TestAccAzureRMStorageAccountEncryptionSettings_disappears(t *testing.T) { + parentResourceName := "azurerm_storage_account.testsa" + resourceName := "azurerm_storage_account_encryption_settings.custom" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + preConfig := testAccAzureRMStorageAccountEncryptionSettings_basic(ri, rs, testLocation()) + postConfig := testAccAzureRMStorageAccountEncryptionSettings_basicDelete(ri, rs, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageAccountDestroyed, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageAccountEncryptionSettingsExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "enable_blob_encryption", "true"), + resource.TestCheckResourceAttr(resourceName, "enable_file_encryption", "true"), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageAccountExistsWithDefaultSettings(parentResourceName), + testCheckAzureRMStorageAccountEncryptionSettingsDestroyed(resourceName), + ), + }, + }, + }) +} + +func testCheckAzureRMStorageAccountExistsWithDefaultSettings(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + storageAccount := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + // Ensure resource group exists in API + ctx := testAccProvider.Meta().(*ArmClient).StopContext + conn := testAccProvider.Meta().(*ArmClient).storageServiceClient + + resp, err := conn.GetProperties(ctx, resourceGroup, storageAccount) + if err != nil { + return fmt.Errorf("Bad: Get on storageServiceClient: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: StorageAccount %q (resource group: %q) does not exist", storageAccount, resourceGroup) + } + + if props := resp.AccountProperties; props != nil { + if encryption := props.Encryption; encryption != nil { + if services := encryption.Services; services != nil { + if !*services.Blob.Enabled { + return fmt.Errorf("enable_blob_encryption not set to default: %s", resourceName) + } + if !*services.File.Enabled { + return fmt.Errorf("enable_file_encryption not set to default: %s", resourceName) + } + } + + if encryption.KeySource != storage.MicrosoftStorage { + return fmt.Errorf("%s keySource not set to default(storage.MicrosoftStorage): %s", resourceName, encryption.KeySource) + } + } else { + return fmt.Errorf("storage account encryption properties not found: %s", resourceName) + } + } + + return nil + } +} + +func testCheckAzureRMStorageAccountEncryptionSettingsExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + if storageAccountId := rs.Primary.Attributes["storage_account_id"]; storageAccountId == "" { + return fmt.Errorf("Unable to read storageAccountId: %s", resourceName) + } + + return nil + } +} + +func testCheckAzureRMStorageAccountDelete(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + storageAccount := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + // Ensure resource group exists in API + ctx := testAccProvider.Meta().(*ArmClient).StopContext + conn := testAccProvider.Meta().(*ArmClient).storageServiceClient + + if _, err := conn.Delete(ctx, resourceGroup, storageAccount); err != nil { + return fmt.Errorf("Bad: Delete on storageServiceClient: %+v", err) + } + + return nil + } +} + +func testCheckAzureRMStorageAccountDestroyed(s *terraform.State) error { + ctx := testAccProvider.Meta().(*ArmClient).StopContext + conn := testAccProvider.Meta().(*ArmClient).storageServiceClient + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_storage_account" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := conn.GetProperties(ctx, resourceGroup, name) + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Storage Account still exists:\n%#v", resp.AccountProperties) + } + } + + return nil +} + +func testCheckAzureRMStorageAccountEncryptionSettingsDestroyed(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + _, ok := s.RootModule().Resources[resourceName] + if !ok { + return nil + } + + return fmt.Errorf("Found: %s", resourceName) + } +} + +func testCheckAzureRMStorageAccountEncryptionSettingsDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_storage_account_encryption_settings" { + continue + } + + return fmt.Errorf("Storage Account Encryption Settings still exists\n") + } + + return nil +} + +func testAccAzureRMStorageAccountEncryptionSettings_basic(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "testrg" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_storage_account" "testsa" { + name = "unlikely23exst2acct%s" + resource_group_name = "${azurerm_resource_group.testrg.name}" + + location = "${azurerm_resource_group.testrg.location}" + account_tier = "Standard" + account_replication_type = "LRS" + + tags { + environment = "production" + } +} + +resource "azurerm_storage_account_encryption_settings" "custom" { + storage_account_id = "${azurerm_storage_account.testsa.id}" + enable_blob_encryption = true + enable_file_encryption = true +} +`, rInt, location, rString) +} + +func testAccAzureRMStorageAccountEncryptionSettings_basicDelete(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "testrg" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_storage_account" "testsa" { + name = "unlikely23exst2acct%s" + resource_group_name = "${azurerm_resource_group.testrg.name}" + + location = "${azurerm_resource_group.testrg.location}" + account_tier = "Standard" + account_replication_type = "LRS" + + tags { + environment = "production" + } +} +`, rInt, location, rString) +} + +func testAccAzureRMStorageAccountEncryptionSettings_fileEncryptionDisabled(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "testrg" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_storage_account" "testsa" { + name = "unlikely23exst2acct%s" + resource_group_name = "${azurerm_resource_group.testrg.name}" + + location = "${azurerm_resource_group.testrg.location}" + account_tier = "Standard" + account_replication_type = "LRS" + + tags { + environment = "production" + } +} + +resource "azurerm_storage_account_encryption_settings" "custom" { + storage_account_id = "${azurerm_storage_account.testsa.id} + enable_file_encryption = false" +} +`, rInt, location, rString) +} + +func testAccAzureRMStorageAccountEncryptionSettings_blobEncryptionDisabled(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "testrg" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_storage_account" "testsa" { + name = "unlikely23exst2acct%s" + resource_group_name = "${azurerm_resource_group.testrg.name}" + + location = "${azurerm_resource_group.testrg.location}" + account_tier = "Standard" + account_replication_type = "LRS" + + tags { + environment = "production" + } +} + +resource "azurerm_storage_account_encryption_settings" "custom" { + storage_account_id = "${azurerm_storage_account.testsa.id} + enable_blob_encryption = false" +} +`, rInt, location, rString) +} + +func testAccAzureRMStorageAccountEncryptionSettings_requiresImport(rInt int, rString string, location string) string { + template := testAccAzureRMStorageAccountEncryptionSettings_basic(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_storage_account_encryption_settings" "import" { + storage_account_id = "${azurerm_storage_account.testrg.id}" + enable_blob_encryption = "true" + enable_file_encryption = "true" +} +`, template) +} diff --git a/azurerm/resource_arm_storage_account_test.go b/azurerm/resource_arm_storage_account_test.go index 954a91e2881a..2399ddd41641 100644 --- a/azurerm/resource_arm_storage_account_test.go +++ b/azurerm/resource_arm_storage_account_test.go @@ -3,7 +3,6 @@ package azurerm import ( "fmt" "net/http" - "os" "regexp" "testing" @@ -206,88 +205,6 @@ func TestAccAzureRMStorageAccount_blobConnectionString(t *testing.T) { }) } -func TestAccAzureRMStorageAccount_blobEncryption(t *testing.T) { - _, exists := os.LookupEnv("TF_ACC_STORAGE_ENCRYPTION_DISABLE") - if !exists { - t.Skip("`TF_ACC_STORAGE_ENCRYPTION_DISABLE` isn't specified - skipping since disabling encryption is generally disabled") - } - - resourceName := "azurerm_storage_account.testsa" - ri := tf.AccRandTimeInt() - rs := acctest.RandString(4) - location := testLocation() - preConfig := testAccAzureRMStorageAccount_blobEncryption(ri, rs, location) - postConfig := testAccAzureRMStorageAccount_blobEncryptionDisabled(ri, rs, location) - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMStorageAccountDestroy, - Steps: []resource.TestStep{ - { - Config: preConfig, - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMStorageAccountExists(resourceName), - resource.TestCheckResourceAttr("azurerm_storage_account.testsa", "enable_blob_encryption", "true"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - { - Config: postConfig, - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMStorageAccountExists(resourceName), - resource.TestCheckResourceAttr("azurerm_storage_account.testsa", "enable_blob_encryption", "false"), - ), - }, - }, - }) -} - -func TestAccAzureRMStorageAccount_fileEncryption(t *testing.T) { - _, exists := os.LookupEnv("TF_ACC_STORAGE_ENCRYPTION_DISABLE") - if !exists { - t.Skip("`TF_ACC_STORAGE_ENCRYPTION_DISABLE` isn't specified - skipping since disabling encryption is generally disabled") - } - - resourceName := "azurerm_storage_account.testsa" - ri := tf.AccRandTimeInt() - rs := acctest.RandString(4) - location := testLocation() - preConfig := testAccAzureRMStorageAccount_fileEncryption(ri, rs, location) - postConfig := testAccAzureRMStorageAccount_fileEncryptionDisabled(ri, rs, location) - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMStorageAccountDestroy, - Steps: []resource.TestStep{ - { - Config: preConfig, - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMStorageAccountExists(resourceName), - resource.TestCheckResourceAttr("azurerm_storage_account.testsa", "enable_file_encryption", "true"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - { - Config: postConfig, - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMStorageAccountExists(resourceName), - resource.TestCheckResourceAttr("azurerm_storage_account.testsa", "enable_file_encryption", "false"), - ), - }, - }, - }) -} - func TestAccAzureRMStorageAccount_enableHttpsTrafficOnly(t *testing.T) { resourceName := "azurerm_storage_account.testsa" ri := tf.AccRandTimeInt() @@ -561,41 +478,6 @@ func TestAccAzureRMStorageAccount_networkRulesDeleted(t *testing.T) { }) } -func TestAccAzureRMStorageAccount_keyVault(t *testing.T) { - resourceName := "azurerm_storage_account.testsa" - ri := acctest.RandInt() - rs := acctest.RandString(4) - location := testLocation() - preConfig := testAccAzureRMStorageAccount_identity(ri, rs, location) - postConfig := testAccAzureRMStorageAccount_keyvault(ri, rs, location) - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMStorageAccountDestroy, - Steps: []resource.TestStep{ - { - Config: preConfig, - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMStorageAccountExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "account_encryption_source", "Microsoft.Storage"), - ), - }, - { - Config: postConfig, - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMStorageAccountExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "account_encryption_source", "Microsoft.KeyVault"), - resource.TestCheckResourceAttr(resourceName, "key_vault_properties.#", "1"), - resource.TestCheckResourceAttrSet(resourceName, "key_vault_properties.0.key_name"), - resource.TestCheckResourceAttrSet(resourceName, "key_vault_properties.0.key_version"), - resource.TestCheckResourceAttrSet(resourceName, "key_vault_properties.0.key_vault_uri"), - ), - }, - }, - }) -} - func testCheckAzureRMStorageAccountExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { // Ensure we have enough information in state to look up in API @@ -753,98 +635,6 @@ resource "azurerm_storage_account" "testsa" { `, rInt, location, rString) } -func testAccAzureRMStorageAccount_blobEncryption(rInt int, rString string, location string) string { - return fmt.Sprintf(` -resource "azurerm_resource_group" "testrg" { - name = "acctestAzureRMSA-%d" - location = "%s" -} - -resource "azurerm_storage_account" "testsa" { - name = "unlikely23exst2acct%s" - resource_group_name = "${azurerm_resource_group.testrg.name}" - - location = "${azurerm_resource_group.testrg.location}" - account_tier = "Standard" - account_replication_type = "LRS" - enable_blob_encryption = true - - tags { - environment = "production" - } -} -`, rInt, location, rString) -} - -func testAccAzureRMStorageAccount_blobEncryptionDisabled(rInt int, rString string, location string) string { - return fmt.Sprintf(` -resource "azurerm_resource_group" "testrg" { - name = "acctestAzureRMSA-%d" - location = "%s" -} - -resource "azurerm_storage_account" "testsa" { - name = "unlikely23exst2acct%s" - resource_group_name = "${azurerm_resource_group.testrg.name}" - - location = "${azurerm_resource_group.testrg.location}" - account_tier = "Standard" - account_replication_type = "LRS" - enable_blob_encryption = false - - tags { - environment = "production" - } -} -`, rInt, location, rString) -} - -func testAccAzureRMStorageAccount_fileEncryption(rInt int, rString string, location string) string { - return fmt.Sprintf(` -resource "azurerm_resource_group" "testrg" { - name = "acctestAzureRMSA-%d" - location = "%s" -} - -resource "azurerm_storage_account" "testsa" { - name = "unlikely23exst2acct%s" - resource_group_name = "${azurerm_resource_group.testrg.name}" - - location = "${azurerm_resource_group.testrg.location}" - account_tier = "Standard" - account_replication_type = "LRS" - enable_file_encryption = true - - tags { - environment = "production" - } -} -`, rInt, location, rString) -} - -func testAccAzureRMStorageAccount_fileEncryptionDisabled(rInt int, rString string, location string) string { - return fmt.Sprintf(` -resource "azurerm_resource_group" "testrg" { - name = "acctestAzureRMSA-%d" - location = "%s" -} - -resource "azurerm_storage_account" "testsa" { - name = "unlikely23exst2acct%s" - resource_group_name = "${azurerm_resource_group.testrg.name}" - - location = "${azurerm_resource_group.testrg.location}" - account_tier = "Standard" - account_replication_type = "LRS" - enable_file_encryption = false - - tags { - environment = "production" - } -} -`, rInt, location, rString) -} - func testAccAzureRMStorageAccount_enableHttpsTrafficOnly(rInt int, rString string, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "testrg" { @@ -1113,98 +903,3 @@ resource "azurerm_storage_account" "testsa" { } `, rInt, location, rInt, rInt, rString) } - -func testAccAzureRMStorageAccount_keyvault(rInt int, rString string, location string) string { - return fmt.Sprintf(` -resource "azurerm_resource_group" "testrg" { - name = "testAccAzureRMSA-%d" - location = "%s" -} - -data "azurerm_client_config" "current" {} - -resource "azurerm_key_vault" "test" { - name = "testAccKv-%s" - location = "${azurerm_resource_group.testrg.location}" - resource_group_name = "${azurerm_resource_group.testrg.name}" - - sku { - name = "standard" - } - - tenant_id = "${data.azurerm_client_config.current.tenant_id}" -} - -resource "azurerm_key_vault_access_policy" "sp" { - vault_name = "${azurerm_key_vault.test.name}" - resource_group_name = "${azurerm_resource_group.testrg.name}" - - tenant_id = "${data.azurerm_client_config.current.tenant_id}" - object_id = "${data.azurerm_client_config.current.service_principal_object_id}" - - key_permissions = [ - "get", - "create", - "list", - "delete", - ] - - secret_permissions = [] -} - -resource "azurerm_key_vault_access_policy" "storage" { - vault_name = "${azurerm_key_vault.test.name}" - resource_group_name = "${azurerm_resource_group.testrg.name}" - - tenant_id = "${azurerm_storage_account.testsa.identity.0.tenant_id}" - object_id = "${azurerm_storage_account.testsa.identity.0.principal_id}" - - key_permissions = [ - "get", - "wrapKey", - "unwrapKey", - ] - - secret_permissions = [] - } - -resource "azurerm_key_vault_key" "test" { - depends_on = ["azurerm_key_vault_access_policy.sp"] - - name = "testAccKey-%d" - vault_uri = "${azurerm_key_vault.test.vault_uri}" - key_type = "RSA" - key_size = 2048 - - key_opts = [ - "decrypt", - "encrypt", - "sign", - "unwrapKey", - "verify", - "wrapKey", - ] -} - -resource "azurerm_storage_account" "testsa" { - name = "unlikely23exst2acct%s" - resource_group_name = "${azurerm_resource_group.testrg.name}" - location = "${azurerm_resource_group.testrg.location}" - - account_tier = "Standard" - account_replication_type = "LRS" - - account_encryption_source = "Microsoft.KeyVault" - - key_vault_properties { - key_name = "${azurerm_key_vault_key.test.name}" - key_version = "${azurerm_key_vault_key.test.version}" - key_vault_uri = "${azurerm_key_vault.test.vault_uri}" - } - - tags { - environment = "production" - } -} -`, rInt, location, rString, rInt, rString) -} diff --git a/website/docs/r/storage_account_encryption_settings.html.markdown b/website/docs/r/storage_account_encryption_settings.html.markdown index 310b66aae56e..0eaf0a9b6c24 100644 --- a/website/docs/r/storage_account_encryption_settings.html.markdown +++ b/website/docs/r/storage_account_encryption_settings.html.markdown @@ -13,7 +13,7 @@ Manages the encryption settings of an Azure Storage Account. ## Example Usage ```hcl -resource "azurerm_storage_account_encryption_settings" "custom" { +resource "azurerm_storage_account_encryption_settings" "tfex" { storage_account_id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfex-RG/providers/Microsoft.Storage/storageAccounts/tfexstorageaccount" key_vault { @@ -82,7 +82,7 @@ resource "azurerm_storage_account" "tfex" { } } -resource "azurerm_storage_account_encryption_settings" "custom" { +resource "azurerm_storage_account_encryption_settings" "tfex" { storage_account_id = "${azurerm_storage_account.tfex.id}" key_vault { From 0f0e22aff8c01ea4512dd6dc834b1eed347de20d Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Wed, 27 Feb 2019 14:02:39 -0800 Subject: [PATCH 14/16] Removed unused test functions --- ...torage_account_encryption_settings_test.go | 48 ------------------- 1 file changed, 48 deletions(-) diff --git a/azurerm/resource_arm_storage_account_encryption_settings_test.go b/azurerm/resource_arm_storage_account_encryption_settings_test.go index ea3ccdce1c2f..751b0b733fa6 100644 --- a/azurerm/resource_arm_storage_account_encryption_settings_test.go +++ b/azurerm/resource_arm_storage_account_encryption_settings_test.go @@ -200,29 +200,6 @@ func testCheckAzureRMStorageAccountEncryptionSettingsExists(resourceName string) } } -func testCheckAzureRMStorageAccountDelete(resourceName string) resource.TestCheckFunc { - return func(s *terraform.State) error { - // Ensure we have enough information in state to look up in API - rs, ok := s.RootModule().Resources[resourceName] - if !ok { - return fmt.Errorf("Not found: %s", resourceName) - } - - storageAccount := rs.Primary.Attributes["name"] - resourceGroup := rs.Primary.Attributes["resource_group_name"] - - // Ensure resource group exists in API - ctx := testAccProvider.Meta().(*ArmClient).StopContext - conn := testAccProvider.Meta().(*ArmClient).storageServiceClient - - if _, err := conn.Delete(ctx, resourceGroup, storageAccount); err != nil { - return fmt.Errorf("Bad: Delete on storageServiceClient: %+v", err) - } - - return nil - } -} - func testCheckAzureRMStorageAccountDestroyed(s *terraform.State) error { ctx := testAccProvider.Meta().(*ArmClient).StopContext conn := testAccProvider.Meta().(*ArmClient).storageServiceClient @@ -259,18 +236,6 @@ func testCheckAzureRMStorageAccountEncryptionSettingsDestroyed(resourceName stri } } -func testCheckAzureRMStorageAccountEncryptionSettingsDestroy(s *terraform.State) error { - for _, rs := range s.RootModule().Resources { - if rs.Type != "azurerm_storage_account_encryption_settings" { - continue - } - - return fmt.Errorf("Storage Account Encryption Settings still exists\n") - } - - return nil -} - func testAccAzureRMStorageAccountEncryptionSettings_basic(rInt int, rString string, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "testrg" { @@ -374,16 +339,3 @@ resource "azurerm_storage_account_encryption_settings" "custom" { } `, rInt, location, rString) } - -func testAccAzureRMStorageAccountEncryptionSettings_requiresImport(rInt int, rString string, location string) string { - template := testAccAzureRMStorageAccountEncryptionSettings_basic(rInt, rString, location) - return fmt.Sprintf(` -%s - -resource "azurerm_storage_account_encryption_settings" "import" { - storage_account_id = "${azurerm_storage_account.testrg.id}" - enable_blob_encryption = "true" - enable_file_encryption = "true" -} -`, template) -} From e0cadbcdc002bbf3fb62943ef01123d6e998132b Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Thu, 28 Feb 2019 12:09:52 -0800 Subject: [PATCH 15/16] Removed encyrption tests from storage account test --- azurerm/resource_arm_storage_account_test.go | 92 -------------------- 1 file changed, 92 deletions(-) diff --git a/azurerm/resource_arm_storage_account_test.go b/azurerm/resource_arm_storage_account_test.go index 7d74fe1959da..f174538297d0 100644 --- a/azurerm/resource_arm_storage_account_test.go +++ b/azurerm/resource_arm_storage_account_test.go @@ -635,98 +635,6 @@ resource "azurerm_storage_account" "testsa" { `, rInt, location, rString) } -func testAccAzureRMStorageAccount_blobEncryption(rInt int, rString string, location string) string { - return fmt.Sprintf(` -resource "azurerm_resource_group" "testrg" { - name = "acctestAzureRMSA-%d" - location = "%s" -} - -resource "azurerm_storage_account" "testsa" { - name = "unlikely23exst2acct%s" - resource_group_name = "${azurerm_resource_group.testrg.name}" - - location = "${azurerm_resource_group.testrg.location}" - account_tier = "Standard" - account_replication_type = "LRS" - enable_blob_encryption = true - - tags = { - environment = "production" - } -} -`, rInt, location, rString) -} - -func testAccAzureRMStorageAccount_blobEncryptionDisabled(rInt int, rString string, location string) string { - return fmt.Sprintf(` -resource "azurerm_resource_group" "testrg" { - name = "acctestAzureRMSA-%d" - location = "%s" -} - -resource "azurerm_storage_account" "testsa" { - name = "unlikely23exst2acct%s" - resource_group_name = "${azurerm_resource_group.testrg.name}" - - location = "${azurerm_resource_group.testrg.location}" - account_tier = "Standard" - account_replication_type = "LRS" - enable_blob_encryption = false - - tags = { - environment = "production" - } -} -`, rInt, location, rString) -} - -func testAccAzureRMStorageAccount_fileEncryption(rInt int, rString string, location string) string { - return fmt.Sprintf(` -resource "azurerm_resource_group" "testrg" { - name = "acctestAzureRMSA-%d" - location = "%s" -} - -resource "azurerm_storage_account" "testsa" { - name = "unlikely23exst2acct%s" - resource_group_name = "${azurerm_resource_group.testrg.name}" - - location = "${azurerm_resource_group.testrg.location}" - account_tier = "Standard" - account_replication_type = "LRS" - enable_file_encryption = true - - tags = { - environment = "production" - } -} -`, rInt, location, rString) -} - -func testAccAzureRMStorageAccount_fileEncryptionDisabled(rInt int, rString string, location string) string { - return fmt.Sprintf(` -resource "azurerm_resource_group" "testrg" { - name = "acctestAzureRMSA-%d" - location = "%s" -} - -resource "azurerm_storage_account" "testsa" { - name = "unlikely23exst2acct%s" - resource_group_name = "${azurerm_resource_group.testrg.name}" - - location = "${azurerm_resource_group.testrg.location}" - account_tier = "Standard" - account_replication_type = "LRS" - enable_file_encryption = false - - tags = { - environment = "production" - } -} -`, rInt, location, rString) -} - func testAccAzureRMStorageAccount_enableHttpsTrafficOnly(rInt int, rString string, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "testrg" { From ad2ff1e50f5ee183bb634c7a08e9336627c49f1b Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Fri, 1 Mar 2019 13:54:59 -0800 Subject: [PATCH 16/16] Removed duplicate functions --- azurerm/resource_arm_storage_account.go | 28 ------------------------- 1 file changed, 28 deletions(-) diff --git a/azurerm/resource_arm_storage_account.go b/azurerm/resource_arm_storage_account.go index def882236b8b..d49c9638a10a 100644 --- a/azurerm/resource_arm_storage_account.go +++ b/azurerm/resource_arm_storage_account.go @@ -916,34 +916,6 @@ func validateArmStorageAccountType(v interface{}, _ string) (warnings []string, return warnings, errors } -func expandAzureRmStorageAccountIdentity(d *schema.ResourceData) *storage.Identity { - identities := d.Get("identity").([]interface{}) - identity := identities[0].(map[string]interface{}) - identityType := identity["type"].(string) - return &storage.Identity{ - Type: &identityType, - } -} - -func flattenAzureRmStorageAccountIdentity(identity *storage.Identity) []interface{} { - if identity == nil { - return make([]interface{}, 0) - } - - result := make(map[string]interface{}) - if identity.Type != nil { - result["type"] = *identity.Type - } - if identity.PrincipalID != nil { - result["principal_id"] = *identity.PrincipalID - } - if identity.TenantID != nil { - result["tenant_id"] = *identity.TenantID - } - - return []interface{}{result} -} - func getBlobConnectionString(blobEndpoint *string, acctName *string, acctKey *string) string { var endpoint string if blobEndpoint != nil {