From 87a3f14c564cef14eaeccf8624790762e596b5c1 Mon Sep 17 00:00:00 2001 From: Pratik Date: Mon, 11 Feb 2019 20:44:06 +0530 Subject: [PATCH 01/13] Support more than 16 access policies Key Vault supports up to 1024 access policy entries for a key vault. --- azurerm/resource_arm_key_vault.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azurerm/resource_arm_key_vault.go b/azurerm/resource_arm_key_vault.go index 38fbf51a986b..e02881b42292 100644 --- a/azurerm/resource_arm_key_vault.go +++ b/azurerm/resource_arm_key_vault.go @@ -84,7 +84,7 @@ func resourceArmKeyVault() *schema.Resource { Type: schema.TypeList, Optional: true, Computed: true, - MaxItems: 16, + MaxItems: 1024, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "tenant_id": { From 1be5a03a8fe0ee44efcb85128423286e294e1611 Mon Sep 17 00:00:00 2001 From: Pratik Date: Tue, 12 Feb 2019 22:09:14 +0530 Subject: [PATCH 02/13] updating document for #2866 --- website/docs/r/key_vault_access_policy.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/key_vault_access_policy.html.markdown b/website/docs/r/key_vault_access_policy.html.markdown index 1141a2a8d808..b51a6a41977e 100644 --- a/website/docs/r/key_vault_access_policy.html.markdown +++ b/website/docs/r/key_vault_access_policy.html.markdown @@ -12,7 +12,7 @@ Manages a Key Vault Access Policy. ~> **NOTE:** It's possible to define Key Vault Access Policies both within [the `azurerm_key_vault` resource](key_vault.html) via the `access_policy` block and by using [the `azurerm_key_vault_access_policy` resource](key_vault_access_policy.html). However it's not possible to use both methods to manage Access Policies within a KeyVault, since there'll be conflicts. --> **NOTE:** Azure permits a maximum of 16 Access Policies per Key Vault - [more information can be found in this document](https://docs.microsoft.com/en-us/azure/key-vault/key-vault-secure-your-key-vault#data-plane-access-control). +-> **NOTE:** Azure permits a maximum of 1024 Access Policies per Key Vault - [more information can be found in this document](https://docs.microsoft.com/en-us/azure/key-vault/key-vault-secure-your-key-vault#data-plane-access-control). ## Example Usage From ead5ca71d306735a6c52aafc0b6119353b5d8799 Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Thu, 28 Feb 2019 16:26:53 -0800 Subject: [PATCH 03/13] Update resource_arm_key_vault_key_test.go Added test case for multiple access policies --- azurerm/resource_arm_key_vault_key_test.go | 660 ++++++++++++--------- 1 file changed, 373 insertions(+), 287 deletions(-) diff --git a/azurerm/resource_arm_key_vault_key_test.go b/azurerm/resource_arm_key_vault_key_test.go index daa2579cec70..36ccff5793b9 100644 --- a/azurerm/resource_arm_key_vault_key_test.go +++ b/azurerm/resource_arm_key_vault_key_test.go @@ -2,250 +2,308 @@ package azurerm import ( "fmt" - "log" "testing" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" - - "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/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) -func TestAccAzureRMKeyVaultKey_basicEC(t *testing.T) { - resourceName := "azurerm_key_vault_key.test" - rs := acctest.RandString(6) - config := testAccAzureRMKeyVaultKey_basicEC(rs, testLocation()) +func TestAccAzureRMKeyVault_name(t *testing.T) { + cases := []struct { + Input string + ExpectError bool + }{ + { + Input: "", + ExpectError: true, + }, + { + Input: "hi", + ExpectError: true, + }, + { + Input: "hello", + ExpectError: false, + }, + { + Input: "hello-world", + ExpectError: false, + }, + { + Input: "hello-world-21", + ExpectError: false, + }, + { + Input: "hello_world_21", + ExpectError: true, + }, + { + Input: "Hello-World", + ExpectError: false, + }, + { + Input: "20202020", + ExpectError: false, + }, + { + Input: "ABC123!@£", + ExpectError: true, + }, + { + Input: "abcdefghijklmnopqrstuvwxyz", + ExpectError: true, + }, + } + + for _, tc := range cases { + _, errors := validateKeyVaultName(tc.Input, "") + + hasError := len(errors) > 0 + + if tc.ExpectError && !hasError { + t.Fatalf("Expected the Key Vault Name to trigger a validation error for '%s'", tc.Input) + } + } +} + +func TestAccAzureRMKeyVault_basic(t *testing.T) { + resourceName := "azurerm_key_vault.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMKeyVault_basic(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testCheckAzureRMKeyVaultKeyDestroy, + CheckDestroy: testCheckAzureRMKeyVaultDestroy, Steps: []resource.TestStep{ { Config: config, Check: resource.ComposeTestCheckFunc( - testCheckAzureRMKeyVaultKeyExists(resourceName), + testCheckAzureRMKeyVaultExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "network_acls.#", "0"), ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"key_size"}, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, }, }, }) } -func TestAccAzureRMKeyVaultKey_requiresImport(t *testing.T) { +func TestAccAzureRMKeyVault_requiresImport(t *testing.T) { if !requireResourcesToBeImported { t.Skip("Skipping since resources aren't required to be imported") return } - resourceName := "azurerm_key_vault_key.test" - rs := acctest.RandString(6) + resourceName := "azurerm_key_vault.test" + ri := tf.AccRandTimeInt() location := testLocation() resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testCheckAzureRMKeyVaultKeyDestroy, + CheckDestroy: testCheckAzureRMKeyVaultDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMKeyVaultKey_basicEC(rs, location), + Config: testAccAzureRMKeyVault_basic(ri, location), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMKeyVaultKeyExists(resourceName), + testCheckAzureRMKeyVaultExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "network_acls.#", "0"), ), }, { - Config: testAccAzureRMKeyVaultKey_requiresImport(rs, location), - ExpectError: testRequiresImportError("azurerm_key_vault_key"), + Config: testAccAzureRMKeyVault_requiresImport(ri, location), + ExpectError: testRequiresImportError("azurerm_key_vault"), }, }, }) } -func TestAccAzureRMKeyVaultKey_basicRSA(t *testing.T) { - resourceName := "azurerm_key_vault_key.test" - rs := acctest.RandString(6) - config := testAccAzureRMKeyVaultKey_basicRSA(rs, testLocation()) +func TestAccAzureRMKeyVault_networkAcls(t *testing.T) { + resourceName := "azurerm_key_vault.test" + ri := tf.AccRandTimeInt() + location := testLocation() resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testCheckAzureRMKeyVaultKeyDestroy, + CheckDestroy: testCheckAzureRMKeyVaultDestroy, Steps: []resource.TestStep{ { - Config: config, + Config: testAccAzureRMKeyVault_networkAcls(ri, location), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMKeyVaultKeyExists(resourceName), + testCheckAzureRMKeyVaultExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "network_acls.#", "1"), + resource.TestCheckResourceAttr(resourceName, "network_acls.0.bypass", "None"), + resource.TestCheckResourceAttr(resourceName, "network_acls.0.default_action", "Deny"), + resource.TestCheckResourceAttr(resourceName, "network_acls.0.ip_rules.#", "0"), + resource.TestCheckResourceAttr(resourceName, "network_acls.0.virtual_network_subnet_ids.#", "2"), ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"key_size"}, + Config: testAccAzureRMKeyVault_networkAclsUpdated(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKeyVaultExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "network_acls.#", "1"), + resource.TestCheckResourceAttr(resourceName, "network_acls.0.bypass", "AzureServices"), + resource.TestCheckResourceAttr(resourceName, "network_acls.0.default_action", "Allow"), + resource.TestCheckResourceAttr(resourceName, "network_acls.0.ip_rules.#", "1"), + resource.TestCheckResourceAttr(resourceName, "network_acls.0.virtual_network_subnet_ids.#", "1"), + ), }, }, }) } -func TestAccAzureRMKeyVaultKey_basicRSAHSM(t *testing.T) { - resourceName := "azurerm_key_vault_key.test" - rs := acctest.RandString(6) - config := testAccAzureRMKeyVaultKey_basicRSAHSM(rs, testLocation()) +func TestAccAzureRMKeyVault_accessPolicyUpperLimit(t *testing.T) { + resourceName := "azurerm_key_vault.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMKeyVault_accessPolicyUpperLimit(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testCheckAzureRMKeyVaultKeyDestroy, + CheckDestroy: testCheckAzureRMKeyVaultDestroy, Steps: []resource.TestStep{ { Config: config, Check: resource.ComposeTestCheckFunc( - testCheckAzureRMKeyVaultKeyExists(resourceName), + testCheckAzureRMKeyVaultExists(resourceName), + testCheckAzureRMKeyVaultDisappears(resourceName), ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"key_size"}, + ExpectNonEmptyPlan: true, }, }, }) } -func TestAccAzureRMKeyVaultKey_complete(t *testing.T) { - resourceName := "azurerm_key_vault_key.test" - rs := acctest.RandString(6) - config := testAccAzureRMKeyVaultKey_complete(rs, testLocation()) +func TestAccAzureRMKeyVault_disappears(t *testing.T) { + resourceName := "azurerm_key_vault.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMKeyVault_basic(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testCheckAzureRMKeyVaultKeyDestroy, + CheckDestroy: testCheckAzureRMKeyVaultDestroy, Steps: []resource.TestStep{ { Config: config, Check: resource.ComposeTestCheckFunc( - testCheckAzureRMKeyVaultKeyExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), - resource.TestCheckResourceAttr(resourceName, "tags.hello", "world"), + testCheckAzureRMKeyVaultExists(resourceName), + testCheckAzureRMKeyVaultDisappears(resourceName), ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"key_size"}, + ExpectNonEmptyPlan: true, }, }, }) } -func TestAccAzureRMKeyVaultKey_update(t *testing.T) { - resourceName := "azurerm_key_vault_key.test" - rs := acctest.RandString(6) - config := testAccAzureRMKeyVaultKey_basicRSA(rs, testLocation()) - updatedConfig := testAccAzureRMKeyVaultKey_basicUpdated(rs, testLocation()) +func TestAccAzureRMKeyVault_complete(t *testing.T) { + resourceName := "azurerm_key_vault.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMKeyVault_complete(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testCheckAzureRMKeyVaultKeyDestroy, + CheckDestroy: testCheckAzureRMKeyVaultDestroy, Steps: []resource.TestStep{ { Config: config, Check: resource.ComposeTestCheckFunc( - testCheckAzureRMKeyVaultKeyExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "key_opts.#", "6"), - resource.TestCheckResourceAttr(resourceName, "key_opts.0", "decrypt"), + testCheckAzureRMKeyVaultExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "access_policy.0.application_id"), ), }, { - Config: updatedConfig, - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMKeyVaultKeyExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "key_opts.#", "5"), - resource.TestCheckResourceAttr(resourceName, "key_opts.0", "encrypt"), - ), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, }, }, }) } -func TestAccAzureRMKeyVaultKey_disappears(t *testing.T) { - resourceName := "azurerm_key_vault_key.test" - rs := acctest.RandString(6) - config := testAccAzureRMKeyVaultKey_basicEC(rs, testLocation()) +func TestAccAzureRMKeyVault_update(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_key_vault.test" + preConfig := testAccAzureRMKeyVault_basic(ri, testLocation()) + postConfig := testAccAzureRMKeyVault_update(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testCheckAzureRMKeyVaultKeyDestroy, + CheckDestroy: testCheckAzureRMKeyVaultDestroy, Steps: []resource.TestStep{ { - Config: config, + Config: preConfig, Check: resource.ComposeTestCheckFunc( - testCheckAzureRMKeyVaultKeyExists(resourceName), - testCheckAzureRMKeyVaultKeyDisappears(resourceName), + testCheckAzureRMKeyVaultExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "access_policy.0.key_permissions.0", "create"), + resource.TestCheckResourceAttr(resourceName, "access_policy.0.secret_permissions.0", "set"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "access_policy.0.key_permissions.0", "get"), + resource.TestCheckResourceAttr(resourceName, "access_policy.0.secret_permissions.0", "get"), + resource.TestCheckResourceAttr(resourceName, "enabled_for_deployment", "true"), + resource.TestCheckResourceAttr(resourceName, "enabled_for_disk_encryption", "true"), + resource.TestCheckResourceAttr(resourceName, "enabled_for_template_deployment", "true"), + resource.TestCheckResourceAttr(resourceName, "tags.environment", "Staging"), ), - ExpectNonEmptyPlan: true, }, }, }) } -func TestAccAzureRMKeyVaultKey_disappearsWhenParentKeyVaultDeleted(t *testing.T) { - rs := acctest.RandString(6) - config := testAccAzureRMKeyVaultKey_basicEC(rs, testLocation()) +func TestAccAzureRMKeyVault_justCert(t *testing.T) { + resourceName := "azurerm_key_vault.test" + ri := tf.AccRandTimeInt() resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testCheckAzureRMKeyVaultKeyDestroy, + CheckDestroy: testCheckAzureRMKeyVaultDestroy, Steps: []resource.TestStep{ { - Config: config, + Config: testAccAzureRMKeyVault_justCert(ri, testLocation()), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMKeyVaultKeyExists("azurerm_key_vault_key.test"), - testCheckAzureRMKeyVaultDisappears("azurerm_key_vault.test"), + testCheckAzureRMKeyVaultExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "access_policy.0.certificate_permissions.0", "get"), ), - ExpectNonEmptyPlan: true, + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, }, }, }) } -func testCheckAzureRMKeyVaultKeyDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).keyVaultManagementClient +func testCheckAzureRMKeyVaultDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).keyVaultClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { - if rs.Type != "azurerm_key_vault_key" { + if rs.Type != "azurerm_key_vault" { continue } name := rs.Primary.Attributes["name"] - vaultBaseUrl := rs.Primary.Attributes["vault_uri"] - keyVaultId := rs.Primary.Attributes["key_vault_id"] - - ok, err := azure.KeyVaultExists(ctx, testAccProvider.Meta().(*ArmClient).keyVaultClient, keyVaultId) - if err != nil { - return fmt.Errorf("Error checking if key vault %q for Secret %q in Vault at url %q exists: %v", keyVaultId, name, vaultBaseUrl, err) - } - if !ok { - log.Printf("[DEBUG] Secret %q Key Vault %q was not found in Key Vault at URI %q ", name, keyVaultId, vaultBaseUrl) - return nil - } + resourceGroup := rs.Primary.Attributes["resource_group_name"] - // get the latest version - resp, err := client.GetKey(ctx, vaultBaseUrl, name, "") + resp, err := client.Get(ctx, resourceGroup, name) if err != nil { if utils.ResponseWasNotFound(resp.Response) { return nil @@ -253,96 +311,83 @@ func testCheckAzureRMKeyVaultKeyDestroy(s *terraform.State) error { return err } - return fmt.Errorf("Key Vault Key still exists:\n%#v", resp) + return fmt.Errorf("Key Vault still exists:\n%#v", resp.Properties) } return nil } -func testCheckAzureRMKeyVaultKeyExists(resourceName string) resource.TestCheckFunc { +func testCheckAzureRMKeyVaultExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).keyVaultManagementClient - ctx := testAccProvider.Meta().(*ArmClient).StopContext - // 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) } - name := rs.Primary.Attributes["name"] - vaultBaseUrl := rs.Primary.Attributes["vault_uri"] - keyVaultId := rs.Primary.Attributes["key_vault_id"] - ok, err := azure.KeyVaultExists(ctx, testAccProvider.Meta().(*ArmClient).keyVaultClient, keyVaultId) - if err != nil { - return fmt.Errorf("Error checking if key vault %q for Key %q in Vault at url %q exists: %v", keyVaultId, name, vaultBaseUrl, err) - } - if !ok { - log.Printf("[DEBUG] Key %q Key Vault %q was not found in Key Vault at URI %q ", name, keyVaultId, vaultBaseUrl) - return nil + vaultName := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for vault: %s", vaultName) } - resp, err := client.GetKey(ctx, vaultBaseUrl, name, "") + client := testAccProvider.Meta().(*ArmClient).keyVaultClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, resourceGroup, vaultName) if err != nil { if utils.ResponseWasNotFound(resp.Response) { - return fmt.Errorf("Bad: Key Vault Key %q (resource group: %q) does not exist", name, vaultBaseUrl) + return fmt.Errorf("Bad: Vault %q (resource group: %q) does not exist", vaultName, resourceGroup) } - return fmt.Errorf("Bad: Get on keyVaultManagementClient: %+v", err) + return fmt.Errorf("Bad: Get on keyVaultClient: %+v", err) } return nil } } -func testCheckAzureRMKeyVaultKeyDisappears(resourceName string) resource.TestCheckFunc { +func testCheckAzureRMKeyVaultDisappears(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).keyVaultManagementClient - ctx := testAccProvider.Meta().(*ArmClient).StopContext - // 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) } - name := rs.Primary.Attributes["name"] - vaultBaseUrl := rs.Primary.Attributes["vault_uri"] - keyVaultId := rs.Primary.Attributes["key_vault_id"] - - ok, err := azure.KeyVaultExists(ctx, testAccProvider.Meta().(*ArmClient).keyVaultClient, keyVaultId) - if err != nil { - return fmt.Errorf("Error checking if key vault %q for Key %q in Vault at url %q exists: %v", keyVaultId, name, vaultBaseUrl, err) - } - if !ok { - log.Printf("[DEBUG] Key %q Key Vault %q was not found in Key Vault at URI %q ", name, keyVaultId, vaultBaseUrl) - return nil + vaultName := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for vault: %s", vaultName) } - resp, err := client.DeleteKey(ctx, vaultBaseUrl, name) + client := testAccProvider.Meta().(*ArmClient).keyVaultClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Delete(ctx, resourceGroup, vaultName) if err != nil { - if utils.ResponseWasNotFound(resp.Response) { + if response.WasNotFound(resp.Response) { return nil } - return fmt.Errorf("Bad: Delete on keyVaultManagementClient: %+v", err) + return fmt.Errorf("Bad: Delete on keyVaultClient: %+v", err) } return nil } } -func testAccAzureRMKeyVaultKey_basicEC(rString string, location string) string { +func testAccAzureRMKeyVault_basic(rInt int, location string) string { return fmt.Sprintf(` data "azurerm_client_config" "current" {} resource "azurerm_resource_group" "test" { - name = "acctestRG-%s" + name = "acctestRG-%d" location = "%s" } resource "azurerm_key_vault" "test" { - name = "acctestkv-%s" + name = "vault%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -353,70 +398,155 @@ resource "azurerm_key_vault" "test" { access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" - object_id = "${data.azurerm_client_config.current.service_principal_object_id}" + object_id = "${data.azurerm_client_config.current.client_id}" key_permissions = [ "create", - "delete", - "get", ] secret_permissions = [ - "get", - "delete", "set", ] } +} +`, rInt, location, rInt) +} + +func testAccAzureRMKeyVault_accessPolicyUpperLimit(rInt int, location string) string { + + var storageAccountConfig string + + for i := 50; i < 68; i++ { + storageAccountConfig += testAccAzureRMKeyVault_generateConfig(i) + } + + return fmt.Sprintf(` +data "azurerm_client_config" "current" {} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_key_vault" "test" { + name = "vault%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + + sku { + name = "premium" + } +} + +%s +`, rInt, location, rInt, storageAccountConfig) +} + +func testAccAzureRMKeyVault_generateConfig(accountNum int) string { + return fmt.Sprintf(` +resource "azurerm_storage_account" "testsa%d" { + name = "testsa%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "GRS" + + identity { + type = "SystemAssigned" + } tags { - environment = "Production" + environment = "testing" } } -resource "azurerm_key_vault_key" "test" { - name = "key-%s" - key_vault_id = "${azurerm_key_vault.test.id}" - key_type = "EC" - key_size = 2048 +resource "azurerm_key_vault_access_policy" "policy%d" { + key_vault_id = "${azurerm_key_vault.test.id}" + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + object_id = "${azurerm_storage_account.testsa%d.identity.0.principal_id}" + + key_permissions = ["get","create","delete","list","restore","recover","unwrapkey","wrapkey","purge","encrypt","decrypt","sign","verify"] + secret_permissions = ["get"] - key_opts = [ - "sign", - "verify", - ] + depends_on = ["azurerm_storage_account.testsa%d"] } -`, rString, location, rString, rString) +`, accountNum, accountNum, accountNum, accountNum, accountNum) } -func testAccAzureRMKeyVaultKey_requiresImport(rString string, location string) string { - template := testAccAzureRMKeyVaultKey_basicEC(rString, location) +func testAccAzureRMKeyVault_requiresImport(rInt int, location string) string { + template := testAccAzureRMKeyVault_basic(rInt, location) return fmt.Sprintf(` %s -resource "azurerm_key_vault_key" "import" { - name = "${azurerm_key_vault_key.test.name}" - key_vault_id = "${azurerm_key_vault.test.id}" - key_type = "EC" - key_size = 2048 - key_opts = [ - "sign", - "verify", - ] +resource "azurerm_key_vault" "import" { + name = "${azurerm_key_vault.test.name}" + location = "${azurerm_key_vault.test.location}" + resource_group_name = "${azurerm_key_vault.test.resource_group_name}" + tenant_id = "${azurerm_key_vault.test.tenant_id}" + + sku { + name = "premium" + } + + access_policy { + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + object_id = "${data.azurerm_client_config.current.client_id}" + + key_permissions = [ + "create", + ] + + secret_permissions = [ + "set", + ] + } } `, template) } -func testAccAzureRMKeyVaultKey_basicRSA(rString string, location string) string { +func testAccAzureRMKeyVault_networkAclsTemplate(rInt int, location string) string { return fmt.Sprintf(` data "azurerm_client_config" "current" {} resource "azurerm_resource_group" "test" { - name = "acctestRG-%s" + name = "acctestRG-%d" location = "%s" } +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test_a" { + name = "acctestsubneta%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" + service_endpoints = ["Microsoft.KeyVault"] +} + +resource "azurerm_subnet" "test_b" { + name = "acctestsubnetb%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.4.0/24" + service_endpoints = ["Microsoft.KeyVault"] +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMKeyVault_networkAcls(rInt int, location string) string { + template := testAccAzureRMKeyVault_networkAclsTemplate(rInt, location) + return fmt.Sprintf(` +%s + resource "azurerm_key_vault" "test" { - name = "acctestkv-%s" + name = "vault%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -427,56 +557,33 @@ resource "azurerm_key_vault" "test" { access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" - object_id = "${data.azurerm_client_config.current.service_principal_object_id}" + object_id = "${data.azurerm_client_config.current.client_id}" key_permissions = [ "create", - "delete", - "get", - "update", ] secret_permissions = [ - "get", - "delete", "set", ] } - tags { - environment = "Production" + network_acls { + default_action = "Deny" + bypass = "None" + virtual_network_subnet_ids = ["${azurerm_subnet.test_a.id}", "${azurerm_subnet.test_b.id}"] } } - -resource "azurerm_key_vault_key" "test" { - name = "key-%s" - key_vault_id = "${azurerm_key_vault.test.id}" - key_type = "RSA" - key_size = 2048 - - key_opts = [ - "decrypt", - "encrypt", - "sign", - "unwrapKey", - "verify", - "wrapKey", - ] -} -`, rString, location, rString, rString) +`, template, rInt) } -func testAccAzureRMKeyVaultKey_basicRSAHSM(rString string, location string) string { +func testAccAzureRMKeyVault_networkAclsUpdated(rInt int, location string) string { + template := testAccAzureRMKeyVault_networkAclsTemplate(rInt, location) return fmt.Sprintf(` -data "azurerm_client_config" "current" {} - -resource "azurerm_resource_group" "test" { - name = "acctestRG-%s" - location = "%s" -} +%s resource "azurerm_key_vault" "test" { - name = "acctestkv-%s" + name = "vault%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -487,55 +594,38 @@ resource "azurerm_key_vault" "test" { access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" - object_id = "${data.azurerm_client_config.current.service_principal_object_id}" + object_id = "${data.azurerm_client_config.current.client_id}" key_permissions = [ "create", - "delete", - "get", ] secret_permissions = [ - "get", - "delete", "set", ] } - tags { - environment = "Production" + network_acls { + default_action = "Allow" + bypass = "AzureServices" + ip_rules = ["10.0.0.102/32"] + virtual_network_subnet_ids = ["${azurerm_subnet.test_a.id}"] } } - -resource "azurerm_key_vault_key" "test" { - name = "key-%s" - key_vault_id = "${azurerm_key_vault.test.id}" - key_type = "RSA-HSM" - key_size = 2048 - - key_opts = [ - "decrypt", - "encrypt", - "sign", - "unwrapKey", - "verify", - "wrapKey", - ] -} -`, rString, location, rString, rString) +`, template, rInt) } -func testAccAzureRMKeyVaultKey_complete(rString string, location string) string { +func testAccAzureRMKeyVault_update(rInt int, location string) string { return fmt.Sprintf(` data "azurerm_client_config" "current" {} resource "azurerm_resource_group" "test" { - name = "acctestRG-%s" + name = "acctestRG-%d" location = "%s" } resource "azurerm_key_vault" "test" { - name = "acctestkv-%s" + name = "vault%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -546,59 +636,39 @@ resource "azurerm_key_vault" "test" { access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" - object_id = "${data.azurerm_client_config.current.service_principal_object_id}" + object_id = "${data.azurerm_client_config.current.client_id}" key_permissions = [ - "create", - "delete", "get", ] secret_permissions = [ "get", - "delete", - "set", ] } - tags { - environment = "Production" - } -} - -resource "azurerm_key_vault_key" "test" { - name = "key-%s" - key_vault_id = "${azurerm_key_vault.test.id}" - key_type = "RSA" - key_size = 2048 - - key_opts = [ - "decrypt", - "encrypt", - "sign", - "unwrapKey", - "verify", - "wrapKey", - ] + enabled_for_deployment = true + enabled_for_disk_encryption = true + enabled_for_template_deployment = true - tags { - "hello" = "world" + tags = { + environment = "Staging" } } -`, rString, location, rString, rString) +`, rInt, location, rInt) } -func testAccAzureRMKeyVaultKey_basicUpdated(rString string, location string) string { +func testAccAzureRMKeyVault_complete(rInt int, location string) string { return fmt.Sprintf(` data "azurerm_client_config" "current" {} resource "azurerm_resource_group" "test" { - name = "acctestRG-%s" + name = "acctestRG-%d" location = "%s" } resource "azurerm_key_vault" "test" { - name = "acctestkv-%s" + name = "vault%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -608,41 +678,57 @@ resource "azurerm_key_vault" "test" { } access_policy { - tenant_id = "${data.azurerm_client_config.current.tenant_id}" - object_id = "${data.azurerm_client_config.current.service_principal_object_id}" + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + object_id = "${data.azurerm_client_config.current.client_id}" + application_id = "${data.azurerm_client_config.current.service_principal_application_id}" + + certificate_permissions = [ + "get", + ] key_permissions = [ - "create", - "delete", "get", - "update", ] secret_permissions = [ "get", - "delete", - "set", ] } - tags { + tags = { environment = "Production" } } +`, rInt, location, rInt) +} + +func testAccAzureRMKeyVault_justCert(rInt int, location string) string { + return fmt.Sprintf(` +data "azurerm_client_config" "current" {} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_key_vault" "test" { + name = "vault%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + tenant_id = "${data.azurerm_client_config.current.tenant_id}" -resource "azurerm_key_vault_key" "test" { - name = "key-%s" - vault_uri = "${azurerm_key_vault.test.vault_uri}" - key_type = "RSA" - key_size = 2048 + sku { + name = "premium" + } - key_opts = [ - "encrypt", - "sign", - "unwrapKey", - "verify", - "wrapKey", - ] + access_policy { + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + object_id = "${data.azurerm_client_config.current.client_id}" + + certificate_permissions = [ + "get", + ] + } } -`, rString, location, rString, rString) +`, rInt, location, rInt) } From 72f7d05643481673608798b24d3a69b35a3c69c6 Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Thu, 28 Feb 2019 16:45:36 -0800 Subject: [PATCH 04/13] Re-added the access policy test --- azurerm/resource_arm_key_vault_key_test.go | 134 ++++----------------- 1 file changed, 22 insertions(+), 112 deletions(-) diff --git a/azurerm/resource_arm_key_vault_key_test.go b/azurerm/resource_arm_key_vault_key_test.go index c58c27198b63..36ccff5793b9 100644 --- a/azurerm/resource_arm_key_vault_key_test.go +++ b/azurerm/resource_arm_key_vault_key_test.go @@ -95,33 +95,7 @@ func TestAccAzureRMKeyVault_basic(t *testing.T) { }) } -func TestAccAzureRMKeyVaultKey_basicECClassic(t *testing.T) { - resourceName := "azurerm_key_vault_key.test" - rs := acctest.RandString(6) - config := testAccAzureRMKeyVaultKey_basicECClassic(rs, testLocation()) - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMKeyVaultKeyDestroy, - Steps: []resource.TestStep{ - { - Config: config, - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMKeyVaultKeyExists(resourceName), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"key_size"}, - }, - }, - }) -} - -func TestAccAzureRMKeyVaultKey_requiresImport(t *testing.T) { +func TestAccAzureRMKeyVault_requiresImport(t *testing.T) { if !requireResourcesToBeImported { t.Skip("Skipping since resources aren't required to be imported") return @@ -482,71 +456,18 @@ resource "azurerm_storage_account" "testsa%d" { type = "SystemAssigned" } - tags = { - environment = "Production" + tags { + environment = "testing" } } -resource "azurerm_key_vault_key" "test" { - name = "key-%s" - key_vault_id = "${azurerm_key_vault.test.id}" - key_type = "EC" - key_size = 2048 - - key_opts = [ - "sign", - "verify", - ] -} -`, rString, location, rString, rString) -} - -func testAccAzureRMKeyVaultKey_basicECClassic(rString string, location string) string { - return fmt.Sprintf(` -data "azurerm_client_config" "current" {} - -resource "azurerm_resource_group" "test" { - name = "acctestRG-%s" - location = "%s" -} - -resource "azurerm_key_vault" "test" { - name = "acctestkv-%s" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - tenant_id = "${data.azurerm_client_config.current.tenant_id}" - - sku { - name = "premium" - } +resource "azurerm_key_vault_access_policy" "policy%d" { + key_vault_id = "${azurerm_key_vault.test.id}" + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + object_id = "${azurerm_storage_account.testsa%d.identity.0.principal_id}" - access_policy { - tenant_id = "${data.azurerm_client_config.current.tenant_id}" - object_id = "${data.azurerm_client_config.current.service_principal_object_id}" - - key_permissions = [ - "create", - "delete", - "get", - ] - - secret_permissions = [ - "get", - "delete", - "set", - ] - } - - tags = { - environment = "Production" - } -} - -resource "azurerm_key_vault_key" "test" { - name = "key-%s" - vault_uri = "${azurerm_key_vault.test.vault_uri}" - key_type = "EC" - key_size = 2048 + key_permissions = ["get","create","delete","list","restore","recover","unwrapkey","wrapkey","purge","encrypt","decrypt","sign","verify"] + secret_permissions = ["get"] depends_on = ["azurerm_storage_account.testsa%d"] } @@ -647,8 +568,10 @@ resource "azurerm_key_vault" "test" { ] } - tags = { - environment = "Production" + network_acls { + default_action = "Deny" + bypass = "None" + virtual_network_subnet_ids = ["${azurerm_subnet.test_a.id}", "${azurerm_subnet.test_b.id}"] } } `, template, rInt) @@ -682,8 +605,11 @@ resource "azurerm_key_vault" "test" { ] } - tags = { - environment = "Production" + network_acls { + default_action = "Allow" + bypass = "AzureServices" + ip_rules = ["10.0.0.102/32"] + virtual_network_subnet_ids = ["${azurerm_subnet.test_a.id}"] } } `, template, rInt) @@ -721,28 +647,12 @@ resource "azurerm_key_vault" "test" { ] } - tags = { - environment = "Production" - } -} - -resource "azurerm_key_vault_key" "test" { - name = "key-%s" - key_vault_id = "${azurerm_key_vault.test.id}" - key_type = "RSA" - key_size = 2048 - - key_opts = [ - "decrypt", - "encrypt", - "sign", - "unwrapKey", - "verify", - "wrapKey", - ] + enabled_for_deployment = true + enabled_for_disk_encryption = true + enabled_for_template_deployment = true tags = { - "hello" = "world" + environment = "Staging" } } `, rInt, location, rInt) From 3bfa6a33979bb6d50d66098e7613521658fe5690 Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Thu, 28 Feb 2019 16:52:46 -0800 Subject: [PATCH 05/13] Re-basic test cases from Master From a2eaa6e7eb0784aa046f82aa64e851d2c3a0991c Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Thu, 28 Feb 2019 17:00:45 -0800 Subject: [PATCH 06/13] Reset to master updated wrong file --- azurerm/resource_arm_key_vault_key_test.go | 689 ++++++++++----------- 1 file changed, 342 insertions(+), 347 deletions(-) diff --git a/azurerm/resource_arm_key_vault_key_test.go b/azurerm/resource_arm_key_vault_key_test.go index 36ccff5793b9..b9c37fd56431 100644 --- a/azurerm/resource_arm_key_vault_key_test.go +++ b/azurerm/resource_arm_key_vault_key_test.go @@ -2,308 +2,276 @@ package azurerm import ( "fmt" + "log" "testing" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + + "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/response" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) -func TestAccAzureRMKeyVault_name(t *testing.T) { - cases := []struct { - Input string - ExpectError bool - }{ - { - Input: "", - ExpectError: true, - }, - { - Input: "hi", - ExpectError: true, - }, - { - Input: "hello", - ExpectError: false, - }, - { - Input: "hello-world", - ExpectError: false, - }, - { - Input: "hello-world-21", - ExpectError: false, - }, - { - Input: "hello_world_21", - ExpectError: true, - }, - { - Input: "Hello-World", - ExpectError: false, - }, - { - Input: "20202020", - ExpectError: false, - }, - { - Input: "ABC123!@£", - ExpectError: true, - }, - { - Input: "abcdefghijklmnopqrstuvwxyz", - ExpectError: true, - }, - } - - for _, tc := range cases { - _, errors := validateKeyVaultName(tc.Input, "") - - hasError := len(errors) > 0 +func TestAccAzureRMKeyVaultKey_basicEC(t *testing.T) { + resourceName := "azurerm_key_vault_key.test" + rs := acctest.RandString(6) + config := testAccAzureRMKeyVaultKey_basicEC(rs, testLocation()) - if tc.ExpectError && !hasError { - t.Fatalf("Expected the Key Vault Name to trigger a validation error for '%s'", tc.Input) - } - } + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKeyVaultKeyDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKeyVaultKeyExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"key_size"}, + }, + }, + }) } -func TestAccAzureRMKeyVault_basic(t *testing.T) { - resourceName := "azurerm_key_vault.test" - ri := tf.AccRandTimeInt() - config := testAccAzureRMKeyVault_basic(ri, testLocation()) +func TestAccAzureRMKeyVaultKey_basicECClassic(t *testing.T) { + resourceName := "azurerm_key_vault_key.test" + rs := acctest.RandString(6) + config := testAccAzureRMKeyVaultKey_basicECClassic(rs, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testCheckAzureRMKeyVaultDestroy, + CheckDestroy: testCheckAzureRMKeyVaultKeyDestroy, Steps: []resource.TestStep{ { Config: config, Check: resource.ComposeTestCheckFunc( - testCheckAzureRMKeyVaultExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "network_acls.#", "0"), + testCheckAzureRMKeyVaultKeyExists(resourceName), ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"key_size"}, }, }, }) } -func TestAccAzureRMKeyVault_requiresImport(t *testing.T) { +func TestAccAzureRMKeyVaultKey_requiresImport(t *testing.T) { if !requireResourcesToBeImported { t.Skip("Skipping since resources aren't required to be imported") return } - resourceName := "azurerm_key_vault.test" - ri := tf.AccRandTimeInt() + resourceName := "azurerm_key_vault_key.test" + rs := acctest.RandString(6) location := testLocation() resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testCheckAzureRMKeyVaultDestroy, + CheckDestroy: testCheckAzureRMKeyVaultKeyDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMKeyVault_basic(ri, location), + Config: testAccAzureRMKeyVaultKey_basicEC(rs, location), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMKeyVaultExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "network_acls.#", "0"), + testCheckAzureRMKeyVaultKeyExists(resourceName), ), }, { - Config: testAccAzureRMKeyVault_requiresImport(ri, location), - ExpectError: testRequiresImportError("azurerm_key_vault"), + Config: testAccAzureRMKeyVaultKey_requiresImport(rs, location), + ExpectError: testRequiresImportError("azurerm_key_vault_key"), }, }, }) } -func TestAccAzureRMKeyVault_networkAcls(t *testing.T) { - resourceName := "azurerm_key_vault.test" - ri := tf.AccRandTimeInt() - location := testLocation() +func TestAccAzureRMKeyVaultKey_basicRSA(t *testing.T) { + resourceName := "azurerm_key_vault_key.test" + rs := acctest.RandString(6) + config := testAccAzureRMKeyVaultKey_basicRSA(rs, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testCheckAzureRMKeyVaultDestroy, + CheckDestroy: testCheckAzureRMKeyVaultKeyDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMKeyVault_networkAcls(ri, location), + Config: config, Check: resource.ComposeTestCheckFunc( - testCheckAzureRMKeyVaultExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "network_acls.#", "1"), - resource.TestCheckResourceAttr(resourceName, "network_acls.0.bypass", "None"), - resource.TestCheckResourceAttr(resourceName, "network_acls.0.default_action", "Deny"), - resource.TestCheckResourceAttr(resourceName, "network_acls.0.ip_rules.#", "0"), - resource.TestCheckResourceAttr(resourceName, "network_acls.0.virtual_network_subnet_ids.#", "2"), + testCheckAzureRMKeyVaultKeyExists(resourceName), ), }, { - Config: testAccAzureRMKeyVault_networkAclsUpdated(ri, location), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMKeyVaultExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "network_acls.#", "1"), - resource.TestCheckResourceAttr(resourceName, "network_acls.0.bypass", "AzureServices"), - resource.TestCheckResourceAttr(resourceName, "network_acls.0.default_action", "Allow"), - resource.TestCheckResourceAttr(resourceName, "network_acls.0.ip_rules.#", "1"), - resource.TestCheckResourceAttr(resourceName, "network_acls.0.virtual_network_subnet_ids.#", "1"), - ), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"key_size"}, }, }, }) } -func TestAccAzureRMKeyVault_accessPolicyUpperLimit(t *testing.T) { - resourceName := "azurerm_key_vault.test" - ri := tf.AccRandTimeInt() - config := testAccAzureRMKeyVault_accessPolicyUpperLimit(ri, testLocation()) +func TestAccAzureRMKeyVaultKey_basicRSAHSM(t *testing.T) { + resourceName := "azurerm_key_vault_key.test" + rs := acctest.RandString(6) + config := testAccAzureRMKeyVaultKey_basicRSAHSM(rs, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testCheckAzureRMKeyVaultDestroy, + CheckDestroy: testCheckAzureRMKeyVaultKeyDestroy, Steps: []resource.TestStep{ { Config: config, Check: resource.ComposeTestCheckFunc( - testCheckAzureRMKeyVaultExists(resourceName), - testCheckAzureRMKeyVaultDisappears(resourceName), + testCheckAzureRMKeyVaultKeyExists(resourceName), ), - ExpectNonEmptyPlan: true, + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"key_size"}, }, }, }) } -func TestAccAzureRMKeyVault_disappears(t *testing.T) { - resourceName := "azurerm_key_vault.test" - ri := tf.AccRandTimeInt() - config := testAccAzureRMKeyVault_basic(ri, testLocation()) +func TestAccAzureRMKeyVaultKey_complete(t *testing.T) { + resourceName := "azurerm_key_vault_key.test" + rs := acctest.RandString(6) + config := testAccAzureRMKeyVaultKey_complete(rs, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testCheckAzureRMKeyVaultDestroy, + CheckDestroy: testCheckAzureRMKeyVaultKeyDestroy, Steps: []resource.TestStep{ { Config: config, Check: resource.ComposeTestCheckFunc( - testCheckAzureRMKeyVaultExists(resourceName), - testCheckAzureRMKeyVaultDisappears(resourceName), + testCheckAzureRMKeyVaultKeyExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.hello", "world"), ), - ExpectNonEmptyPlan: true, + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"key_size"}, }, }, }) } -func TestAccAzureRMKeyVault_complete(t *testing.T) { - resourceName := "azurerm_key_vault.test" - ri := tf.AccRandTimeInt() - config := testAccAzureRMKeyVault_complete(ri, testLocation()) +func TestAccAzureRMKeyVaultKey_update(t *testing.T) { + resourceName := "azurerm_key_vault_key.test" + rs := acctest.RandString(6) + config := testAccAzureRMKeyVaultKey_basicRSA(rs, testLocation()) + updatedConfig := testAccAzureRMKeyVaultKey_basicUpdated(rs, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testCheckAzureRMKeyVaultDestroy, + CheckDestroy: testCheckAzureRMKeyVaultKeyDestroy, Steps: []resource.TestStep{ { Config: config, Check: resource.ComposeTestCheckFunc( - testCheckAzureRMKeyVaultExists(resourceName), - resource.TestCheckResourceAttrSet(resourceName, "access_policy.0.application_id"), + testCheckAzureRMKeyVaultKeyExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "key_opts.#", "6"), + resource.TestCheckResourceAttr(resourceName, "key_opts.0", "decrypt"), ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + Config: updatedConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKeyVaultKeyExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "key_opts.#", "5"), + resource.TestCheckResourceAttr(resourceName, "key_opts.0", "encrypt"), + ), }, }, }) } -func TestAccAzureRMKeyVault_update(t *testing.T) { - ri := tf.AccRandTimeInt() - resourceName := "azurerm_key_vault.test" - preConfig := testAccAzureRMKeyVault_basic(ri, testLocation()) - postConfig := testAccAzureRMKeyVault_update(ri, testLocation()) +func TestAccAzureRMKeyVaultKey_disappears(t *testing.T) { + resourceName := "azurerm_key_vault_key.test" + rs := acctest.RandString(6) + config := testAccAzureRMKeyVaultKey_basicEC(rs, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testCheckAzureRMKeyVaultDestroy, + CheckDestroy: testCheckAzureRMKeyVaultKeyDestroy, Steps: []resource.TestStep{ { - Config: preConfig, - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMKeyVaultExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "access_policy.0.key_permissions.0", "create"), - resource.TestCheckResourceAttr(resourceName, "access_policy.0.secret_permissions.0", "set"), - resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), - ), - }, - { - Config: postConfig, + Config: config, Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "access_policy.0.key_permissions.0", "get"), - resource.TestCheckResourceAttr(resourceName, "access_policy.0.secret_permissions.0", "get"), - resource.TestCheckResourceAttr(resourceName, "enabled_for_deployment", "true"), - resource.TestCheckResourceAttr(resourceName, "enabled_for_disk_encryption", "true"), - resource.TestCheckResourceAttr(resourceName, "enabled_for_template_deployment", "true"), - resource.TestCheckResourceAttr(resourceName, "tags.environment", "Staging"), + testCheckAzureRMKeyVaultKeyExists(resourceName), + testCheckAzureRMKeyVaultKeyDisappears(resourceName), ), + ExpectNonEmptyPlan: true, }, }, }) } -func TestAccAzureRMKeyVault_justCert(t *testing.T) { - resourceName := "azurerm_key_vault.test" - ri := tf.AccRandTimeInt() +func TestAccAzureRMKeyVaultKey_disappearsWhenParentKeyVaultDeleted(t *testing.T) { + rs := acctest.RandString(6) + config := testAccAzureRMKeyVaultKey_basicEC(rs, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testCheckAzureRMKeyVaultDestroy, + CheckDestroy: testCheckAzureRMKeyVaultKeyDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMKeyVault_justCert(ri, testLocation()), + Config: config, Check: resource.ComposeTestCheckFunc( - testCheckAzureRMKeyVaultExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "access_policy.0.certificate_permissions.0", "get"), + testCheckAzureRMKeyVaultKeyExists("azurerm_key_vault_key.test"), + testCheckAzureRMKeyVaultDisappears("azurerm_key_vault.test"), ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ExpectNonEmptyPlan: true, }, }, }) } -func testCheckAzureRMKeyVaultDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).keyVaultClient +func testCheckAzureRMKeyVaultKeyDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).keyVaultManagementClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { - if rs.Type != "azurerm_key_vault" { + if rs.Type != "azurerm_key_vault_key" { continue } name := rs.Primary.Attributes["name"] - resourceGroup := rs.Primary.Attributes["resource_group_name"] + vaultBaseUrl := rs.Primary.Attributes["vault_uri"] + keyVaultId := rs.Primary.Attributes["key_vault_id"] + + ok, err := azure.KeyVaultExists(ctx, testAccProvider.Meta().(*ArmClient).keyVaultClient, keyVaultId) + if err != nil { + return fmt.Errorf("Error checking if key vault %q for Secret %q in Vault at url %q exists: %v", keyVaultId, name, vaultBaseUrl, err) + } + if !ok { + log.Printf("[DEBUG] Secret %q Key Vault %q was not found in Key Vault at URI %q ", name, keyVaultId, vaultBaseUrl) + return nil + } - resp, err := client.Get(ctx, resourceGroup, name) + // get the latest version + resp, err := client.GetKey(ctx, vaultBaseUrl, name, "") if err != nil { if utils.ResponseWasNotFound(resp.Response) { return nil @@ -311,83 +279,96 @@ func testCheckAzureRMKeyVaultDestroy(s *terraform.State) error { return err } - return fmt.Errorf("Key Vault still exists:\n%#v", resp.Properties) + return fmt.Errorf("Key Vault Key still exists:\n%#v", resp) } return nil } -func testCheckAzureRMKeyVaultExists(resourceName string) resource.TestCheckFunc { +func testCheckAzureRMKeyVaultKeyExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).keyVaultManagementClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + // 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) } + name := rs.Primary.Attributes["name"] + vaultBaseUrl := rs.Primary.Attributes["vault_uri"] + keyVaultId := rs.Primary.Attributes["key_vault_id"] - vaultName := rs.Primary.Attributes["name"] - resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] - if !hasResourceGroup { - return fmt.Errorf("Bad: no resource group found in state for vault: %s", vaultName) + ok, err := azure.KeyVaultExists(ctx, testAccProvider.Meta().(*ArmClient).keyVaultClient, keyVaultId) + if err != nil { + return fmt.Errorf("Error checking if key vault %q for Key %q in Vault at url %q exists: %v", keyVaultId, name, vaultBaseUrl, err) + } + if !ok { + log.Printf("[DEBUG] Key %q Key Vault %q was not found in Key Vault at URI %q ", name, keyVaultId, vaultBaseUrl) + return nil } - client := testAccProvider.Meta().(*ArmClient).keyVaultClient - ctx := testAccProvider.Meta().(*ArmClient).StopContext - - resp, err := client.Get(ctx, resourceGroup, vaultName) + resp, err := client.GetKey(ctx, vaultBaseUrl, name, "") if err != nil { if utils.ResponseWasNotFound(resp.Response) { - return fmt.Errorf("Bad: Vault %q (resource group: %q) does not exist", vaultName, resourceGroup) + return fmt.Errorf("Bad: Key Vault Key %q (resource group: %q) does not exist", name, vaultBaseUrl) } - return fmt.Errorf("Bad: Get on keyVaultClient: %+v", err) + return fmt.Errorf("Bad: Get on keyVaultManagementClient: %+v", err) } return nil } } -func testCheckAzureRMKeyVaultDisappears(resourceName string) resource.TestCheckFunc { +func testCheckAzureRMKeyVaultKeyDisappears(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).keyVaultManagementClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + // 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) } - vaultName := rs.Primary.Attributes["name"] - resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] - if !hasResourceGroup { - return fmt.Errorf("Bad: no resource group found in state for vault: %s", vaultName) - } + name := rs.Primary.Attributes["name"] + vaultBaseUrl := rs.Primary.Attributes["vault_uri"] + keyVaultId := rs.Primary.Attributes["key_vault_id"] - client := testAccProvider.Meta().(*ArmClient).keyVaultClient - ctx := testAccProvider.Meta().(*ArmClient).StopContext + ok, err := azure.KeyVaultExists(ctx, testAccProvider.Meta().(*ArmClient).keyVaultClient, keyVaultId) + if err != nil { + return fmt.Errorf("Error checking if key vault %q for Key %q in Vault at url %q exists: %v", keyVaultId, name, vaultBaseUrl, err) + } + if !ok { + log.Printf("[DEBUG] Key %q Key Vault %q was not found in Key Vault at URI %q ", name, keyVaultId, vaultBaseUrl) + return nil + } - resp, err := client.Delete(ctx, resourceGroup, vaultName) + resp, err := client.DeleteKey(ctx, vaultBaseUrl, name) if err != nil { - if response.WasNotFound(resp.Response) { + if utils.ResponseWasNotFound(resp.Response) { return nil } - return fmt.Errorf("Bad: Delete on keyVaultClient: %+v", err) + return fmt.Errorf("Bad: Delete on keyVaultManagementClient: %+v", err) } return nil } } -func testAccAzureRMKeyVault_basic(rInt int, location string) string { +func testAccAzureRMKeyVaultKey_basicEC(rString string, location string) string { return fmt.Sprintf(` data "azurerm_client_config" "current" {} resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" + name = "acctestRG-%s" location = "%s" } resource "azurerm_key_vault" "test" { - name = "vault%d" + name = "acctestkv-%s" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -398,38 +379,51 @@ resource "azurerm_key_vault" "test" { access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" - object_id = "${data.azurerm_client_config.current.client_id}" + object_id = "${data.azurerm_client_config.current.service_principal_object_id}" key_permissions = [ "create", + "delete", + "get", ] secret_permissions = [ + "get", + "delete", "set", ] } -} -`, rInt, location, rInt) -} -func testAccAzureRMKeyVault_accessPolicyUpperLimit(rInt int, location string) string { + tags = { + environment = "Production" + } +} - var storageAccountConfig string +resource "azurerm_key_vault_key" "test" { + name = "key-%s" + key_vault_id = "${azurerm_key_vault.test.id}" + key_type = "EC" + key_size = 2048 - for i := 50; i < 68; i++ { - storageAccountConfig += testAccAzureRMKeyVault_generateConfig(i) - } + key_opts = [ + "sign", + "verify", + ] +} +`, rString, location, rString, rString) +} +func testAccAzureRMKeyVaultKey_basicECClassic(rString string, location string) string { return fmt.Sprintf(` data "azurerm_client_config" "current" {} resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" + name = "acctestRG-%s" location = "%s" } resource "azurerm_key_vault" "test" { - name = "vault%d" + name = "acctestkv-%s" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -437,116 +431,73 @@ resource "azurerm_key_vault" "test" { sku { name = "premium" } -} -%s -`, rInt, location, rInt, storageAccountConfig) -} + access_policy { + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + object_id = "${data.azurerm_client_config.current.service_principal_object_id}" -func testAccAzureRMKeyVault_generateConfig(accountNum int) string { - return fmt.Sprintf(` -resource "azurerm_storage_account" "testsa%d" { - name = "testsa%d" - resource_group_name = "${azurerm_resource_group.test.name}" - location = "${azurerm_resource_group.test.location}" - account_tier = "Standard" - account_replication_type = "GRS" - - identity { - type = "SystemAssigned" + key_permissions = [ + "create", + "delete", + "get", + ] + + secret_permissions = [ + "get", + "delete", + "set", + ] } - tags { - environment = "testing" + tags = { + environment = "Production" } } -resource "azurerm_key_vault_access_policy" "policy%d" { - key_vault_id = "${azurerm_key_vault.test.id}" - tenant_id = "${data.azurerm_client_config.current.tenant_id}" - object_id = "${azurerm_storage_account.testsa%d.identity.0.principal_id}" - - key_permissions = ["get","create","delete","list","restore","recover","unwrapkey","wrapkey","purge","encrypt","decrypt","sign","verify"] - secret_permissions = ["get"] +resource "azurerm_key_vault_key" "test" { + name = "key-%s" + vault_uri = "${azurerm_key_vault.test.vault_uri}" + key_type = "EC" + key_size = 2048 - depends_on = ["azurerm_storage_account.testsa%d"] + key_opts = [ + "sign", + "verify", + ] } -`, accountNum, accountNum, accountNum, accountNum, accountNum) +`, rString, location, rString, rString) } -func testAccAzureRMKeyVault_requiresImport(rInt int, location string) string { - template := testAccAzureRMKeyVault_basic(rInt, location) +func testAccAzureRMKeyVaultKey_requiresImport(rString string, location string) string { + template := testAccAzureRMKeyVaultKey_basicEC(rString, location) return fmt.Sprintf(` %s +resource "azurerm_key_vault_key" "import" { + name = "${azurerm_key_vault_key.test.name}" + key_vault_id = "${azurerm_key_vault.test.id}" + key_type = "EC" + key_size = 2048 -resource "azurerm_key_vault" "import" { - name = "${azurerm_key_vault.test.name}" - location = "${azurerm_key_vault.test.location}" - resource_group_name = "${azurerm_key_vault.test.resource_group_name}" - tenant_id = "${azurerm_key_vault.test.tenant_id}" - - sku { - name = "premium" - } - - access_policy { - tenant_id = "${data.azurerm_client_config.current.tenant_id}" - object_id = "${data.azurerm_client_config.current.client_id}" - - key_permissions = [ - "create", - ] - - secret_permissions = [ - "set", - ] - } + key_opts = [ + "sign", + "verify", + ] } `, template) } -func testAccAzureRMKeyVault_networkAclsTemplate(rInt int, location string) string { +func testAccAzureRMKeyVaultKey_basicRSA(rString string, location string) string { return fmt.Sprintf(` data "azurerm_client_config" "current" {} resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" + name = "acctestRG-%s" location = "%s" } -resource "azurerm_virtual_network" "test" { - name = "acctestvirtnet%d" - address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" -} - -resource "azurerm_subnet" "test_a" { - name = "acctestsubneta%d" - resource_group_name = "${azurerm_resource_group.test.name}" - virtual_network_name = "${azurerm_virtual_network.test.name}" - address_prefix = "10.0.2.0/24" - service_endpoints = ["Microsoft.KeyVault"] -} - -resource "azurerm_subnet" "test_b" { - name = "acctestsubnetb%d" - resource_group_name = "${azurerm_resource_group.test.name}" - virtual_network_name = "${azurerm_virtual_network.test.name}" - address_prefix = "10.0.4.0/24" - service_endpoints = ["Microsoft.KeyVault"] -} -`, rInt, location, rInt, rInt, rInt) -} - -func testAccAzureRMKeyVault_networkAcls(rInt int, location string) string { - template := testAccAzureRMKeyVault_networkAclsTemplate(rInt, location) - return fmt.Sprintf(` -%s - resource "azurerm_key_vault" "test" { - name = "vault%d" + name = "acctestkv-%s" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -557,33 +508,56 @@ resource "azurerm_key_vault" "test" { access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" - object_id = "${data.azurerm_client_config.current.client_id}" + object_id = "${data.azurerm_client_config.current.service_principal_object_id}" key_permissions = [ "create", + "delete", + "get", + "update", ] secret_permissions = [ + "get", + "delete", "set", ] } - network_acls { - default_action = "Deny" - bypass = "None" - virtual_network_subnet_ids = ["${azurerm_subnet.test_a.id}", "${azurerm_subnet.test_b.id}"] + tags = { + environment = "Production" } } -`, template, rInt) + +resource "azurerm_key_vault_key" "test" { + name = "key-%s" + key_vault_id = "${azurerm_key_vault.test.id}" + key_type = "RSA" + key_size = 2048 + + key_opts = [ + "decrypt", + "encrypt", + "sign", + "unwrapKey", + "verify", + "wrapKey", + ] +} +`, rString, location, rString, rString) } -func testAccAzureRMKeyVault_networkAclsUpdated(rInt int, location string) string { - template := testAccAzureRMKeyVault_networkAclsTemplate(rInt, location) +func testAccAzureRMKeyVaultKey_basicRSAHSM(rString string, location string) string { return fmt.Sprintf(` -%s +data "azurerm_client_config" "current" {} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%s" + location = "%s" +} resource "azurerm_key_vault" "test" { - name = "vault%d" + name = "acctestkv-%s" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -594,38 +568,55 @@ resource "azurerm_key_vault" "test" { access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" - object_id = "${data.azurerm_client_config.current.client_id}" + object_id = "${data.azurerm_client_config.current.service_principal_object_id}" key_permissions = [ "create", + "delete", + "get", ] secret_permissions = [ + "get", + "delete", "set", ] } - network_acls { - default_action = "Allow" - bypass = "AzureServices" - ip_rules = ["10.0.0.102/32"] - virtual_network_subnet_ids = ["${azurerm_subnet.test_a.id}"] + tags = { + environment = "Production" } } -`, template, rInt) + +resource "azurerm_key_vault_key" "test" { + name = "key-%s" + key_vault_id = "${azurerm_key_vault.test.id}" + key_type = "RSA-HSM" + key_size = 2048 + + key_opts = [ + "decrypt", + "encrypt", + "sign", + "unwrapKey", + "verify", + "wrapKey", + ] +} +`, rString, location, rString, rString) } -func testAccAzureRMKeyVault_update(rInt int, location string) string { +func testAccAzureRMKeyVaultKey_complete(rString string, location string) string { return fmt.Sprintf(` data "azurerm_client_config" "current" {} resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" + name = "acctestRG-%s" location = "%s" } resource "azurerm_key_vault" "test" { - name = "vault%d" + name = "acctestkv-%s" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -636,39 +627,59 @@ resource "azurerm_key_vault" "test" { access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" - object_id = "${data.azurerm_client_config.current.client_id}" + object_id = "${data.azurerm_client_config.current.service_principal_object_id}" key_permissions = [ + "create", + "delete", "get", ] secret_permissions = [ "get", + "delete", + "set", ] } - enabled_for_deployment = true - enabled_for_disk_encryption = true - enabled_for_template_deployment = true + tags = { + environment = "Production" + } +} + +resource "azurerm_key_vault_key" "test" { + name = "key-%s" + key_vault_id = "${azurerm_key_vault.test.id}" + key_type = "RSA" + key_size = 2048 + + key_opts = [ + "decrypt", + "encrypt", + "sign", + "unwrapKey", + "verify", + "wrapKey", + ] tags = { - environment = "Staging" + "hello" = "world" } } -`, rInt, location, rInt) +`, rString, location, rString, rString) } -func testAccAzureRMKeyVault_complete(rInt int, location string) string { +func testAccAzureRMKeyVaultKey_basicUpdated(rString string, location string) string { return fmt.Sprintf(` data "azurerm_client_config" "current" {} resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" + name = "acctestRG-%s" location = "%s" } resource "azurerm_key_vault" "test" { - name = "vault%d" + name = "acctestkv-%s" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -678,20 +689,20 @@ resource "azurerm_key_vault" "test" { } access_policy { - tenant_id = "${data.azurerm_client_config.current.tenant_id}" - object_id = "${data.azurerm_client_config.current.client_id}" - application_id = "${data.azurerm_client_config.current.service_principal_application_id}" - - certificate_permissions = [ - "get", - ] + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + object_id = "${data.azurerm_client_config.current.service_principal_object_id}" key_permissions = [ + "create", + "delete", "get", + "update", ] secret_permissions = [ "get", + "delete", + "set", ] } @@ -699,36 +710,20 @@ resource "azurerm_key_vault" "test" { environment = "Production" } } -`, rInt, location, rInt) -} - -func testAccAzureRMKeyVault_justCert(rInt int, location string) string { - return fmt.Sprintf(` -data "azurerm_client_config" "current" {} -resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" - location = "%s" -} +resource "azurerm_key_vault_key" "test" { + name = "key-%s" + vault_uri = "${azurerm_key_vault.test.vault_uri}" + key_type = "RSA" + key_size = 2048 -resource "azurerm_key_vault" "test" { - name = "vault%d" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - tenant_id = "${data.azurerm_client_config.current.tenant_id}" - - sku { - name = "premium" - } - - access_policy { - tenant_id = "${data.azurerm_client_config.current.tenant_id}" - object_id = "${data.azurerm_client_config.current.client_id}" - - certificate_permissions = [ - "get", - ] - } + key_opts = [ + "encrypt", + "sign", + "unwrapKey", + "verify", + "wrapKey", + ] } -`, rInt, location, rInt) +`, rString, location, rString, rString) } From fa97f580d9419808ff158cd29c82bd3194b5161c Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Thu, 28 Feb 2019 17:08:23 -0800 Subject: [PATCH 07/13] Updating the correct key vault test file --- azurerm/resource_arm_key_vault_test.go | 84 ++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/azurerm/resource_arm_key_vault_test.go b/azurerm/resource_arm_key_vault_test.go index b711d458aff7..6ebe2319f887 100644 --- a/azurerm/resource_arm_key_vault_test.go +++ b/azurerm/resource_arm_key_vault_test.go @@ -161,6 +161,28 @@ func TestAccAzureRMKeyVault_networkAcls(t *testing.T) { }) } +func TestAccAzureRMKeyVault_accessPolicyUpperLimit(t *testing.T) { + resourceName := "azurerm_key_vault.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMKeyVault_accessPolicyUpperLimit(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKeyVaultDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKeyVaultExists(resourceName), + testCheckAzureRMKeyVaultDisappears(resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + func TestAccAzureRMKeyVault_disappears(t *testing.T) { resourceName := "azurerm_key_vault.test" ri := tf.AccRandTimeInt() @@ -648,3 +670,65 @@ resource "azurerm_key_vault" "test" { } `, rInt, location, rInt) } + +func testAccAzureRMKeyVault_accessPolicyUpperLimit(rInt int, location string) string { + + var storageAccountConfig string + + for i := 50; i < 68; i++ { + storageAccountConfig += testAccAzureRMKeyVault_generateConfig(i) + } + + return fmt.Sprintf(` +data "azurerm_client_config" "current" {} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_key_vault" "test" { + name = "vault%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + + sku { + name = "premium" + } +} + +%s +`, rInt, location, rInt, storageAccountConfig) +} + +func testAccAzureRMKeyVault_generateConfig(accountNum int) string { + return fmt.Sprintf(` +resource "azurerm_storage_account" "testsa%d" { + name = "testsa%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "GRS" + + identity { + type = "SystemAssigned" + } + + tags { + environment = "testing" + } +} + +resource "azurerm_key_vault_access_policy" "policy%d" { + key_vault_id = "${azurerm_key_vault.test.id}" + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + object_id = "${azurerm_storage_account.testsa%d.identity.0.principal_id}" + + key_permissions = ["get","create","delete","list","restore","recover","unwrapkey","wrapkey","purge","encrypt","decrypt","sign","verify"] + secret_permissions = ["get"] + + depends_on = ["azurerm_storage_account.testsa%d"] +} +`, accountNum, accountNum, accountNum, accountNum, accountNum) +} From 3dd3f518b3adbd77ec1891ebfddae8bc16a59778 Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Thu, 28 Feb 2019 18:56:03 -0800 Subject: [PATCH 08/13] Updated test to add access policies directly to the key vault --- azurerm/resource_arm_key_vault_test.go | 73 +++++++++++++++----------- 1 file changed, 43 insertions(+), 30 deletions(-) diff --git a/azurerm/resource_arm_key_vault_test.go b/azurerm/resource_arm_key_vault_test.go index 6ebe2319f887..7bac804ed888 100644 --- a/azurerm/resource_arm_key_vault_test.go +++ b/azurerm/resource_arm_key_vault_test.go @@ -672,11 +672,20 @@ resource "azurerm_key_vault" "test" { } func testAccAzureRMKeyVault_accessPolicyUpperLimit(rInt int, location string) string { - - var storageAccountConfig string - - for i := 50; i < 68; i++ { - storageAccountConfig += testAccAzureRMKeyVault_generateConfig(i) + + var storageAccountConfigs string + var accessPoliciesConfigs string + var dependsString string + var maxPolicies = 68 + + for i := 50; i <= maxPolicies; i++ { + storageAccountConfigs += testAccAzureRMKeyVault_generateStorageAccountConfigs(i) + accessPoliciesConfigs += testAccAzureRMKeyVault_generateAccessPolicyConfigs(i) + dependsString += fmt.Sprintf(`"azurerm_storage_account.testsa%d"`, i) + if i < maxPolicies { + dependsString += ", " + } + } return fmt.Sprintf(` @@ -696,39 +705,43 @@ resource "azurerm_key_vault" "test" { sku { name = "premium" } +%s + depends_on = [%s] } %s -`, rInt, location, rInt, storageAccountConfig) +`, rInt, location, rInt, accessPoliciesConfigs, dependsString, storageAccountConfigs) } -func testAccAzureRMKeyVault_generateConfig(accountNum int) string { +func testAccAzureRMKeyVault_generateStorageAccountConfigs(accountNum int) string { return fmt.Sprintf(` resource "azurerm_storage_account" "testsa%d" { - name = "testsa%d" - resource_group_name = "${azurerm_resource_group.test.name}" - location = "${azurerm_resource_group.test.location}" - account_tier = "Standard" - account_replication_type = "GRS" - - identity { - type = "SystemAssigned" - } + name = "testsa%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "GRS" - tags { - environment = "testing" - } + identity { + type = "SystemAssigned" + } + + tags { + environment = "testing" + } } - -resource "azurerm_key_vault_access_policy" "policy%d" { - key_vault_id = "${azurerm_key_vault.test.id}" - tenant_id = "${data.azurerm_client_config.current.tenant_id}" - object_id = "${azurerm_storage_account.testsa%d.identity.0.principal_id}" - - key_permissions = ["get","create","delete","list","restore","recover","unwrapkey","wrapkey","purge","encrypt","decrypt","sign","verify"] - secret_permissions = ["get"] - - depends_on = ["azurerm_storage_account.testsa%d"] +`, accountNum, accountNum) } -`, accountNum, accountNum, accountNum, accountNum, accountNum) + +func testAccAzureRMKeyVault_generateAccessPolicyConfigs(accountNum int) string { + return fmt.Sprintf(` + access_policy { + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + object_id = "${azurerm_storage_account.testsa%d.identity.0.principal_id}" + + key_permissions = ["get","create","delete","list","restore","recover","unwrapkey","wrapkey","purge","encrypt","decrypt","sign","verify"] + secret_permissions = ["get"] + } +`, accountNum) } + From df90afdf6458a0970efb14080c86bf776a68fc73 Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Fri, 1 Mar 2019 12:35:22 -0800 Subject: [PATCH 09/13] Added random string to reduce risk of name collision --- azurerm/resource_arm_key_vault_test.go | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/azurerm/resource_arm_key_vault_test.go b/azurerm/resource_arm_key_vault_test.go index 7bac804ed888..42569c4743c3 100644 --- a/azurerm/resource_arm_key_vault_test.go +++ b/azurerm/resource_arm_key_vault_test.go @@ -671,21 +671,21 @@ resource "azurerm_key_vault" "test" { `, rInt, location, rInt) } -func testAccAzureRMKeyVault_accessPolicyUpperLimit(rInt int, location string) string { - +func testAccAzureRMKeyVault_accessPolicyUpperLimit(rInt int, location string, rs string) string { + var storageAccountConfigs string var accessPoliciesConfigs string var dependsString string - var maxPolicies = 68 + rs := acctest.RandString(10) - for i := 50; i <= maxPolicies; i++ { - storageAccountConfigs += testAccAzureRMKeyVault_generateStorageAccountConfigs(i) + for i := 1; i <= 20; i++ { + storageAccountConfigs += testAccAzureRMKeyVault_generateStorageAccountConfigs(i, rs) accessPoliciesConfigs += testAccAzureRMKeyVault_generateAccessPolicyConfigs(i) dependsString += fmt.Sprintf(`"azurerm_storage_account.testsa%d"`, i) - if i < maxPolicies { - dependsString += ", " + if i < 20 { + dependsString += ", " } - + } return fmt.Sprintf(` @@ -713,10 +713,10 @@ resource "azurerm_key_vault" "test" { `, rInt, location, rInt, accessPoliciesConfigs, dependsString, storageAccountConfigs) } -func testAccAzureRMKeyVault_generateStorageAccountConfigs(accountNum int) string { +func testAccAzureRMKeyVault_generateStorageAccountConfigs(accountNum int, rs string) string { return fmt.Sprintf(` resource "azurerm_storage_account" "testsa%d" { - name = "testsa%d" + name = "testsa%d%s" resource_group_name = "${azurerm_resource_group.test.name}" location = "${azurerm_resource_group.test.location}" account_tier = "Standard" @@ -730,7 +730,7 @@ resource "azurerm_storage_account" "testsa%d" { environment = "testing" } } -`, accountNum, accountNum) +`, accountNum, accountNum, rs) } func testAccAzureRMKeyVault_generateAccessPolicyConfigs(accountNum int) string { @@ -744,4 +744,3 @@ func testAccAzureRMKeyVault_generateAccessPolicyConfigs(accountNum int) string { } `, accountNum) } - From 628b4da540e9df603b5052eb70c3446d7b70f721 Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Fri, 1 Mar 2019 12:47:19 -0800 Subject: [PATCH 10/13] Removed depends on string from test --- azurerm/resource_arm_key_vault_test.go | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/azurerm/resource_arm_key_vault_test.go b/azurerm/resource_arm_key_vault_test.go index 42569c4743c3..a69f6b720e0f 100644 --- a/azurerm/resource_arm_key_vault_test.go +++ b/azurerm/resource_arm_key_vault_test.go @@ -4,6 +4,7 @@ import ( "fmt" "testing" + "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/response" @@ -675,17 +676,11 @@ func testAccAzureRMKeyVault_accessPolicyUpperLimit(rInt int, location string, rs var storageAccountConfigs string var accessPoliciesConfigs string - var dependsString string rs := acctest.RandString(10) for i := 1; i <= 20; i++ { storageAccountConfigs += testAccAzureRMKeyVault_generateStorageAccountConfigs(i, rs) accessPoliciesConfigs += testAccAzureRMKeyVault_generateAccessPolicyConfigs(i) - dependsString += fmt.Sprintf(`"azurerm_storage_account.testsa%d"`, i) - if i < 20 { - dependsString += ", " - } - } return fmt.Sprintf(` @@ -706,11 +701,10 @@ resource "azurerm_key_vault" "test" { name = "premium" } %s - depends_on = [%s] } %s -`, rInt, location, rInt, accessPoliciesConfigs, dependsString, storageAccountConfigs) +`, rInt, location, rInt, accessPoliciesConfigs, storageAccountConfigs) } func testAccAzureRMKeyVault_generateStorageAccountConfigs(accountNum int, rs string) string { @@ -724,7 +718,7 @@ resource "azurerm_storage_account" "testsa%d" { identity { type = "SystemAssigned" - } + } tags { environment = "testing" From 8bf75e5a446df57ff07178ca5e5299bbcd4fc633 Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Fri, 1 Mar 2019 13:32:19 -0800 Subject: [PATCH 11/13] Fixed function to call test --- azurerm/resource_arm_key_vault_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azurerm/resource_arm_key_vault_test.go b/azurerm/resource_arm_key_vault_test.go index a69f6b720e0f..18ed3cc8a332 100644 --- a/azurerm/resource_arm_key_vault_test.go +++ b/azurerm/resource_arm_key_vault_test.go @@ -165,7 +165,8 @@ func TestAccAzureRMKeyVault_networkAcls(t *testing.T) { func TestAccAzureRMKeyVault_accessPolicyUpperLimit(t *testing.T) { resourceName := "azurerm_key_vault.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMKeyVault_accessPolicyUpperLimit(ri, testLocation()) + rs := acctest.RandString(10) + config := testAccAzureRMKeyVault_accessPolicyUpperLimit(ri, testLocation(), rs) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -676,7 +677,6 @@ func testAccAzureRMKeyVault_accessPolicyUpperLimit(rInt int, location string, rs var storageAccountConfigs string var accessPoliciesConfigs string - rs := acctest.RandString(10) for i := 1; i <= 20; i++ { storageAccountConfigs += testAccAzureRMKeyVault_generateStorageAccountConfigs(i, rs) From e53a7c50621f4db2fc67c22a74fd8482a5cd96b6 Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Fri, 1 Mar 2019 14:08:27 -0800 Subject: [PATCH 12/13] Changed format of storage account name --- azurerm/resource_arm_key_vault_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azurerm/resource_arm_key_vault_test.go b/azurerm/resource_arm_key_vault_test.go index 18ed3cc8a332..3b2e49ed98d3 100644 --- a/azurerm/resource_arm_key_vault_test.go +++ b/azurerm/resource_arm_key_vault_test.go @@ -710,7 +710,7 @@ resource "azurerm_key_vault" "test" { func testAccAzureRMKeyVault_generateStorageAccountConfigs(accountNum int, rs string) string { return fmt.Sprintf(` resource "azurerm_storage_account" "testsa%d" { - name = "testsa%d%s" + name = "testsa%s%d" resource_group_name = "${azurerm_resource_group.test.name}" location = "${azurerm_resource_group.test.location}" account_tier = "Standard" @@ -724,7 +724,7 @@ resource "azurerm_storage_account" "testsa%d" { environment = "testing" } } -`, accountNum, accountNum, rs) +`, accountNum, rs, accountNum) } func testAccAzureRMKeyVault_generateAccessPolicyConfigs(accountNum int) string { From e406ea551012e2e980a1e42f7ab8b60f10e5fdfe Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Fri, 1 Mar 2019 15:05:26 -0800 Subject: [PATCH 13/13] Update CHANGELOG.md to include #2866 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec750ad5c013..11183f957054 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ IMPROVEMENTS: * `azurerm_application_gateway` - support for setting `path` within the `backend_http_settings` block [GH-2879] * `azurerm_application_gateway` - support for setting `connection_draining` to the `backend_http_settings` [GH-2778] * `azurerm_iothub` - support for the `fallback_route` property [GH-2764] +* `azurerm_key_vault` - support for 1024 `access policies` [GH-2866] * `azurerm_redis_cache` - support for configuring the `maxfragmentationmemory_reserved` in the `redis_configuration` block [GH-2887] * `azurerm_service_fabric_cluster` - support for setting `capacities` and `placement_properties` [GH-2936] * `azurerm_storage_account` - exposing primary/secondary `_host` attributes [GH-2792]