From 2b0fc5e2fc1408988bef1e0bbb3cf752481d3fd0 Mon Sep 17 00:00:00 2001 From: kt Date: Thu, 7 Feb 2019 12:37:41 -0800 Subject: [PATCH] Switch Key Vault sub resources to use Key Vault ID instead of URL (#2820) This will allow us to easily check if the key vault exists before doing a update/read/delete on it causing a NXDOMAIN error (as the domain used for the API call vanishes when the key vault is deleted) fixes #2396 --- azurerm/data_source_key_vault_key.go | 48 ++++++- azurerm/data_source_key_vault_key_test.go | 7 +- azurerm/data_source_key_vault_secret.go | 49 ++++++- azurerm/data_source_key_vault_secret_test.go | 8 +- azurerm/helpers/azure/key_vault.go | 121 +++++++++++++++++ .../helpers/azure/key_vault_access_policy.go | 2 +- azurerm/resource_arm_key_vault.go | 2 +- .../resource_arm_key_vault_access_policy.go | 94 ++++++++++--- ...source_arm_key_vault_access_policy_test.go | 32 ++--- azurerm/resource_arm_key_vault_certificate.go | 126 +++++++++++++++++- ...resource_arm_key_vault_certificate_test.go | 64 ++++++--- azurerm/resource_arm_key_vault_key.go | 91 +++++++++++-- azurerm/resource_arm_key_vault_key_test.go | 57 ++++++-- azurerm/resource_arm_key_vault_secret.go | 77 ++++++++++- azurerm/resource_arm_key_vault_secret_test.go | 47 ++++++- azurerm/resource_arm_sql_administrator.go | 2 +- azurerm/resource_arm_sql_database.go | 2 +- website/docs/d/key_vault_key.html.markdown | 2 +- website/docs/d/key_vault_secret.html.markdown | 2 +- .../r/key_vault_certificate.html.markdown | 10 +- website/docs/r/key_vault_key.html.markdown | 6 +- website/docs/r/key_vault_secret.html.markdown | 8 +- 22 files changed, 730 insertions(+), 127 deletions(-) create mode 100644 azurerm/helpers/azure/key_vault.go diff --git a/azurerm/data_source_key_vault_key.go b/azurerm/data_source_key_vault_key.go index a834102b6813..9aba04b6661c 100644 --- a/azurerm/data_source_key_vault_key.go +++ b/azurerm/data_source_key_vault_key.go @@ -20,10 +20,24 @@ func dataSourceArmKeyVaultKey() *schema.Resource { ValidateFunc: azure.ValidateKeyVaultChildName, }, + "key_vault_id": { + Type: schema.TypeString, + Optional: true, //todo required in 2.0 + Computed: true, //todo removed in 2.0 + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + ConflictsWith: []string{"vault_uri"}, + }, + + //todo remove in 2.0 "vault_uri": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validate.URLIsHTTPS, + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + Deprecated: "This property has been deprecated in favour of the key_vault_id property. This will prevent a class of bugs as described in https://github.com/terraform-providers/terraform-provider-azurerm/issues/2396 and will be removed in version 2.0 of the provider", + ValidateFunc: validate.URLIsHTTPS, + ConflictsWith: []string{"key_vault_id"}, }, "key_type": { @@ -65,16 +79,38 @@ func dataSourceArmKeyVaultKey() *schema.Resource { } func dataSourceArmKeyVaultKeyRead(d *schema.ResourceData, meta interface{}) error { + vaultClient := meta.(*ArmClient).keyVaultClient client := meta.(*ArmClient).keyVaultManagementClient ctx := meta.(*ArmClient).StopContext - vaultUri := d.Get("vault_uri").(string) + keyVaultBaseUri := d.Get("vault_uri").(string) name := d.Get("name").(string) + keyVaultId := d.Get("key_vault_id").(string) + + if keyVaultBaseUri == "" { + if keyVaultId == "" { + return fmt.Errorf("one of `key_vault_id` or `vault_uri` must be set") + } + + pKeyVaultBaseUrl, err := azure.GetKeyVaultBaseUrlFromID(ctx, vaultClient, keyVaultId) + if err != nil { + return fmt.Errorf("Error looking up Key %q vault url from id %q: %+v", name, keyVaultId, err) + } + + keyVaultBaseUri = pKeyVaultBaseUrl + d.Set("vault_uri", keyVaultBaseUri) + } else { + id, err := azure.GetKeyVaultIDFromBaseUrl(ctx, vaultClient, keyVaultBaseUri) + if err != nil { + return fmt.Errorf("Error unable to find key vault ID from URL %q for certificate %q: %+v", keyVaultBaseUri, name, err) + } + d.Set("key_vault_id", id) + } - resp, err := client.GetKey(ctx, vaultUri, name, "") + resp, err := client.GetKey(ctx, keyVaultBaseUri, name, "") if err != nil { if utils.ResponseWasNotFound(resp.Response) { - return fmt.Errorf("Key %q was not found in Key Vault at URI %q", name, vaultUri) + return fmt.Errorf("Key %q was not found in Key Vault at URI %q", name, keyVaultBaseUri) } return err diff --git a/azurerm/data_source_key_vault_key_test.go b/azurerm/data_source_key_vault_key_test.go index 9208b711e164..4bd658a55c94 100644 --- a/azurerm/data_source_key_vault_key_test.go +++ b/azurerm/data_source_key_vault_key_test.go @@ -31,12 +31,13 @@ func TestAccDataSourceAzureRMKeyVaultKey_complete(t *testing.T) { } func testAccDataSourceKeyVaultKey_complete(rString string, location string) string { + t := testAccAzureRMKeyVaultKey_complete(rString, location) return fmt.Sprintf(` %s data "azurerm_key_vault_key" "test" { - name = "${azurerm_key_vault_key.test.name}" - vault_uri = "${azurerm_key_vault_key.test.vault_uri}" + name = "${azurerm_key_vault_key.test.name}" + key_vault_id = "${azurerm_key_vault.test.id}" } -`, testAccAzureRMKeyVaultKey_complete(rString, location)) +`, t) } diff --git a/azurerm/data_source_key_vault_secret.go b/azurerm/data_source_key_vault_secret.go index 3d5bc9ec8c11..02cf3a2f63cd 100644 --- a/azurerm/data_source_key_vault_secret.go +++ b/azurerm/data_source_key_vault_secret.go @@ -21,11 +21,24 @@ func dataSourceArmKeyVaultSecret() *schema.Resource { ValidateFunc: azure.ValidateKeyVaultChildName, }, + "key_vault_id": { + Type: schema.TypeString, + Optional: true, //todo required in 2.0 + Computed: true, //todo removed in 2.0 + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + ConflictsWith: []string{"vault_uri"}, + }, + + //todo remove in 2.0 "vault_uri": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validate.URLIsHTTPS, + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + Deprecated: "This property has been deprecated in favour of the key_vault_id property. This will prevent a class of bugs as described in https://github.com/terraform-providers/terraform-provider-azurerm/issues/2396 and will be removed in version 2.0 of the provider", + ValidateFunc: validate.URLIsHTTPS, + ConflictsWith: []string{"key_vault_id"}, }, "value": { @@ -50,17 +63,39 @@ func dataSourceArmKeyVaultSecret() *schema.Resource { } func dataSourceArmKeyVaultSecretRead(d *schema.ResourceData, meta interface{}) error { + vaultClient := meta.(*ArmClient).keyVaultClient client := meta.(*ArmClient).keyVaultManagementClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) - vaultUri := d.Get("vault_uri").(string) + keyVaultBaseUri := d.Get("vault_uri").(string) + keyVaultId := d.Get("key_vault_id").(string) + + if keyVaultBaseUri == "" { + if keyVaultId == "" { + return fmt.Errorf("one of `key_vault_id` or `vault_uri` must be set") + } + + pKeyVaultBaseUrl, err := azure.GetKeyVaultBaseUrlFromID(ctx, vaultClient, keyVaultId) + if err != nil { + return fmt.Errorf("Error looking up Secret %q vault url form id %q: %+v", name, keyVaultId, err) + } + + keyVaultBaseUri = pKeyVaultBaseUrl + d.Set("vault_uri", keyVaultBaseUri) + } else { + id, err := azure.GetKeyVaultIDFromBaseUrl(ctx, vaultClient, keyVaultBaseUri) + if err != nil { + return fmt.Errorf("Error unable to find key vault ID from URL %q for certificate %q: %+v", keyVaultBaseUri, name, err) + } + d.Set("key_vault_id", id) + } // we always want to get the latest version - resp, err := client.GetSecret(ctx, vaultUri, name, "") + resp, err := client.GetSecret(ctx, keyVaultBaseUri, name, "") if err != nil { if utils.ResponseWasNotFound(resp.Response) { - return fmt.Errorf("KeyVault Secret %q (KeyVault URI %q) does not exist", name, vaultUri) + return fmt.Errorf("KeyVault Secret %q (KeyVault URI %q) does not exist", name, keyVaultBaseUri) } return fmt.Errorf("Error making Read request on Azure KeyVault Secret %s: %+v", name, err) } diff --git a/azurerm/data_source_key_vault_secret_test.go b/azurerm/data_source_key_vault_secret_test.go index fda4d5b58896..58f1e77305ff 100644 --- a/azurerm/data_source_key_vault_secret_test.go +++ b/azurerm/data_source_key_vault_secret_test.go @@ -59,8 +59,8 @@ func testAccDataSourceKeyVaultSecret_basic(rString string, location string) stri %s data "azurerm_key_vault_secret" "test" { - name = "${azurerm_key_vault_secret.test.name}" - vault_uri = "${azurerm_key_vault_secret.test.vault_uri}" + name = "${azurerm_key_vault_secret.test.name}" + key_vault_id = "${azurerm_key_vault.test.id}" } `, r) } @@ -71,8 +71,8 @@ func testAccDataSourceKeyVaultSecret_complete(rString string, location string) s %s data "azurerm_key_vault_secret" "test" { - name = "${azurerm_key_vault_secret.test.name}" - vault_uri = "${azurerm_key_vault_secret.test.vault_uri}" + name = "${azurerm_key_vault_secret.test.name}" + key_vault_id = "${azurerm_key_vault.test.id}" } `, r) } diff --git a/azurerm/helpers/azure/key_vault.go b/azurerm/helpers/azure/key_vault.go new file mode 100644 index 000000000000..a054b1c1ed9d --- /dev/null +++ b/azurerm/helpers/azure/key_vault.go @@ -0,0 +1,121 @@ +package azure + +import ( + "context" + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/keyvault/mgmt/2018-02-14/keyvault" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func GetKeyVaultBaseUrlFromID(ctx context.Context, client keyvault.VaultsClient, keyVaultId string) (string, error) { + + if keyVaultId == "" { + return "", fmt.Errorf("keyVaultId is empty") + } + + id, err := ParseAzureResourceID(keyVaultId) + if err != nil { + return "", err + } + resourceGroup := id.ResourceGroup + + vaultName, ok := id.Path["vaults"] + if !ok { + return "", fmt.Errorf("resource id does not contain `vaults`: %q", keyVaultId) + } + + resp, err := client.Get(ctx, resourceGroup, vaultName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return "", fmt.Errorf("Error unable to find KeyVault %q (Resource Group %q): %+v", vaultName, resourceGroup, err) + } + return "", fmt.Errorf("Error making Read request on KeyVault %q (Resource Group %q): %+v", vaultName, resourceGroup, err) + } + + if resp.Properties == nil || resp.Properties.VaultURI == nil { + return "", fmt.Errorf("vault (%s) response properties or VaultURI is nil", keyVaultId) + } + + return *resp.Properties.VaultURI, nil +} + +func GetKeyVaultIDFromBaseUrl(ctx context.Context, client keyvault.VaultsClient, keyVaultUrl string) (string, error) { + + list, err := client.ListComplete(ctx, utils.Int32(1000)) + if err != nil { + return "", fmt.Errorf("Error GetKeyVaultId unable to list Key Vaults %v", err) + } + + for list.NotDone() { + v := list.Value() + if v.ID == nil { + log.Printf("[DEBUG]GetKeyVaultId: v.ID was nil, continuing") + continue + } + + vid, err := ParseAzureResourceID(*v.ID) + if err != nil { + log.Printf("[DEBUG] GetKeyVaultId: unable to parse v.ID (%s): %v", *v.ID, err) + continue + } + resourceGroup := vid.ResourceGroup + name := vid.Path["vaults"] + + //resp does not appear to contain the vault properties, so lets fech them + get, err := client.Get(ctx, resourceGroup, name) + if err != nil { + log.Printf("[DEBUG] GetKeyVaultId: Error making Read request on KeyVault %q (Resource Group %q): %+v", name, resourceGroup, err) + continue + } + + if get.ID == nil || get.Properties == nil || get.Properties.VaultURI == nil { + log.Printf("[DEBUG] GetKeyVaultId: KeyVault %q (Resource Group %q) has nil ID, properties or vault URI", name, resourceGroup) + continue + } + + if keyVaultUrl == *get.Properties.VaultURI { + return *get.ID, nil + } + + e := list.NextWithContext(ctx) + if e != nil { + return "", fmt.Errorf("Error GetKeyVaultId: Error getting next value on KeyVault %q (Resource Group %q): %+v", name, resourceGroup, err) + } + } + + return "", fmt.Errorf("Error GetKeyVaultId unable to find Key Vault with url %q", keyVaultUrl) +} + +func KeyVaultExists(ctx context.Context, client keyvault.VaultsClient, keyVaultId string) (bool, error) { + + if keyVaultId == "" { + return false, fmt.Errorf("keyVaultId is empty") + } + + id, err := ParseAzureResourceID(keyVaultId) + if err != nil { + return false, err + } + resourceGroup := id.ResourceGroup + + vaultName, ok := id.Path["vaults"] + if !ok { + return false, fmt.Errorf("resource id does not contain `vaults`: %q", keyVaultId) + } + + resp, err := client.Get(ctx, resourceGroup, vaultName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return false, nil + } + return false, fmt.Errorf("Error making Read request on KeyVault %q (Resource Group %q): %+v", vaultName, resourceGroup, err) + } + + if resp.Properties == nil || resp.Properties.VaultURI == nil { + return false, fmt.Errorf("vault (%s) response properties or VaultURI is nil", keyVaultId) + } + + return true, nil +} diff --git a/azurerm/helpers/azure/key_vault_access_policy.go b/azurerm/helpers/azure/key_vault_access_policy.go index bb14984191e1..270b72773910 100644 --- a/azurerm/helpers/azure/key_vault_access_policy.go +++ b/azurerm/helpers/azure/key_vault_access_policy.go @@ -4,7 +4,7 @@ import ( "github.com/Azure/azure-sdk-for-go/services/keyvault/mgmt/2018-02-14/keyvault" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" - "github.com/satori/go.uuid" + uuid "github.com/satori/go.uuid" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" ) diff --git a/azurerm/resource_arm_key_vault.go b/azurerm/resource_arm_key_vault.go index 1eafc69a9700..38fbf51a986b 100644 --- a/azurerm/resource_arm_key_vault.go +++ b/azurerm/resource_arm_key_vault.go @@ -11,7 +11,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" - "github.com/satori/go.uuid" + uuid "github.com/satori/go.uuid" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/set" diff --git a/azurerm/resource_arm_key_vault_access_policy.go b/azurerm/resource_arm_key_vault_access_policy.go index 0bc545255ce6..efb03addc385 100644 --- a/azurerm/resource_arm_key_vault_access_policy.go +++ b/azurerm/resource_arm_key_vault_access_policy.go @@ -3,11 +3,14 @@ package azurerm import ( "fmt" "log" + "regexp" "strings" + "github.com/satori/go.uuid" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/Azure/azure-sdk-for-go/services/keyvault/mgmt/2018-02-14/keyvault" "github.com/hashicorp/terraform/helper/schema" - "github.com/satori/go.uuid" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" @@ -24,13 +27,52 @@ func resourceArmKeyVaultAccessPolicy() *schema.Resource { }, Schema: map[string]*schema.Schema{ + "key_vault_id": { + Type: schema.TypeString, + Optional: true, //todo required in 2.0 + Computed: true, //todo removed in 2.0 + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + ConflictsWith: []string{"vault_name"}, + }, + + //todo remove in 2.0 "vault_name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + Deprecated: "This property has been deprecated in favour of the key_vault_id property. This will prevent a class of bugs as described in https://github.com/terraform-providers/terraform-provider-azurerm/issues/2396 and will be removed in version 2.0 of the provider", + ValidateFunc: validate.NoEmptyStrings, + ConflictsWith: []string{"key_vault_id"}, }, - "resource_group_name": resourceGroupNameSchema(), + //todo remove in 2.0 + "resource_group_name": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + Deprecated: "This property has been deprecated as the resource group is now pulled from the vault ID and will be removed in version 2.0 of the provider", + ValidateFunc: func(v interface{}, k string) (warnings []string, errors []error) { + value := v.(string) + + if len(value) > 80 { + errors = append(errors, fmt.Errorf("%q may not exceed 80 characters in length", k)) + } + + if strings.HasSuffix(value, ".") { + errors = append(errors, fmt.Errorf("%q may not end with a period", k)) + } + + // regex pulled from https://docs.microsoft.com/en-us/rest/api/resources/resourcegroups/createorupdate + if matched := regexp.MustCompile(`^[-\w\._\(\)]+$`).Match([]byte(value)); !matched { + errors = append(errors, fmt.Errorf("%q may only contain alphanumeric characters, dash, underscores, parentheses and periods", k)) + } + + return warnings, errors + }, + }, "tenant_id": { Type: schema.TypeString, @@ -67,8 +109,9 @@ func resourceArmKeyVaultAccessPolicyCreateOrDelete(d *schema.ResourceData, meta ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] Preparing arguments for Key Vault Access Policy: %s.", action) + vaultId := d.Get("key_vault_id").(string) vaultName := d.Get("vault_name").(string) - resGroup := d.Get("resource_group_name").(string) + resourceGroup := d.Get("resource_group_name").(string) tenantIdRaw := d.Get("tenant_id").(string) tenantId, err := uuid.FromString(tenantIdRaw) @@ -79,15 +122,36 @@ func resourceArmKeyVaultAccessPolicyCreateOrDelete(d *schema.ResourceData, meta applicationIdRaw := d.Get("application_id").(string) objectId := d.Get("object_id").(string) - keyVault, err := client.Get(ctx, resGroup, vaultName) + if vaultName == "" { + if vaultId == "" { + return fmt.Errorf("one of `key_vault_id` or `vault_name` must be set") + } + id, err2 := azure.ParseAzureResourceID(vaultId) + if err2 != nil { + return err2 + } + + resourceGroup = id.ResourceGroup + + vaultNameTemp, ok := id.Path["vaults"] + if !ok { + return fmt.Errorf("key_value_id does not contain `vaults`: %q", vaultId) + } + vaultName = vaultNameTemp + + } else if resourceGroup == "" { + return fmt.Errorf("one of `resource_group_name` must be set when `vault_name` is used") + } + + keyVault, err := client.Get(ctx, resourceGroup, vaultName) if err != nil { if utils.ResponseWasNotFound(keyVault.Response) { - log.Printf("[DEBUG] Parent Key Vault %q was not found in Resource Group %q - removing from state!", vaultName, resGroup) + log.Printf("[DEBUG] Parent Key Vault %q was not found in Resource Group %q - removing from state!", vaultName, resourceGroup) d.SetId("") return nil } - return fmt.Errorf("Error retrieving Key Vault %q (Resource Group %q): %+v", vaultName, resGroup, err) + return fmt.Errorf("Error retrieving Key Vault %q (Resource Group %q): %+v", vaultName, resourceGroup, err) } // This is because azure doesn't have an 'id' for a keyvault access policy @@ -168,18 +232,17 @@ func resourceArmKeyVaultAccessPolicyCreateOrDelete(d *schema.ResourceData, meta }, } - _, err = client.UpdateAccessPolicy(ctx, resGroup, vaultName, action, parameters) - if err != nil { - return fmt.Errorf("Error updating Access Policy (Object ID %q / Application ID %q) for Key Vault %q (Resource Group %q): %+v", objectId, applicationIdRaw, vaultName, resGroup, err) + if _, err = client.UpdateAccessPolicy(ctx, resourceGroup, vaultName, action, parameters); err != nil { + return fmt.Errorf("Error updating Access Policy (Object ID %q / Application ID %q) for Key Vault %q (Resource Group %q): %+v", objectId, applicationIdRaw, vaultName, resourceGroup, err) } - read, err := client.Get(ctx, resGroup, vaultName) + read, err := client.Get(ctx, resourceGroup, vaultName) if err != nil { - return fmt.Errorf("Error retrieving Key Vault %q (Resource Group %q): %+v", vaultName, resGroup, err) + return fmt.Errorf("Error retrieving Key Vault %q (Resource Group %q): %+v", vaultName, resourceGroup, err) } if read.ID == nil { - return fmt.Errorf("Cannot read KeyVault %q (Resource Group %q) ID", vaultName, resGroup) + return fmt.Errorf("Cannot read KeyVault %q (Resource Group %q) ID", vaultName, resourceGroup) } if d.IsNewResource() { @@ -237,6 +300,7 @@ func resourceArmKeyVaultAccessPolicyRead(d *schema.ResourceData, meta interface{ return nil } + d.Set("key_vault_id", resp.ID) d.Set("vault_name", resp.Name) d.Set("resource_group_name", resGroup) d.Set("object_id", objectId) diff --git a/azurerm/resource_arm_key_vault_access_policy_test.go b/azurerm/resource_arm_key_vault_access_policy_test.go index e3e7b5e40886..56f27b177249 100644 --- a/azurerm/resource_arm_key_vault_access_policy_test.go +++ b/azurerm/resource_arm_key_vault_access_policy_test.go @@ -149,20 +149,26 @@ func TestAccAzureRMKeyVaultAccessPolicy_update(t *testing.T) { func testCheckAzureRMKeyVaultAccessPolicyExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).keyVaultClient + 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["vault_name"] - resGroup := rs.Primary.Attributes["resource_group_name"] + id, err := parseAzureResourceID(rs.Primary.ID) + + if err != nil { + return err + } + resGroup := id.ResourceGroup + vaultName := id.Path["vaults"] + objectId := rs.Primary.Attributes["object_id"] applicationId := rs.Primary.Attributes["application_id"] - client := testAccProvider.Meta().(*ArmClient).keyVaultClient - ctx := testAccProvider.Meta().(*ArmClient).StopContext - resp, err := client.Get(ctx, resGroup, vaultName) if err != nil { if utils.ResponseWasNotFound(resp.Response) { @@ -190,8 +196,7 @@ func testAccAzureRMKeyVaultAccessPolicy_basic(rString string, location string) s %s resource "azurerm_key_vault_access_policy" "test" { - vault_name = "${azurerm_key_vault.test.name}" - resource_group_name = "${azurerm_resource_group.test.name}" + key_vault_id = "${azurerm_key_vault.test.id}" key_permissions = [ "get", @@ -214,10 +219,9 @@ func testAccAzureRMKeyVaultAccessPolicy_requiresImport(rString string, location %s resource "azurerm_key_vault_access_policy" "import" { - vault_name = "${azurerm_key_vault_access_policy.test.vault_name}" - resource_group_name = "${azurerm_key_vault_access_policy.test.resource_group_name}" - tenant_id = "${azurerm_key_vault_access_policy.test.tenant_id}" - object_id = "${azurerm_key_vault_access_policy.test.object_id}" + key_vault_id = "${azurerm_key_vault.test.id}" + tenant_id = "${azurerm_key_vault_access_policy.test.tenant_id}" + object_id = "${azurerm_key_vault_access_policy.test.object_id}" key_permissions = [ "get", @@ -237,8 +241,7 @@ func testAccAzureRMKeyVaultAccessPolicy_multiple(rString string, location string %s resource "azurerm_key_vault_access_policy" "test_with_application_id" { - vault_name = "${azurerm_key_vault.test.name}" - resource_group_name = "${azurerm_resource_group.test.name}" + key_vault_id = "${azurerm_key_vault.test.id}" key_permissions = [ "create", @@ -261,8 +264,7 @@ resource "azurerm_key_vault_access_policy" "test_with_application_id" { } resource "azurerm_key_vault_access_policy" "test_no_application_id" { - vault_name = "${azurerm_key_vault.test.name}" - resource_group_name = "${azurerm_resource_group.test.name}" + key_vault_id = "${azurerm_key_vault.test.id}" key_permissions = [ "list", diff --git a/azurerm/resource_arm_key_vault_certificate.go b/azurerm/resource_arm_key_vault_certificate.go index 164e716c7319..abe3f6fdc342 100644 --- a/azurerm/resource_arm_key_vault_certificate.go +++ b/azurerm/resource_arm_key_vault_certificate.go @@ -19,14 +19,71 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) +//todo refactor and find a home for this wayward func +func resourceArmKeyVaultChildResourceImporter(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + client := meta.(*ArmClient).keyVaultClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseKeyVaultChildID(d.Id()) + if err != nil { + return []*schema.ResourceData{d}, fmt.Errorf("Error Unable to parse ID (%s) for Key Vault Child import: %v", d.Id(), err) + } + + list, err := client.ListComplete(ctx, utils.Int32(1000)) + if err != nil { + return []*schema.ResourceData{d}, fmt.Errorf("Error Unable to list Key Vaults for Key Vault Child import: %v", err) + } + + for list.NotDone() { + v := list.Value() + if v.ID == nil { + log.Printf("[DEBUG] Key Vault Child import: v.ID was nil, continuing") + continue + } + + vid, err := parseAzureResourceID(*v.ID) + if err != nil { + log.Printf("[DEBUG] Key Vault Child import: unable to parse v.ID (%s): %v", *v.ID, err) + continue + } + resourceGroup := vid.ResourceGroup + name := vid.Path["vaults"] + + //resp does not appear to contain the vault properties, so lets fech them + get, err := client.Get(ctx, resourceGroup, name) + if err != nil { + log.Printf("[DEBUG] Key Vault Child import: Error making Read request on KeyVault %q (Resource Group %q): %+v", name, resourceGroup, err) + continue + } + + if get.ID == nil || get.Properties == nil || get.Properties.VaultURI == nil { + log.Printf("[DEBUG] Key Vault Child import: KeyVault %q (Resource Group %q) has nil ID, properties or vault URI", name, resourceGroup) + continue + } + + if id.KeyVaultBaseUrl == *get.Properties.VaultURI { + d.Set("key_vault_id", get.ID) + break + } + + e := list.NextWithContext(ctx) + if e != nil { + return []*schema.ResourceData{d}, e + } + } + + return []*schema.ResourceData{d}, nil +} + func resourceArmKeyVaultCertificate() *schema.Resource { return &schema.Resource{ // TODO: support Updating once we have more information about what can be updated Create: resourceArmKeyVaultCertificateCreate, Read: resourceArmKeyVaultCertificateRead, Delete: resourceArmKeyVaultCertificateDelete, + Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + State: resourceArmKeyVaultChildResourceImporter, }, Schema: map[string]*schema.Schema{ @@ -37,11 +94,24 @@ func resourceArmKeyVaultCertificate() *schema.Resource { ValidateFunc: azure.ValidateKeyVaultChildName, }, + "key_vault_id": { + Type: schema.TypeString, + Optional: true, //todo required in 2.0 + Computed: true, //todo removed in 2.0 + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + ConflictsWith: []string{"vault_uri"}, + }, + + //todo remove in 2.0 "vault_uri": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validate.URLIsHTTPS, + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + Deprecated: "This property has been deprecated in favour of the key_vault_id property. This will prevent a class of bugs as described in https://github.com/terraform-providers/terraform-provider-azurerm/issues/2396 and will be removed in version 2.0 of the provider", + ValidateFunc: validate.URLIsHTTPS, + ConflictsWith: []string{"key_vault_id"}, }, "certificate": { @@ -298,12 +368,33 @@ func resourceArmKeyVaultCertificate() *schema.Resource { } func resourceArmKeyVaultCertificateCreate(d *schema.ResourceData, meta interface{}) error { + vaultClient := meta.(*ArmClient).keyVaultClient client := meta.(*ArmClient).keyVaultManagementClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) + keyVaultId := d.Get("key_vault_id").(string) keyVaultBaseUrl := d.Get("vault_uri").(string) + if keyVaultBaseUrl == "" { + if keyVaultId == "" { + return fmt.Errorf("one of `key_vault_id` or `vault_uri` must be set") + } + + pKeyVaultBaseUrl, err := azure.GetKeyVaultBaseUrlFromID(ctx, vaultClient, keyVaultId) + if err != nil { + return fmt.Errorf("Error looking up Certificate %q vault url form id %q: %+v", name, keyVaultId, err) + } + + keyVaultBaseUrl = pKeyVaultBaseUrl + } else { + id, err := azure.GetKeyVaultIDFromBaseUrl(ctx, vaultClient, keyVaultBaseUrl) + if err != nil { + return fmt.Errorf("Error unable to find key vault ID from URL %q for certificate %q: %+v", keyVaultBaseUrl, name, err) + } + d.Set("key_vault_id", id) + } + if requireResourcesToBeImported { existing, err := client.GetCertificate(ctx, keyVaultBaseUrl, name, "") if err != nil { @@ -384,13 +475,23 @@ func resourceArmKeyVaultCertificateRead(d *schema.ResourceData, meta interface{} client := meta.(*ArmClient).keyVaultManagementClient ctx := meta.(*ArmClient).StopContext + keyVaultId := d.Get("key_vault_id").(string) id, err := azure.ParseKeyVaultChildID(d.Id()) if err != nil { return err } - cert, err := client.GetCertificate(ctx, id.KeyVaultBaseUrl, id.Name, "") + ok, err := azure.KeyVaultExists(ctx, meta.(*ArmClient).keyVaultClient, keyVaultId) + if err != nil { + return fmt.Errorf("Error checking if key vault %q for Certificate %q in Vault at url %q exists: %v", keyVaultId, id.Name, id.KeyVaultBaseUrl, err) + } + if !ok { + log.Printf("[DEBUG] Certificate %q Key Vault %q was not found in Key Vault at URI %q - removing from state", id.Name, keyVaultId, id.KeyVaultBaseUrl) + d.SetId("") + return nil + } + cert, err := client.GetCertificate(ctx, id.KeyVaultBaseUrl, id.Name, "") if err != nil { if utils.ResponseWasNotFound(cert.Response) { log.Printf("[DEBUG] Certificate %q was not found in Key Vault at URI %q - removing from state", id.Name, id.KeyVaultBaseUrl) @@ -398,7 +499,7 @@ func resourceArmKeyVaultCertificateRead(d *schema.ResourceData, meta interface{} return nil } - return err + return fmt.Errorf("Error reading Key Vault Certificate: %+v", err) } d.Set("name", id.Name) @@ -434,11 +535,22 @@ func resourceArmKeyVaultCertificateDelete(d *schema.ResourceData, meta interface client := meta.(*ArmClient).keyVaultManagementClient ctx := meta.(*ArmClient).StopContext + keyVaultId := d.Get("key_vault_id").(string) id, err := azure.ParseKeyVaultChildID(d.Id()) if err != nil { return err } + ok, err := azure.KeyVaultExists(ctx, meta.(*ArmClient).keyVaultClient, keyVaultId) + if err != nil { + return fmt.Errorf("Error checking if key vault %q for Certificate %q in Vault at url %q exists: %v", keyVaultId, id.Name, id.KeyVaultBaseUrl, err) + } + if !ok { + log.Printf("[DEBUG] Certificate %q Key Vault %q was not found in Key Vault at URI %q - removing from state", id.Name, keyVaultId, id.KeyVaultBaseUrl) + d.SetId("") + return nil + } + resp, err := client.DeleteCertificate(ctx, id.KeyVaultBaseUrl, id.Name) if err != nil { if utils.ResponseWasNotFound(resp.Response) { diff --git a/azurerm/resource_arm_key_vault_certificate_test.go b/azurerm/resource_arm_key_vault_certificate_test.go index 4b49cde6c00c..f1f64a025163 100644 --- a/azurerm/resource_arm_key_vault_certificate_test.go +++ b/azurerm/resource_arm_key_vault_certificate_test.go @@ -2,8 +2,11 @@ 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" @@ -225,6 +228,16 @@ func testCheckAzureRMKeyVaultCertificateDestroy(s *terraform.State) error { 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 Certificate %q in Vault at url %q exists: %v", keyVaultId, name, vaultBaseUrl, err) + } + if !ok { + log.Printf("[DEBUG] Certificate %q Key Vault %q was not found in Key Vault at URI %q ", name, keyVaultId, vaultBaseUrl) + return nil + } // get the latest version resp, err := client.GetCertificate(ctx, vaultBaseUrl, name, "") @@ -232,7 +245,7 @@ func testCheckAzureRMKeyVaultCertificateDestroy(s *terraform.State) error { if utils.ResponseWasNotFound(resp.Response) { return nil } - return err + return fmt.Errorf("Bad: Get on keyVault certificate: %+v", err) } return fmt.Errorf("Key Vault Certificate still exists:\n%#v", resp) @@ -243,16 +256,27 @@ func testCheckAzureRMKeyVaultCertificateDestroy(s *terraform.State) error { func testCheckAzureRMKeyVaultCertificateExists(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"] - client := testAccProvider.Meta().(*ArmClient).keyVaultManagementClient - 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 Certificate %q in Vault at url %q exists: %v", keyVaultId, name, vaultBaseUrl, err) + } + if !ok { + log.Printf("[DEBUG] Certificate %q Key Vault %q was not found in Key Vault at URI %q ", name, keyVaultId, vaultBaseUrl) + return nil + } resp, err := client.GetCertificate(ctx, vaultBaseUrl, name, "") if err != nil { @@ -260,7 +284,7 @@ func testCheckAzureRMKeyVaultCertificateExists(resourceName string) resource.Tes return fmt.Errorf("Bad: Key Vault Certificate %q (resource group: %q) does not exist", name, vaultBaseUrl) } - return fmt.Errorf("Bad: Get on keyVaultManagementClient: %+v", err) + return fmt.Errorf("Bad: Get on keyVault certificate: %+v", err) } return nil @@ -269,6 +293,9 @@ func testCheckAzureRMKeyVaultCertificateExists(resourceName string) resource.Tes func testCheckAzureRMKeyVaultCertificateDisappears(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 { @@ -276,9 +303,16 @@ func testCheckAzureRMKeyVaultCertificateDisappears(resourceName string) resource } name := rs.Primary.Attributes["name"] vaultBaseUrl := rs.Primary.Attributes["vault_uri"] + keyVaultId := rs.Primary.Attributes["key_vault_id"] - client := testAccProvider.Meta().(*ArmClient).keyVaultManagementClient - 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 Certificate %q in Vault at url %q exists: %v", keyVaultId, name, vaultBaseUrl, err) + } + if !ok { + log.Printf("[DEBUG] Certificate %q Key Vault %q was not found in Key Vault at URI %q ", name, keyVaultId, vaultBaseUrl) + return nil + } resp, err := client.DeleteCertificate(ctx, vaultBaseUrl, name) if err != nil { @@ -333,8 +367,8 @@ resource "azurerm_key_vault" "test" { } resource "azurerm_key_vault_certificate" "test" { - name = "acctestcert%s" - vault_uri = "${azurerm_key_vault.test.vault_uri}" + name = "acctestcert%s" + key_vault_id = "${azurerm_key_vault.test.id}" certificate { contents = "${base64encode(file("testdata/keyvaultcert.pfx"))}" @@ -367,8 +401,8 @@ func testAccAzureRMKeyVaultCertificate_requiresImport(rString string, location s %s resource "azurerm_key_vault_certificate" "import" { - name = "${azurerm_key_vault_certificate.test.name}" - vault_uri = "${azurerm_key_vault_certificate.test.vault_uri}" + name = "${azurerm_key_vault_certificate.test.name}" + key_vault_id = "${azurerm_key_vault.test.id}" certificate { contents = "${base64encode(file("testdata/keyvaultcert.pfx"))}" @@ -436,7 +470,7 @@ resource "azurerm_key_vault" "test" { resource "azurerm_key_vault_certificate" "test" { name = "acctestcert%s" - vault_uri = "${azurerm_key_vault.test.vault_uri}" + key_vault_id = "${azurerm_key_vault.test.id}" certificate_policy { issuer_parameters { @@ -523,8 +557,8 @@ resource "azurerm_key_vault" "test" { } resource "azurerm_key_vault_certificate" "test" { - name = "acctestcert%s" - vault_uri = "${azurerm_key_vault.test.vault_uri}" + name = "acctestcert%s" + key_vault_id = "${azurerm_key_vault.test.id}" certificate_policy { issuer_parameters { @@ -618,8 +652,8 @@ resource "azurerm_key_vault" "test" { } resource "azurerm_key_vault_certificate" "test" { - name = "acctestcert%s" - vault_uri = "${azurerm_key_vault.test.vault_uri}" + name = "acctestcert%s" + key_vault_id = "${azurerm_key_vault.test.id}" certificate_policy { issuer_parameters { diff --git a/azurerm/resource_arm_key_vault_key.go b/azurerm/resource_arm_key_vault_key.go index 9b04ca0d8aae..edadc32064f9 100644 --- a/azurerm/resource_arm_key_vault_key.go +++ b/azurerm/resource_arm_key_vault_key.go @@ -20,7 +20,7 @@ func resourceArmKeyVaultKey() *schema.Resource { Update: resourceArmKeyVaultKeyUpdate, Delete: resourceArmKeyVaultKeyDelete, Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + State: resourceArmKeyVaultChildResourceImporter, }, Schema: map[string]*schema.Schema{ @@ -31,11 +31,24 @@ func resourceArmKeyVaultKey() *schema.Resource { ValidateFunc: azure.ValidateKeyVaultChildName, }, + "key_vault_id": { + Type: schema.TypeString, + Optional: true, //todo required in 2.0 + Computed: true, //todo removed in 2.0 + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + ConflictsWith: []string{"vault_uri"}, + }, + + //todo remove in 2.0 "vault_uri": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validate.URLIsHTTPS, + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + Deprecated: "This property has been deprecated in favour of the key_vault_id property. This will prevent a class of bugs as described in https://github.com/terraform-providers/terraform-provider-azurerm/issues/2396 and will be removed in version 2.0 of the provider", + ValidateFunc: validate.URLIsHTTPS, + ConflictsWith: []string{"key_vault_id"}, }, "key_type": { @@ -99,18 +112,39 @@ func resourceArmKeyVaultKey() *schema.Resource { } func resourceArmKeyVaultKeyCreate(d *schema.ResourceData, meta interface{}) error { + vaultClient := meta.(*ArmClient).keyVaultClient client := meta.(*ArmClient).keyVaultManagementClient ctx := meta.(*ArmClient).StopContext log.Print("[INFO] preparing arguments for AzureRM KeyVault Key creation.") name := d.Get("name").(string) - keyVaultBaseUrl := d.Get("vault_uri").(string) + keyVaultBaseUri := d.Get("vault_uri").(string) + keyVaultId := d.Get("key_vault_id").(string) + + if keyVaultBaseUri == "" { + if keyVaultId == "" { + return fmt.Errorf("one of `key_vault_id` or `vault_uri` must be set") + } + + pKeyVaultBaseUrl, err := azure.GetKeyVaultBaseUrlFromID(ctx, vaultClient, keyVaultId) + if err != nil { + return fmt.Errorf("Error looking up Key %q vault url form id %q: %+v", name, keyVaultId, err) + } + + keyVaultBaseUri = pKeyVaultBaseUrl + } else { + id, err := azure.GetKeyVaultIDFromBaseUrl(ctx, vaultClient, keyVaultBaseUri) + if err != nil { + return fmt.Errorf("Error unable to find key vault ID from URL %q for certificate %q: %+v", keyVaultBaseUri, name, err) + } + d.Set("key_vault_id", id) + } if requireResourcesToBeImported { - existing, err := client.GetKey(ctx, keyVaultBaseUrl, name, "") + existing, err := client.GetKey(ctx, keyVaultBaseUri, name, "") if err != nil { if !utils.ResponseWasNotFound(existing.Response) { - return fmt.Errorf("Error checking for presence of existing Key %q (Key Vault %q): %s", name, keyVaultBaseUrl, err) + return fmt.Errorf("Error checking for presence of existing Key %q (Key Vault %q): %s", name, keyVaultBaseUri, err) } } @@ -135,12 +169,12 @@ func resourceArmKeyVaultKeyCreate(d *schema.ResourceData, meta interface{}) erro Tags: expandTags(tags), } - if _, err := client.CreateKey(ctx, keyVaultBaseUrl, name, parameters); err != nil { + if _, err := client.CreateKey(ctx, keyVaultBaseUri, name, parameters); err != nil { return fmt.Errorf("Error Creating Key: %+v", err) } // "" indicates the latest version - read, err := client.GetKey(ctx, keyVaultBaseUrl, name, "") + read, err := client.GetKey(ctx, keyVaultBaseUri, name, "") if err != nil { return err } @@ -154,12 +188,22 @@ func resourceArmKeyVaultKeyUpdate(d *schema.ResourceData, meta interface{}) erro client := meta.(*ArmClient).keyVaultManagementClient ctx := meta.(*ArmClient).StopContext - log.Print("[INFO] preparing arguments for AzureRM KeyVault Key update.") + keyVaultId := d.Get("key_vault_id").(string) id, err := azure.ParseKeyVaultChildID(d.Id()) if err != nil { return err } + ok, err := azure.KeyVaultExists(ctx, 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, id.Name, id.KeyVaultBaseUrl, err) + } + if !ok { + log.Printf("[DEBUG] Key %q Key Vault %q was not found in Key Vault at URI %q - removing from state", id.Name, keyVaultId, id.KeyVaultBaseUrl) + d.SetId("") + return nil + } + keyOptions := expandKeyVaultKeyOptions(d) tags := d.Get("tags").(map[string]interface{}) @@ -171,8 +215,7 @@ func resourceArmKeyVaultKeyUpdate(d *schema.ResourceData, meta interface{}) erro Tags: expandTags(tags), } - _, err = client.UpdateKey(ctx, id.KeyVaultBaseUrl, id.Name, id.Version, parameters) - if err != nil { + if _, err = client.UpdateKey(ctx, id.KeyVaultBaseUrl, id.Name, id.Version, parameters); err != nil { return err } @@ -183,11 +226,22 @@ func resourceArmKeyVaultKeyRead(d *schema.ResourceData, meta interface{}) error client := meta.(*ArmClient).keyVaultManagementClient ctx := meta.(*ArmClient).StopContext + keyVaultId := d.Get("key_vault_id").(string) id, err := azure.ParseKeyVaultChildID(d.Id()) if err != nil { return err } + ok, err := azure.KeyVaultExists(ctx, 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, id.Name, id.KeyVaultBaseUrl, err) + } + if !ok { + log.Printf("[DEBUG] Key %q Key Vault %q was not found in Key Vault at URI %q - removing from state", id.Name, keyVaultId, id.KeyVaultBaseUrl) + d.SetId("") + return nil + } + resp, err := client.GetKey(ctx, id.KeyVaultBaseUrl, id.Name, "") if err != nil { if utils.ResponseWasNotFound(resp.Response) { @@ -225,11 +279,22 @@ func resourceArmKeyVaultKeyDelete(d *schema.ResourceData, meta interface{}) erro client := meta.(*ArmClient).keyVaultManagementClient ctx := meta.(*ArmClient).StopContext + keyVaultId := d.Get("key_vault_id").(string) id, err := azure.ParseKeyVaultChildID(d.Id()) if err != nil { return err } + ok, err := azure.KeyVaultExists(ctx, 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, id.Name, id.KeyVaultBaseUrl, err) + } + if !ok { + log.Printf("[DEBUG] Key %q Key Vault %q was not found in Key Vault at URI %q - removing from state", id.Name, keyVaultId, id.KeyVaultBaseUrl) + d.SetId("") + return nil + } + _, err = client.DeleteKey(ctx, id.KeyVaultBaseUrl, id.Name) return err } diff --git a/azurerm/resource_arm_key_vault_key_test.go b/azurerm/resource_arm_key_vault_key_test.go index ad09183b6201..daa2579cec70 100644 --- a/azurerm/resource_arm_key_vault_key_test.go +++ b/azurerm/resource_arm_key_vault_key_test.go @@ -2,8 +2,11 @@ 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" @@ -230,6 +233,16 @@ func testCheckAzureRMKeyVaultKeyDestroy(s *terraform.State) error { 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 + } // get the latest version resp, err := client.GetKey(ctx, vaultBaseUrl, name, "") @@ -248,6 +261,9 @@ func testCheckAzureRMKeyVaultKeyDestroy(s *terraform.State) error { 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 { @@ -255,9 +271,16 @@ func testCheckAzureRMKeyVaultKeyExists(resourceName string) resource.TestCheckFu } name := rs.Primary.Attributes["name"] vaultBaseUrl := rs.Primary.Attributes["vault_uri"] + keyVaultId := rs.Primary.Attributes["key_vault_id"] - client := testAccProvider.Meta().(*ArmClient).keyVaultManagementClient - 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.GetKey(ctx, vaultBaseUrl, name, "") if err != nil { @@ -274,6 +297,9 @@ func testCheckAzureRMKeyVaultKeyExists(resourceName string) resource.TestCheckFu 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 { @@ -282,9 +308,16 @@ func testCheckAzureRMKeyVaultKeyDisappears(resourceName string) resource.TestChe name := rs.Primary.Attributes["name"] vaultBaseUrl := rs.Primary.Attributes["vault_uri"] + keyVaultId := rs.Primary.Attributes["key_vault_id"] - client := testAccProvider.Meta().(*ArmClient).keyVaultManagementClient - 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.DeleteKey(ctx, vaultBaseUrl, name) if err != nil { @@ -342,7 +375,7 @@ resource "azurerm_key_vault" "test" { resource "azurerm_key_vault_key" "test" { name = "key-%s" - vault_uri = "${azurerm_key_vault.test.vault_uri}" + key_vault_id = "${azurerm_key_vault.test.id}" key_type = "EC" key_size = 2048 @@ -361,7 +394,7 @@ func testAccAzureRMKeyVaultKey_requiresImport(rString string, location string) s resource "azurerm_key_vault_key" "import" { name = "${azurerm_key_vault_key.test.name}" - vault_uri = "${azurerm_key_vault_key.test.vault_uri}" + key_vault_id = "${azurerm_key_vault.test.id}" key_type = "EC" key_size = 2048 @@ -417,7 +450,7 @@ resource "azurerm_key_vault" "test" { resource "azurerm_key_vault_key" "test" { name = "key-%s" - vault_uri = "${azurerm_key_vault.test.vault_uri}" + key_vault_id = "${azurerm_key_vault.test.id}" key_type = "RSA" key_size = 2048 @@ -476,7 +509,7 @@ resource "azurerm_key_vault" "test" { resource "azurerm_key_vault_key" "test" { name = "key-%s" - vault_uri = "${azurerm_key_vault.test.vault_uri}" + key_vault_id = "${azurerm_key_vault.test.id}" key_type = "RSA-HSM" key_size = 2048 @@ -534,10 +567,10 @@ resource "azurerm_key_vault" "test" { } resource "azurerm_key_vault_key" "test" { - name = "key-%s" - vault_uri = "${azurerm_key_vault.test.vault_uri}" - key_type = "RSA" - key_size = 2048 + name = "key-%s" + key_vault_id = "${azurerm_key_vault.test.id}" + key_type = "RSA" + key_size = 2048 key_opts = [ "decrypt", diff --git a/azurerm/resource_arm_key_vault_secret.go b/azurerm/resource_arm_key_vault_secret.go index 0a82fa88d8a0..a8f324ec5dfc 100644 --- a/azurerm/resource_arm_key_vault_secret.go +++ b/azurerm/resource_arm_key_vault_secret.go @@ -19,7 +19,7 @@ func resourceArmKeyVaultSecret() *schema.Resource { Update: resourceArmKeyVaultSecretUpdate, Delete: resourceArmKeyVaultSecretDelete, Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + State: resourceArmKeyVaultChildResourceImporter, }, Schema: map[string]*schema.Schema{ @@ -30,11 +30,24 @@ func resourceArmKeyVaultSecret() *schema.Resource { ValidateFunc: azure.ValidateKeyVaultChildName, }, + "key_vault_id": { + Type: schema.TypeString, + Optional: true, //todo required in 2.0 + Computed: true, //todo removed in 2.0 + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + ConflictsWith: []string{"vault_uri"}, + }, + + //todo remove in 2.0 "vault_uri": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validate.URLIsHTTPS, + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + Deprecated: "This property has been deprecated in favour of the key_vault_id property. This will prevent a class of bugs as described in https://github.com/terraform-providers/terraform-provider-azurerm/issues/2396 and will be removed in version 2.0 of the provider", + ValidateFunc: validate.URLIsHTTPS, + ConflictsWith: []string{"key_vault_id"}, }, "value": { @@ -59,6 +72,7 @@ func resourceArmKeyVaultSecret() *schema.Resource { } func resourceArmKeyVaultSecretCreate(d *schema.ResourceData, meta interface{}) error { + vaultClient := meta.(*ArmClient).keyVaultClient client := meta.(*ArmClient).keyVaultManagementClient ctx := meta.(*ArmClient).StopContext @@ -66,6 +80,26 @@ func resourceArmKeyVaultSecretCreate(d *schema.ResourceData, meta interface{}) e name := d.Get("name").(string) keyVaultBaseUrl := d.Get("vault_uri").(string) + keyVaultId := d.Get("key_vault_id").(string) + + if keyVaultBaseUrl == "" { + if keyVaultId == "" { + return fmt.Errorf("one of `key_vault_id` or `vault_uri` must be set") + } + + pKeyVaultBaseUrl, err := azure.GetKeyVaultBaseUrlFromID(ctx, vaultClient, keyVaultId) + if err != nil { + return fmt.Errorf("Error looking up Secret %q vault url form id %q: %+v", name, keyVaultId, err) + } + + keyVaultBaseUrl = pKeyVaultBaseUrl + } else { + id, err := azure.GetKeyVaultIDFromBaseUrl(ctx, vaultClient, keyVaultBaseUrl) + if err != nil { + return fmt.Errorf("Error unable to find key vault ID from URL %q for certificate %q: %+v", keyVaultBaseUrl, name, err) + } + d.Set("key_vault_id", id) + } if requireResourcesToBeImported { existing, err := client.GetSecret(ctx, keyVaultBaseUrl, name, "") @@ -113,11 +147,22 @@ func resourceArmKeyVaultSecretUpdate(d *schema.ResourceData, meta interface{}) e ctx := meta.(*ArmClient).StopContext log.Print("[INFO] preparing arguments for AzureRM KeyVault Secret update.") + keyVaultId := d.Get("key_vault_id").(string) id, err := azure.ParseKeyVaultChildID(d.Id()) if err != nil { return err } + ok, err := azure.KeyVaultExists(ctx, 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, id.Name, id.KeyVaultBaseUrl, err) + } + if !ok { + log.Printf("[DEBUG] Secret %q Key Vault %q was not found in Key Vault at URI %q - removing from state", id.Name, keyVaultId, id.KeyVaultBaseUrl) + d.SetId("") + return nil + } + value := d.Get("value").(string) contentType := d.Get("content_type").(string) tags := d.Get("tags").(map[string]interface{}) @@ -164,11 +209,22 @@ func resourceArmKeyVaultSecretRead(d *schema.ResourceData, meta interface{}) err client := meta.(*ArmClient).keyVaultManagementClient ctx := meta.(*ArmClient).StopContext + keyVaultId := d.Get("key_vault_id").(string) id, err := azure.ParseKeyVaultChildID(d.Id()) if err != nil { return err } + ok, err := azure.KeyVaultExists(ctx, 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, id.Name, id.KeyVaultBaseUrl, err) + } + if !ok { + log.Printf("[DEBUG] Secret %q Key Vault %q was not found in Key Vault at URI %q - removing from state", id.Name, keyVaultId, id.KeyVaultBaseUrl) + d.SetId("") + return nil + } + // we always want to get the latest version resp, err := client.GetSecret(ctx, id.KeyVaultBaseUrl, id.Name, "") if err != nil { @@ -200,11 +256,22 @@ func resourceArmKeyVaultSecretDelete(d *schema.ResourceData, meta interface{}) e client := meta.(*ArmClient).keyVaultManagementClient ctx := meta.(*ArmClient).StopContext + keyVaultId := d.Get("key_vault_id").(string) id, err := azure.ParseKeyVaultChildID(d.Id()) if err != nil { return err } + ok, err := azure.KeyVaultExists(ctx, 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, id.Name, id.KeyVaultBaseUrl, err) + } + if !ok { + log.Printf("[DEBUG] Secret %q Key Vault %q was not found in Key Vault at URI %q - removing from state", id.Name, keyVaultId, id.KeyVaultBaseUrl) + d.SetId("") + return nil + } + _, err = client.DeleteSecret(ctx, id.KeyVaultBaseUrl, id.Name) return err } diff --git a/azurerm/resource_arm_key_vault_secret_test.go b/azurerm/resource_arm_key_vault_secret_test.go index 53e6e94fd71d..f6b33121cceb 100644 --- a/azurerm/resource_arm_key_vault_secret_test.go +++ b/azurerm/resource_arm_key_vault_secret_test.go @@ -2,8 +2,11 @@ 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" @@ -176,6 +179,16 @@ func testCheckAzureRMKeyVaultSecretDestroy(s *terraform.State) error { 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 + } // get the latest version resp, err := client.GetSecret(ctx, vaultBaseUrl, name, "") @@ -194,6 +207,9 @@ func testCheckAzureRMKeyVaultSecretDestroy(s *terraform.State) error { func testCheckAzureRMKeyVaultSecretExists(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 { @@ -201,9 +217,16 @@ func testCheckAzureRMKeyVaultSecretExists(resourceName string) resource.TestChec } name := rs.Primary.Attributes["name"] vaultBaseUrl := rs.Primary.Attributes["vault_uri"] + keyVaultId := rs.Primary.Attributes["key_vault_id"] - client := testAccProvider.Meta().(*ArmClient).keyVaultManagementClient - 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 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.GetSecret(ctx, vaultBaseUrl, name, "") if err != nil { @@ -220,6 +243,9 @@ func testCheckAzureRMKeyVaultSecretExists(resourceName string) resource.TestChec func testCheckAzureRMKeyVaultSecretDisappears(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 { @@ -227,9 +253,16 @@ func testCheckAzureRMKeyVaultSecretDisappears(resourceName string) resource.Test } name := rs.Primary.Attributes["name"] vaultBaseUrl := rs.Primary.Attributes["vault_uri"] + keyVaultId := rs.Primary.Attributes["key_vault_id"] - client := testAccProvider.Meta().(*ArmClient).keyVaultManagementClient - 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 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.DeleteSecret(ctx, vaultBaseUrl, name) if err != nil { @@ -286,7 +319,7 @@ resource "azurerm_key_vault" "test" { resource "azurerm_key_vault_secret" "test" { name = "secret-%s" value = "rick-and-morty" - vault_uri = "${azurerm_key_vault.test.vault_uri}" + key_vault_id = "${azurerm_key_vault.test.id}" } `, rString, location, rString, rString) } @@ -299,7 +332,7 @@ func testAccAzureRMKeyVaultSecret_requiresImport(rString string, location string resource "azurerm_key_vault_secret" "import" { name = "${azurerm_key_vault_secret.test.name}" value = "${azurerm_key_vault_secret.test.value}" - vault_uri = "${azurerm_key_vault_secret.test.vault_uri}" + key_vault_id = "${azurerm_key_vault_secret.test.key_vault_id}" } `, template) } @@ -346,7 +379,7 @@ resource "azurerm_key_vault" "test" { resource "azurerm_key_vault_secret" "test" { name = "secret-%s" value = "" - vault_uri = "${azurerm_key_vault.test.vault_uri}" + key_vault_id = "${azurerm_key_vault.test.id}" content_type = "application/xml" tags { diff --git a/azurerm/resource_arm_sql_administrator.go b/azurerm/resource_arm_sql_administrator.go index ce46b8ad04fd..08172e75e328 100644 --- a/azurerm/resource_arm_sql_administrator.go +++ b/azurerm/resource_arm_sql_administrator.go @@ -6,7 +6,7 @@ import ( "github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/2015-05-01-preview/sql" "github.com/hashicorp/terraform/helper/schema" - "github.com/satori/go.uuid" + uuid "github.com/satori/go.uuid" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) diff --git a/azurerm/resource_arm_sql_database.go b/azurerm/resource_arm_sql_database.go index c4ff9c72ebb1..55dd2c73df02 100644 --- a/azurerm/resource_arm_sql_database.go +++ b/azurerm/resource_arm_sql_database.go @@ -6,6 +6,7 @@ import ( "strings" "time" + "github.com/satori/go.uuid" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" @@ -13,7 +14,6 @@ import ( "github.com/Azure/go-autorest/autorest/date" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" - "github.com/satori/go.uuid" "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" diff --git a/website/docs/d/key_vault_key.html.markdown b/website/docs/d/key_vault_key.html.markdown index d09e1dc00628..db22ff096b35 100644 --- a/website/docs/d/key_vault_key.html.markdown +++ b/website/docs/d/key_vault_key.html.markdown @@ -33,7 +33,7 @@ The following arguments are supported: * `name` - (Required) Specifies the name of the Key Vault Key. -* `vault_uri` - (Required) Specifies the URI used to access the Key Vault instance, available on the `azurerm_key_vault` Data Source / Resource. +* `vault_uri` - (Required) Specifies the ID of the Key Vault Key Vault instance where the Key resides, available on the `azurerm_key_vault` Data Source / Resource. ## Attributes Reference diff --git a/website/docs/d/key_vault_secret.html.markdown b/website/docs/d/key_vault_secret.html.markdown index 954cf8a61530..fee5997351fe 100644 --- a/website/docs/d/key_vault_secret.html.markdown +++ b/website/docs/d/key_vault_secret.html.markdown @@ -33,7 +33,7 @@ The following arguments are supported: * `name` - (Required) Specifies the name of the Key Vault Secret. -* `vault_uri` - (Required) Specifies the URI used to access the Key Vault instance, available on the `azurerm_key_vault` Data Source / Resource. +* `vault_uri` - (Required) Specifies the ID of the Key Vault Key Vault instance where the Secret resides, available on the `azurerm_key_vault` Data Source / Resource. ## Attributes Reference diff --git a/website/docs/r/key_vault_certificate.html.markdown b/website/docs/r/key_vault_certificate.html.markdown index 6c79b733702b..cd56a0265450 100644 --- a/website/docs/r/key_vault_certificate.html.markdown +++ b/website/docs/r/key_vault_certificate.html.markdown @@ -89,8 +89,8 @@ resource "azurerm_key_vault" "test" { } resource "azurerm_key_vault_certificate" "test" { - name = "imported-cert" - vault_uri = "${azurerm_key_vault.test.vault_uri}" + name = "imported-cert" + key_vault_id = "${azurerm_key_vault.test.id}" certificate { contents = "${base64encode(file("certificate-to-import.pfx"))}" @@ -164,8 +164,8 @@ resource "azurerm_key_vault" "test" { } resource "azurerm_key_vault_certificate" "test" { - name = "generated-cert" - vault_uri = "${azurerm_key_vault.test.vault_uri}" + name = "generated-cert" + key_vault_id = "${azurerm_key_vault.test.id}" certificate_policy { issuer_parameters { @@ -225,7 +225,7 @@ The following arguments are supported: * `name` - (Required) Specifies the name of the Key Vault Certificate. Changing this forces a new resource to be created. -* `vault_uri` - (Required) Specifies the URI used to access the Key Vault instance, available on the `azurerm_key_vault` resource. +* `key_vault_id` - (Required) The ID of the Key Vault where the Certificate should be created. * `certificate` - (Optional) A `certificate` block as defined below, used to Import an existing certificate. diff --git a/website/docs/r/key_vault_key.html.markdown b/website/docs/r/key_vault_key.html.markdown index a256b8f7d514..5bd26420bc4b 100644 --- a/website/docs/r/key_vault_key.html.markdown +++ b/website/docs/r/key_vault_key.html.markdown @@ -30,7 +30,7 @@ resource "random_id" "server" { } resource "azurerm_key_vault" "test" { - name = "${format("%s%s", "kv", random_id.server.hex)}" + name = "keyvaultkeyexample" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -60,7 +60,7 @@ resource "azurerm_key_vault" "test" { resource "azurerm_key_vault_key" "generated" { name = "generated-certificate" - vault_uri = "${azurerm_key_vault.test.vault_uri}" + key_vault_id = "${azurerm_key_vault.test.id}" key_type = "RSA" key_size = 2048 @@ -81,7 +81,7 @@ The following arguments are supported: * `name` - (Required) Specifies the name of the Key Vault Key. Changing this forces a new resource to be created. -* `vault_uri` - (Required) Specifies the URI used to access the Key Vault instance, available on the `azurerm_key_vault` resource. +* `key_vault_id` - (Required) The ID of the Key Vault where the Key should be created. * `key_type` - (Required) Specifies the Key Type to use for this Key Vault Key. Possible values are `EC` (Elliptic Curve), `Oct` (Octet), `RSA` and `RSA-HSM`. Changing this forces a new resource to be created. diff --git a/website/docs/r/key_vault_secret.html.markdown b/website/docs/r/key_vault_secret.html.markdown index 1de443188fb2..4faa67433afa 100644 --- a/website/docs/r/key_vault_secret.html.markdown +++ b/website/docs/r/key_vault_secret.html.markdown @@ -64,9 +64,9 @@ resource "azurerm_key_vault" "test" { } resource "azurerm_key_vault_secret" "test" { - name = "secret-sauce" - value = "szechuan" - vault_uri = "${azurerm_key_vault.test.vault_uri}" + name = "secret-sauce" + value = "szechuan" + key_vault_id = "${azurerm_key_vault.test.id}" tags { environment = "Production" @@ -82,7 +82,7 @@ The following arguments are supported: * `value` - (Required) Specifies the value of the Key Vault Secret. -* `vault_uri` - (Required) Specifies the URI used to access the Key Vault instance, available on the `azurerm_key_vault` resource. +* `key_vault_id` - (Required) The ID of the Key Vault where the Secret should be created. * `content_type` - (Optional) Specifies the content type for the Key Vault Secret.