From 14c7cc77510908a12c84d06418ce24e584673e41 Mon Sep 17 00:00:00 2001 From: Jochen Rauschenbusch Date: Mon, 29 Jun 2020 13:00:33 +0200 Subject: [PATCH 01/15] New Resource: kusto_cluster_customer_managed_key --- ...o_cluster_customer_managed_key_resource.go | 258 +++++++++++++++++ .../internal/services/kusto/registration.go | 9 +- ...kusto_cluster_customer_managed_key_test.go | 264 ++++++++++++++++++ website/azurerm.erb | 3 + ...cluster_customer_managed_key.html.markdown | 122 ++++++++ 5 files changed, 652 insertions(+), 4 deletions(-) create mode 100644 azurerm/internal/services/kusto/kusto_cluster_customer_managed_key_resource.go create mode 100644 azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go create mode 100644 website/docs/r/kusto_cluster_customer_managed_key.html.markdown diff --git a/azurerm/internal/services/kusto/kusto_cluster_customer_managed_key_resource.go b/azurerm/internal/services/kusto/kusto_cluster_customer_managed_key_resource.go new file mode 100644 index 000000000000..5fa036a5dd3c --- /dev/null +++ b/azurerm/internal/services/kusto/kusto_cluster_customer_managed_key_resource.go @@ -0,0 +1,258 @@ +package kusto + +import ( + "fmt" + "log" + "time" + + "github.com/Azure/azure-sdk-for-go/services/kusto/mgmt/2020-02-15/kusto" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + "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/internal/clients" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" + keyVaultParse "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/keyvault/parse" + keyVaultValidate "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/keyvault/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/kusto/parse" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmKustoClusterCustomerManagedKey() *schema.Resource { + return &schema.Resource{ + Create: resourceArmKustoClusterCustomerManagedKeyCreateUpdate, + Read: resourceArmKustoClusterCustomerManagedKeyRead, + Update: resourceArmKustoClusterCustomerManagedKeyCreateUpdate, + Delete: resourceArmKustoClusterCustomerManagedKeyDelete, + + // TODO: this needs a custom ID validating importer + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(30 * time.Minute), + Read: schema.DefaultTimeout(5 * time.Minute), + Update: schema.DefaultTimeout(30 * time.Minute), + Delete: schema.DefaultTimeout(30 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "cluster_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + }, + + "key_vault_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: keyVaultValidate.KeyVaultID, + }, + + "key_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "key_version": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + }, + } +} + +func resourceArmKustoClusterCustomerManagedKeyCreateUpdate(d *schema.ResourceData, meta interface{}) error { + clusterClient := meta.(*clients.Client).Kusto.ClustersClient + vaultsClient := meta.(*clients.Client).KeyVault.VaultsClient + ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d) + defer cancel() + + clusterIDRaw := d.Get("cluster_id").(string) + clusterID, err := parse.KustoClusterID(clusterIDRaw) + if err != nil { + return err + } + + locks.ByName(clusterID.Name, "azurerm_kusto_cluster") + defer locks.UnlockByName(clusterID.Name, "azurerm_kusto_cluster") + + cluster, err := clusterClient.Get(ctx, clusterID.ResourceGroup, clusterID.Name) + if err != nil { + return fmt.Errorf("Error retrieving Kusto Cluster %q (Resource Group %q): %+v", clusterID.Name, clusterID.ResourceGroup, err) + } + if cluster.KeyVaultProperties == nil { + return fmt.Errorf("Error retrieving Kusto Cluster %q (Resource Group %q): `properties` was nil", clusterID.Name, clusterID.ResourceGroup) + } + + // since we're mutating the kusto cluster here, we can use that as the ID + resourceID := clusterIDRaw + + if d.IsNewResource() { + // whilst this looks superflurious given encryption is enabled by default, due to the way + // the Azure API works this technically can be nil + if cluster.ClusterProperties.KeyVaultProperties != nil { + return tf.ImportAsExistsError("azurerm_storage_account_customer_managed_key", resourceID) + } + } + + keyVaultIDRaw := d.Get("key_vault_id").(string) + keyVaultID, err := keyVaultParse.KeyVaultID(keyVaultIDRaw) + if err != nil { + return err + } + + keyVault, err := vaultsClient.Get(ctx, keyVaultID.ResourceGroup, keyVaultID.Name) + if err != nil { + return fmt.Errorf("Error retrieving Key Vault %q (Resource Group %q): %+v", keyVaultID.Name, keyVaultID.ResourceGroup, err) + } + + softDeleteEnabled := false + purgeProtectionEnabled := false + if props := keyVault.Properties; props != nil { + if esd := props.EnableSoftDelete; esd != nil { + softDeleteEnabled = *esd + } + if epp := props.EnablePurgeProtection; epp != nil { + purgeProtectionEnabled = *epp + } + } + if !softDeleteEnabled || !purgeProtectionEnabled { + return fmt.Errorf("Key Vault %q (Resource Group %q) must be configured for both Purge Protection and Soft Delete", keyVaultID.Name, keyVaultID.ResourceGroup) + } + + keyVaultBaseURL, err := azure.GetKeyVaultBaseUrlFromID(ctx, vaultsClient, keyVaultIDRaw) + if err != nil { + return fmt.Errorf("Error looking up Key Vault URI from Key Vault %q (Resource Group %q): %+v", keyVaultID.Name, keyVaultID.ResourceGroup, err) + } + + keyName := d.Get("key_name").(string) + keyVersion := d.Get("key_version").(string) + props := kusto.ClusterUpdate{ + ClusterProperties: &kusto.ClusterProperties{ + KeyVaultProperties: &kusto.KeyVaultProperties{ + KeyName: utils.String(keyName), + KeyVersion: utils.String(keyVersion), + KeyVaultURI: utils.String(keyVaultBaseURL), + }, + }, + } + + if _, err = clusterClient.Update(ctx, clusterID.ResourceGroup, clusterID.Name, props); err != nil { + return fmt.Errorf("Error updating Customer Managed Key for Kusto Cluster %q (Resource Group %q): %+v", clusterID.Name, clusterID.ResourceGroup, err) + } + + d.SetId(resourceID) + + return resourceArmKustoClusterCustomerManagedKeyRead(d, meta) +} + +func resourceArmKustoClusterCustomerManagedKeyRead(d *schema.ResourceData, meta interface{}) error { + clusterClient := meta.(*clients.Client).Kusto.ClustersClient + vaultsClient := meta.(*clients.Client).KeyVault.VaultsClient + ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) + defer cancel() + + clusterID, err := parse.KustoClusterID(d.Id()) + if err != nil { + return err + } + + cluster, err := clusterClient.Get(ctx, clusterID.ResourceGroup, clusterID.Name) + if err != nil { + if utils.ResponseWasNotFound(cluster.Response) { + log.Printf("[DEBUG] Kusto Cluster %q could not be found in Resource Group %q - removing from state!", clusterID.Name, clusterID.ResourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving Kusto Cluster %q (Resource Group %q): %+v", clusterID.Name, clusterID.ResourceGroup, err) + } + if cluster.ClusterProperties == nil { + return fmt.Errorf("Error retrieving Kusto Cluster %q (Resource Group %q): `properties` was nil", clusterID.Name, clusterID.ResourceGroup) + } + if cluster.ClusterProperties.KeyVaultProperties == nil { + log.Printf("[DEBUG] Customer Managed Key was not defined for Kusto Cluster %q (Resource Group %q) - removing from state!", clusterID.Name, clusterID.ResourceGroup) + d.SetId("") + return nil + } + + props := cluster.ClusterProperties.KeyVaultProperties + + keyName := "" + keyVaultURI := "" + keyVersion := "" + if props != nil { + if props.KeyName != nil { + keyName = *props.KeyName + } + if props.KeyVaultURI != nil { + keyVaultURI = *props.KeyVaultURI + } + if props.KeyVersion != nil { + keyVersion = *props.KeyVersion + } + } + + if keyVaultURI == "" { + return fmt.Errorf("Error retrieving Kusto Cluster %q (Resource Group %q): `properties.keyVaultProperties.keyVaultUri` was nil", clusterID.Name, clusterID.ResourceGroup) + } + + // now we have the key vault uri we can look up the ID + keyVaultID, err := azure.GetKeyVaultIDFromBaseUrl(ctx, vaultsClient, keyVaultURI) + if err != nil { + return fmt.Errorf("Error retrieving Key Vault ID from the Base URI %q: %+v", keyVaultURI, err) + } + + d.Set("cluster_id", d.Id()) + d.Set("key_vault_id", keyVaultID) + d.Set("key_name", keyName) + d.Set("key_version", keyVersion) + + return nil +} + +func resourceArmKustoClusterCustomerManagedKeyDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).Kusto.ClustersClient + ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) + defer cancel() + + clusterID, err := parse.KustoClusterID(d.Id()) + if err != nil { + return err + } + + locks.ByName(clusterID.Name, "azurerm_kusto_cluster") + defer locks.UnlockByName(clusterID.Name, "azurerm_kusto_cluster") + + // confirm it still exists prior to trying to update it, else we'll get an error + cluster, err := client.Get(ctx, clusterID.ResourceGroup, clusterID.Name) + if err != nil { + if utils.ResponseWasNotFound(cluster.Response) { + return nil + } + + return fmt.Errorf("Error retrieving Kusto Cluster %q (Resource Group %q): %+v", clusterID.Name, clusterID.ResourceGroup, err) + } + + // Since this isn't a real object, just modifying an existing object + // "Delete" doesn't really make sense it should really be a "Revert to Default" + // So instead of the Delete func actually deleting the Kusto Cluster I am + // making it reset the Kusto Cluster to it's default state + props := kusto.ClusterUpdate{ + ClusterProperties: &kusto.ClusterProperties{ + KeyVaultProperties: &kusto.KeyVaultProperties{}, + }, + } + + if _, err = client.Update(ctx, clusterID.ResourceGroup, clusterID.Name, props); err != nil { + return fmt.Errorf("Error removing Customer Managed Key for Kusto Cluster %q (Resource Group %q): %+v", clusterID.Name, clusterID.ResourceGroup, err) + } + + return nil +} diff --git a/azurerm/internal/services/kusto/registration.go b/azurerm/internal/services/kusto/registration.go index 6a0414cffb4e..83d306afe0be 100644 --- a/azurerm/internal/services/kusto/registration.go +++ b/azurerm/internal/services/kusto/registration.go @@ -28,9 +28,10 @@ func (r Registration) SupportedDataSources() map[string]*schema.Resource { // SupportedResources returns the supported Resources supported by this Service func (r Registration) SupportedResources() map[string]*schema.Resource { return map[string]*schema.Resource{ - "azurerm_kusto_cluster": resourceArmKustoCluster(), - "azurerm_kusto_database": resourceArmKustoDatabase(), - "azurerm_kusto_database_principal": resourceArmKustoDatabasePrincipal(), - "azurerm_kusto_eventhub_data_connection": resourceArmKustoEventHubDataConnection(), + "azurerm_kusto_cluster": resourceArmKustoCluster(), + "azurerm_kusto_cluster_customer_managed_key": resourceArmKustoClusterCustomerManagedKey(), + "azurerm_kusto_database": resourceArmKustoDatabase(), + "azurerm_kusto_database_principal": resourceArmKustoDatabasePrincipal(), + "azurerm_kusto_eventhub_data_connection": resourceArmKustoEventHubDataConnection(), } } diff --git a/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go b/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go new file mode 100644 index 000000000000..9b95fa63eb24 --- /dev/null +++ b/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go @@ -0,0 +1,264 @@ +package tests + +import ( + "fmt" + "net/http" + "testing" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" +) + +func TestAccAzureRMKustoClusterCustomerManagedKey_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_kusto_cluster_customer_managed_key", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMKustoClusterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMKustoClusterCustomerManagedKey_basic(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKustoClusterCustomerManagedKeyExists(data.ResourceName), + ), + }, + data.ImportStep(), + { + // Delete the encryption settings resource and verify it is gone + Config: testAccAzureRMKustoClusterCustomerManagedKey_template(data), + Check: resource.ComposeTestCheckFunc( + // Then ensure the encryption settings on the storage account + // have been reverted to their default state + testCheckAzureRMKustoClusterExistsWithDefaultSettings("azurerm_kusto_cluster.test"), + ), + }, + }, + }) +} + +func TestAccAzureRMKustoClusterCustomerManagedKey_requiresImport(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_kusto_cluster_customer_managed_key", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMKustoClusterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMKustoClusterCustomerManagedKey_basic(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKustoClusterCustomerManagedKeyExists(data.ResourceName), + ), + }, + data.RequiresImportErrorStep(testAccAzureRMKustoClusterCustomerManagedKey_requiresImport), + }, + }) +} + +func TestAccAzureRMKustoClusterCustomerManagedKey_updateKey(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_kusto_cluster_customer_managed_key", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMKustoClusterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMKustoClusterCustomerManagedKey_basic(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKustoClusterCustomerManagedKeyExists(data.ResourceName), + ), + }, + data.ImportStep(), + { + Config: testAccAzureRMKustoClusterCustomerManagedKey_updated(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKustoClusterCustomerManagedKeyExists(data.ResourceName), + ), + }, + data.ImportStep(), + }, + }) +} + +func testCheckAzureRMKustoClusterExistsWithDefaultSettings(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + kustoCluster := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + // Ensure resource group exists in API + ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext + conn := acceptance.AzureProvider.Meta().(*clients.Client).Kusto.ClustersClient + + resp, err := conn.Get(ctx, resourceGroup, kustoCluster) + if err != nil { + return fmt.Errorf("Bad: Get on Kusto ClustersClient: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Kusto Cluster %q (resource group: %q) does not exist", kustoCluster, resourceGroup) + } + + if props := resp.ClusterProperties; props != nil { + return fmt.Errorf("Kusto Cluster encryption properties not found: %s", resourceName) + } + + return nil + } +} + +func testCheckAzureRMKustoClusterCustomerManagedKeyExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + if kustoClusterId := rs.Primary.Attributes["storage_account_id"]; kustoClusterId == "" { + return fmt.Errorf("Unable to read kustoClusterId: %s", resourceName) + } + + return nil + } +} + +func testAccAzureRMKustoClusterCustomerManagedKey_basic(data acceptance.TestData) string { + template := testAccAzureRMKustoClusterCustomerManagedKey_template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_kusto_cluster_customer_managed_key" "test" { + cluster_id = azurerm_kusto_cluster.test.id + key_vault_id = azurerm_key_vault.test.id + key_name = azurerm_key_vault_key.first.name + key_version = azurerm_key_vault_key.first.version +} +`, template) +} + +func testAccAzureRMKustoClusterCustomerManagedKey_requiresImport(data acceptance.TestData) string { + template := testAccAzureRMKustoClusterCustomerManagedKey_basic(data) + return fmt.Sprintf(` +%s + +resource "azurerm_kusto_cluster_customer_managed_key" "import" { + cluster_id = azurerm_storage_account_customer_managed_key.test.cluster_id + key_vault_id = azurerm_storage_account_customer_managed_key.test.key_vault_id + key_name = azurerm_storage_account_customer_managed_key.test.key_name + key_version = azurerm_storage_account_customer_managed_key.test.key_version +} +`, template) +} + +func testAccAzureRMKustoClusterCustomerManagedKey_updated(data acceptance.TestData) string { + template := testAccAzureRMKustoClusterCustomerManagedKey_template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_key_vault_key" "second" { + name = "second" + key_vault_id = azurerm_key_vault.test.id + key_type = "RSA" + key_size = 2048 + key_opts = ["decrypt", "encrypt", "sign", "unwrapKey", "verify", "wrapKey"] + + depends_on = [ + azurerm_key_vault_access_policy.client, + azurerm_key_vault_access_policy.cluster, + ] +} + +resource "azurerm_kusto_cluster_customer_managed_key" "test" { + cluster_id = azurerm_kusto_cluster.test.id + key_vault_id = azurerm_key_vault.test.id + key_name = azurerm_key_vault_key.second.name + key_version = azurerm_key_vault_key.second.version +} +`, template) +} + +func testAccAzureRMKustoClusterCustomerManagedKey_template(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features { + key_vault { + purge_soft_delete_on_destroy = false + } + } +} + +data "azurerm_client_config" "current" {} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + 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 = "standard" + soft_delete_enabled = true + purge_protection_enabled = true +} + +resource "azurerm_key_vault_access_policy" "cluster" { + key_vault_id = azurerm_key_vault.test.id + tenant_id = azurerm_kusto_cluster.test.identity.0.tenant_id + object_id = azurerm_kusto_cluster.test.identity.0.principal_id + + key_permissions = ["get", "create", "list", "restore", "recover", "unwrapkey", "wrapkey", "purge", "encrypt", "decrypt", "sign", "verify"] + secret_permissions = ["get"] +} + +resource "azurerm_key_vault_access_policy" "client" { + key_vault_id = azurerm_key_vault.test.id + tenant_id = data.azurerm_client_config.current.tenant_id + object_id = data.azurerm_client_config.current.object_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 = "test" + key_vault_id = azurerm_key_vault.test.id + key_type = "RSA" + key_size = 2048 + key_opts = ["decrypt", "encrypt", "sign", "unwrapKey", "verify", "wrapKey"] + + depends_on = [ + azurerm_key_vault_access_policy.client, + azurerm_key_vault_access_policy.cluster, + ] +} + +resource "azurerm_kusto_cluster" "test" { + name = "acctestkc%s" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + + sku { + name = "Dev(No SLA)_Standard_D11_v2" + capacity = 1 + } + + identity { + type = "SystemAssigned" + } +} +`, data.RandomInteger, data.Locations.Primary, data.RandomString, data.RandomString) +} diff --git a/website/azurerm.erb b/website/azurerm.erb index 6d17486ebce1..d19153559798 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -1394,6 +1394,9 @@
  • azurerm_kusto_cluster
  • +
  • + azurerm_kusto_cluster_customer_managed_key +
  • azurerm_kusto_database
  • diff --git a/website/docs/r/kusto_cluster_customer_managed_key.html.markdown b/website/docs/r/kusto_cluster_customer_managed_key.html.markdown new file mode 100644 index 000000000000..2381e0e3fd0d --- /dev/null +++ b/website/docs/r/kusto_cluster_customer_managed_key.html.markdown @@ -0,0 +1,122 @@ +--- +subcategory: "Data Explorer" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_kusto_cluster_customer_managed_key" +description: |- + Manages a Customer Managed Key for a Kusto Cluster. +--- + +# azurerm_kusto_cluster_customer_managed_key + +Manages a Customer Managed Key for a Kusto Cluster. + +## Example Usage + +```hcl +data "azurerm_client_config" "current" {} + +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_key_vault" "example" { + name = "examplekv" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + tenant_id = data.azurerm_client_config.current.tenant_id + sku_name = "standard" + + soft_delete_enabled = true + purge_protection_enabled = true +} + +resource "azurerm_key_vault_access_policy" "cluster" { + key_vault_id = azurerm_key_vault.example.id + tenant_id = data.azurerm_client_config.current.tenant_id + object_id = azurerm_kusto_cluster.example.identity.0.principal_id + + key_permissions = ["get", "create", "list", "restore", "recover", "unwrapkey", "wrapkey", "purge", "encrypt", "decrypt", "sign", "verify"] + secret_permissions = ["get"] +} + +resource "azurerm_key_vault_access_policy" "client" { + key_vault_id = azurerm_key_vault.example.id + tenant_id = data.azurerm_client_config.current.tenant_id + object_id = data.azurerm_client_config.current.object_id + + key_permissions = ["get", "create", "delete", "list", "restore", "recover", "unwrapkey", "wrapkey", "purge", "encrypt", "decrypt", "sign", "verify"] + secret_permissions = ["get"] +} + + +resource "azurerm_key_vault_key" "example" { + name = "tfex-key" + key_vault_id = azurerm_key_vault.example.id + key_type = "RSA" + key_size = 2048 + key_opts = ["decrypt", "encrypt", "sign", "unwrapKey", "verify", "wrapKey"] + + depends_on = [ + azurerm_key_vault_access_policy.client, + azurerm_key_vault_access_policy.cluster, + ] +} + +resource "azurerm_kusto_cluster" "example" { + name = "kustocluster" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + + sku { + name = "Standard_D13_v2" + capacity = 2 + } + + identity { + type = "SystemAssigned" + } +} + +resource "azurerm_kusto_cluster_customer_managed_key" "example" { + cluster_id = azurerm_kusto_cluster.example.id + key_vault_id = azurerm_key_vault.example.id + key_name = azurerm_key_vault_key.example.name + key_version = azurerm_key_vault_key.example.version +} +``` + +## Arguments Reference + +The following arguments are supported: + +* `cluster_id` - (Required) The ID of the Kusto Cluster. Changing this forces a new resource to be created. + +* `key_vault_id` - (Required) The ID of the Key Vault. Changing this forces a new resource to be created. + +* `key_name` - (Required) The name of Key Vault Key. + +* `key_version` - (Required) The version of Key Vault Key. + +## Attributes Reference + +In addition to the Arguments listed above - the following Attributes are exported: + +* `id` - The ID of the Kusto Cluster. + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions: + +* `create` - (Defaults to 30 minutes) Used when creating the Kusto Cluster Customer Managed Key. +* `read` - (Defaults to 5 minutes) Used when retrieving the Kusto Cluster Customer Managed Key. +* `update` - (Defaults to 30 minutes) Used when updating the Kusto Cluster Customer Managed Key. +* `delete` - (Defaults to 30 minutes) Used when deleting the Kusto Cluster Customer Managed Key. + +## Import + +Customer Managed Keys for a Kusto Cluster can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_kusto_cluster_customer_managed_key.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Kusto/Clusters/cluster1 +``` From ea8b48039555956d9551c012eb0dc64652318d0c Mon Sep 17 00:00:00 2001 From: Matthew Frahry Date: Wed, 1 Jul 2020 08:33:19 -0700 Subject: [PATCH 02/15] Update kusto_cluster_customer_managed_key_test.go --- .../kusto/tests/kusto_cluster_customer_managed_key_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go b/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go index 9b95fa63eb24..91a1a999d553 100644 --- a/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go +++ b/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go @@ -141,7 +141,8 @@ func testAccAzureRMKustoClusterCustomerManagedKey_basic(data acceptance.TestData resource "azurerm_kusto_cluster_customer_managed_key" "test" { cluster_id = azurerm_kusto_cluster.test.id key_vault_id = azurerm_key_vault.test.id - key_name = azurerm_key_vault_key.first.name + key_name = + .first.name key_version = azurerm_key_vault_key.first.version } `, template) @@ -233,7 +234,7 @@ resource "azurerm_key_vault_access_policy" "client" { secret_permissions = ["get"] } -resource "azurerm_key_vault_key" "test" { +resource "azurerm_key_vault_key" "first" { name = "test" key_vault_id = azurerm_key_vault.test.id key_type = "RSA" From 075050dbd0aa4268ea219bb2648347ccb0d302ac Mon Sep 17 00:00:00 2001 From: Matthew Frahry Date: Wed, 1 Jul 2020 10:36:16 -0700 Subject: [PATCH 03/15] Update kusto_cluster_customer_managed_key_test.go --- .../kusto/tests/kusto_cluster_customer_managed_key_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go b/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go index 91a1a999d553..34f39443ce46 100644 --- a/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go +++ b/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go @@ -141,8 +141,7 @@ func testAccAzureRMKustoClusterCustomerManagedKey_basic(data acceptance.TestData resource "azurerm_kusto_cluster_customer_managed_key" "test" { cluster_id = azurerm_kusto_cluster.test.id key_vault_id = azurerm_key_vault.test.id - key_name = - .first.name + key_name = azurerm_key_vault_key.first.name key_version = azurerm_key_vault_key.first.version } `, template) From c5939e20a9b504ab5022eed832d7d92cd48f362f Mon Sep 17 00:00:00 2001 From: Jochen Rauschenbusch Date: Thu, 9 Jul 2020 20:50:18 +0200 Subject: [PATCH 04/15] fix kusto resources registration --- azurerm/internal/services/kusto/registration.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/azurerm/internal/services/kusto/registration.go b/azurerm/internal/services/kusto/registration.go index 05f2c858a348..ff958b3c6a25 100644 --- a/azurerm/internal/services/kusto/registration.go +++ b/azurerm/internal/services/kusto/registration.go @@ -28,12 +28,13 @@ func (r Registration) SupportedDataSources() map[string]*schema.Resource { // SupportedResources returns the supported Resources supported by this Service func (r Registration) SupportedResources() map[string]*schema.Resource { return map[string]*schema.Resource{ - "azurerm_kusto_cluster": resourceArmKustoCluster(), - "azurerm_kusto_cluster_customer_managed_key": resourceArmKustoClusterCustomerManagedKey(), + "azurerm_kusto_cluster": resourceArmKustoCluster(), + "azurerm_kusto_cluster_customer_managed_key": resourceArmKustoClusterCustomerManagedKey(), "azurerm_kusto_cluster_principal_assignment": resourceArmKustoClusterPrincipalAssignment(), - "azurerm_kusto_database": resourceArmKustoDatabase(), - "azurerm_kusto_database_principal": resourceArmKustoDatabasePrincipal(), - "azurerm_kusto_eventhub_data_connection": resourceArmKustoEventHubDataConnection(), + "azurerm_kusto_database": resourceArmKustoDatabase(), + "azurerm_kusto_database_principal": resourceArmKustoDatabasePrincipal(), + "azurerm_kusto_database_principal_assignment": resourceArmKustoDatabasePrincipalAssignment(), + "azurerm_kusto_eventhub_data_connection": resourceArmKustoEventHubDataConnection(), "azurerm_kusto_attached_database_configuration": resourceArmKustoAttachedDatabaseConfiguration(), } } From a47479dc3f4ba3cbb1968bb3eb511c1846a3c475 Mon Sep 17 00:00:00 2001 From: Jochen Rauschenbusch Date: Thu, 9 Jul 2020 21:18:11 +0200 Subject: [PATCH 05/15] fix nil reference check --- .../kusto/kusto_cluster_customer_managed_key_resource.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azurerm/internal/services/kusto/kusto_cluster_customer_managed_key_resource.go b/azurerm/internal/services/kusto/kusto_cluster_customer_managed_key_resource.go index 5fa036a5dd3c..237454b69b89 100644 --- a/azurerm/internal/services/kusto/kusto_cluster_customer_managed_key_resource.go +++ b/azurerm/internal/services/kusto/kusto_cluster_customer_managed_key_resource.go @@ -86,7 +86,7 @@ func resourceArmKustoClusterCustomerManagedKeyCreateUpdate(d *schema.ResourceDat if err != nil { return fmt.Errorf("Error retrieving Kusto Cluster %q (Resource Group %q): %+v", clusterID.Name, clusterID.ResourceGroup, err) } - if cluster.KeyVaultProperties == nil { + if cluster.ClusterProperties == nil { return fmt.Errorf("Error retrieving Kusto Cluster %q (Resource Group %q): `properties` was nil", clusterID.Name, clusterID.ResourceGroup) } From 7c26de3838f4cee3595eb7aa27290cb1c9da708d Mon Sep 17 00:00:00 2001 From: Jochen Rauschenbusch Date: Thu, 9 Jul 2020 22:21:21 +0200 Subject: [PATCH 06/15] fix copy/paste error --- .../tests/kusto_cluster_customer_managed_key_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go b/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go index 34f39443ce46..659c927464b6 100644 --- a/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go +++ b/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go @@ -153,10 +153,10 @@ func testAccAzureRMKustoClusterCustomerManagedKey_requiresImport(data acceptance %s resource "azurerm_kusto_cluster_customer_managed_key" "import" { - cluster_id = azurerm_storage_account_customer_managed_key.test.cluster_id - key_vault_id = azurerm_storage_account_customer_managed_key.test.key_vault_id - key_name = azurerm_storage_account_customer_managed_key.test.key_name - key_version = azurerm_storage_account_customer_managed_key.test.key_version + cluster_id = azurerm_kusto_cluster_customer_managed_key.test.cluster_id + key_vault_id = azurerm_kusto_cluster_customer_managed_key.test.key_vault_id + key_name = azurerm_kusto_cluster_customer_managed_key.test.key_name + key_version = azurerm_kusto_cluster_customer_managed_key.test.key_version } `, template) } From 4c0138ba54fd46d0ff7473af4da182a39943a4b6 Mon Sep 17 00:00:00 2001 From: Jochen Rauschenbusch Date: Fri, 10 Jul 2020 08:50:07 +0200 Subject: [PATCH 07/15] fix wait for future --- ...usto_cluster_customer_managed_key_resource.go | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/azurerm/internal/services/kusto/kusto_cluster_customer_managed_key_resource.go b/azurerm/internal/services/kusto/kusto_cluster_customer_managed_key_resource.go index 237454b69b89..ab09b7238c5b 100644 --- a/azurerm/internal/services/kusto/kusto_cluster_customer_managed_key_resource.go +++ b/azurerm/internal/services/kusto/kusto_cluster_customer_managed_key_resource.go @@ -87,7 +87,7 @@ func resourceArmKustoClusterCustomerManagedKeyCreateUpdate(d *schema.ResourceDat return fmt.Errorf("Error retrieving Kusto Cluster %q (Resource Group %q): %+v", clusterID.Name, clusterID.ResourceGroup, err) } if cluster.ClusterProperties == nil { - return fmt.Errorf("Error retrieving Kusto Cluster %q (Resource Group %q): `properties` was nil", clusterID.Name, clusterID.ResourceGroup) + return fmt.Errorf("Error retrieving Kusto Cluster %q (Resource Group %q): `ClusterProperties` was nil", clusterID.Name, clusterID.ResourceGroup) } // since we're mutating the kusto cluster here, we can use that as the ID @@ -143,9 +143,13 @@ func resourceArmKustoClusterCustomerManagedKeyCreateUpdate(d *schema.ResourceDat }, } - if _, err = clusterClient.Update(ctx, clusterID.ResourceGroup, clusterID.Name, props); err != nil { + future, err := clusterClient.Update(ctx, clusterID.ResourceGroup, clusterID.Name, props) + if err != nil { return fmt.Errorf("Error updating Customer Managed Key for Kusto Cluster %q (Resource Group %q): %+v", clusterID.Name, clusterID.ResourceGroup, err) } + if err = future.WaitForCompletionRef(ctx, clusterClient.Client); err != nil { + return fmt.Errorf("Error waiting for completion of Kusto Cluster Update %q (Resource Group %q): %+v", clusterID.Name, clusterID.ResourceGroup, err) + } d.SetId(resourceID) @@ -174,7 +178,7 @@ func resourceArmKustoClusterCustomerManagedKeyRead(d *schema.ResourceData, meta return fmt.Errorf("Error retrieving Kusto Cluster %q (Resource Group %q): %+v", clusterID.Name, clusterID.ResourceGroup, err) } if cluster.ClusterProperties == nil { - return fmt.Errorf("Error retrieving Kusto Cluster %q (Resource Group %q): `properties` was nil", clusterID.Name, clusterID.ResourceGroup) + return fmt.Errorf("Error retrieving Kusto Cluster %q (Resource Group %q): `ClusterProperties` was nil", clusterID.Name, clusterID.ResourceGroup) } if cluster.ClusterProperties.KeyVaultProperties == nil { log.Printf("[DEBUG] Customer Managed Key was not defined for Kusto Cluster %q (Resource Group %q) - removing from state!", clusterID.Name, clusterID.ResourceGroup) @@ -250,9 +254,13 @@ func resourceArmKustoClusterCustomerManagedKeyDelete(d *schema.ResourceData, met }, } - if _, err = client.Update(ctx, clusterID.ResourceGroup, clusterID.Name, props); err != nil { + future, err := client.Update(ctx, clusterID.ResourceGroup, clusterID.Name, props) + if err != nil { return fmt.Errorf("Error removing Customer Managed Key for Kusto Cluster %q (Resource Group %q): %+v", clusterID.Name, clusterID.ResourceGroup, err) } + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for completion of Kusto Cluster Update %q (Resource Group %q): %+v", clusterID.Name, clusterID.ResourceGroup, err) + } return nil } From 4ac6f298e3320e300c3c61e3fc74a362c2fea6b0 Mon Sep 17 00:00:00 2001 From: Jochen Rauschenbusch Date: Fri, 17 Jul 2020 14:39:03 +0200 Subject: [PATCH 08/15] fix: least permissions --- .../kusto/tests/kusto_cluster_customer_managed_key_test.go | 6 ++---- .../r/kusto_cluster_customer_managed_key.html.markdown | 7 ++----- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go b/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go index 659c927464b6..60c875de9e07 100644 --- a/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go +++ b/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go @@ -220,8 +220,7 @@ resource "azurerm_key_vault_access_policy" "cluster" { tenant_id = azurerm_kusto_cluster.test.identity.0.tenant_id object_id = azurerm_kusto_cluster.test.identity.0.principal_id - key_permissions = ["get", "create", "list", "restore", "recover", "unwrapkey", "wrapkey", "purge", "encrypt", "decrypt", "sign", "verify"] - secret_permissions = ["get"] + key_permissions = ["get", "unwrapkey", "wrapkey"] } resource "azurerm_key_vault_access_policy" "client" { @@ -229,8 +228,7 @@ resource "azurerm_key_vault_access_policy" "client" { tenant_id = data.azurerm_client_config.current.tenant_id object_id = data.azurerm_client_config.current.object_id - key_permissions = ["get", "create", "delete", "list", "restore", "recover", "unwrapkey", "wrapkey", "purge", "encrypt", "decrypt", "sign", "verify"] - secret_permissions = ["get"] + key_permissions = ["get", "list", "create", "recover"] } resource "azurerm_key_vault_key" "first" { diff --git a/website/docs/r/kusto_cluster_customer_managed_key.html.markdown b/website/docs/r/kusto_cluster_customer_managed_key.html.markdown index 2381e0e3fd0d..03cc54f3aa9c 100644 --- a/website/docs/r/kusto_cluster_customer_managed_key.html.markdown +++ b/website/docs/r/kusto_cluster_customer_managed_key.html.markdown @@ -36,8 +36,7 @@ resource "azurerm_key_vault_access_policy" "cluster" { tenant_id = data.azurerm_client_config.current.tenant_id object_id = azurerm_kusto_cluster.example.identity.0.principal_id - key_permissions = ["get", "create", "list", "restore", "recover", "unwrapkey", "wrapkey", "purge", "encrypt", "decrypt", "sign", "verify"] - secret_permissions = ["get"] + key_permissions = ["get", "unwrapkey", "wrapkey"] } resource "azurerm_key_vault_access_policy" "client" { @@ -45,11 +44,9 @@ resource "azurerm_key_vault_access_policy" "client" { tenant_id = data.azurerm_client_config.current.tenant_id object_id = data.azurerm_client_config.current.object_id - key_permissions = ["get", "create", "delete", "list", "restore", "recover", "unwrapkey", "wrapkey", "purge", "encrypt", "decrypt", "sign", "verify"] - secret_permissions = ["get"] + key_permissions = ["get", "list", "create", "recover"] } - resource "azurerm_key_vault_key" "example" { name = "tfex-key" key_vault_id = azurerm_key_vault.example.id From 6798aef6b8333eca5a3c379118093dd8fdb20f38 Mon Sep 17 00:00:00 2001 From: Jochen Rauschenbusch Date: Fri, 17 Jul 2020 14:43:35 +0200 Subject: [PATCH 09/15] fix permissions --- .../kusto/tests/kusto_cluster_customer_managed_key_test.go | 2 +- website/docs/r/kusto_cluster_customer_managed_key.html.markdown | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go b/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go index 60c875de9e07..9e5b18d555e9 100644 --- a/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go +++ b/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go @@ -228,7 +228,7 @@ resource "azurerm_key_vault_access_policy" "client" { tenant_id = data.azurerm_client_config.current.tenant_id object_id = data.azurerm_client_config.current.object_id - key_permissions = ["get", "list", "create", "recover"] + key_permissions = ["get", "list", "create", "delete", "recover"] } resource "azurerm_key_vault_key" "first" { diff --git a/website/docs/r/kusto_cluster_customer_managed_key.html.markdown b/website/docs/r/kusto_cluster_customer_managed_key.html.markdown index 03cc54f3aa9c..816bf1522eaa 100644 --- a/website/docs/r/kusto_cluster_customer_managed_key.html.markdown +++ b/website/docs/r/kusto_cluster_customer_managed_key.html.markdown @@ -44,7 +44,7 @@ resource "azurerm_key_vault_access_policy" "client" { tenant_id = data.azurerm_client_config.current.tenant_id object_id = data.azurerm_client_config.current.object_id - key_permissions = ["get", "list", "create", "recover"] + key_permissions = ["get", "list", "create", "delete", "recover"] } resource "azurerm_key_vault_key" "example" { From 11072b472db6ea7aef6f97fe4c0d06fb6977c748 Mon Sep 17 00:00:00 2001 From: Jochen Rauschenbusch Date: Fri, 17 Jul 2020 15:09:36 +0200 Subject: [PATCH 10/15] fix import error --- .../kusto/kusto_cluster_customer_managed_key_resource.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azurerm/internal/services/kusto/kusto_cluster_customer_managed_key_resource.go b/azurerm/internal/services/kusto/kusto_cluster_customer_managed_key_resource.go index ab09b7238c5b..20c83dfe2dbb 100644 --- a/azurerm/internal/services/kusto/kusto_cluster_customer_managed_key_resource.go +++ b/azurerm/internal/services/kusto/kusto_cluster_customer_managed_key_resource.go @@ -97,7 +97,7 @@ func resourceArmKustoClusterCustomerManagedKeyCreateUpdate(d *schema.ResourceDat // whilst this looks superflurious given encryption is enabled by default, due to the way // the Azure API works this technically can be nil if cluster.ClusterProperties.KeyVaultProperties != nil { - return tf.ImportAsExistsError("azurerm_storage_account_customer_managed_key", resourceID) + return tf.ImportAsExistsError("azurerm_kusto_cluster_customer_managed_key", resourceID) } } From 18e06d4b07efbcf00874b50f000db7d3856b031d Mon Sep 17 00:00:00 2001 From: Jochen Rauschenbusch Date: Fri, 17 Jul 2020 15:09:47 +0200 Subject: [PATCH 11/15] fix acc tests --- .../kusto/tests/kusto_cluster_customer_managed_key_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go b/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go index 9e5b18d555e9..e89d3f7cdca0 100644 --- a/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go +++ b/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go @@ -31,7 +31,7 @@ func TestAccAzureRMKustoClusterCustomerManagedKey_basic(t *testing.T) { // Delete the encryption settings resource and verify it is gone Config: testAccAzureRMKustoClusterCustomerManagedKey_template(data), Check: resource.ComposeTestCheckFunc( - // Then ensure the encryption settings on the storage account + // Then ensure the encryption settings on the Kusto cluster // have been reverted to their default state testCheckAzureRMKustoClusterExistsWithDefaultSettings("azurerm_kusto_cluster.test"), ), @@ -125,8 +125,8 @@ func testCheckAzureRMKustoClusterCustomerManagedKeyExists(resourceName string) r return fmt.Errorf("Not found: %s", resourceName) } - if kustoClusterId := rs.Primary.Attributes["storage_account_id"]; kustoClusterId == "" { - return fmt.Errorf("Unable to read kustoClusterId: %s", resourceName) + if kustoClusterId := rs.Primary.Attributes["cluster_id"]; kustoClusterId == "" { + return fmt.Errorf("Unable to read Kusto cluster id: %s", resourceName) } return nil From 81af7c10d1a1826b210ffd2692fad231a1e65e88 Mon Sep 17 00:00:00 2001 From: Jochen Rauschenbusch Date: Fri, 17 Jul 2020 15:57:58 +0200 Subject: [PATCH 12/15] fix acc tests --- ...kusto_cluster_customer_managed_key_test.go | 44 ++++++++++++------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go b/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go index e89d3f7cdca0..684217759187 100644 --- a/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go +++ b/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go @@ -2,11 +2,12 @@ package tests import ( "fmt" - "net/http" "testing" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/kusto/parse" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" @@ -33,7 +34,7 @@ func TestAccAzureRMKustoClusterCustomerManagedKey_basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( // Then ensure the encryption settings on the Kusto cluster // have been reverted to their default state - testCheckAzureRMKustoClusterExistsWithDefaultSettings("azurerm_kusto_cluster.test"), + testCheckAzureRMKustoClusterExistsWithCustomEncryptionKeyUsed("azurerm_kusto_cluster.test"), ), }, }, @@ -85,32 +86,45 @@ func TestAccAzureRMKustoClusterCustomerManagedKey_updateKey(t *testing.T) { }) } -func testCheckAzureRMKustoClusterExistsWithDefaultSettings(resourceName string) resource.TestCheckFunc { +func testCheckAzureRMKustoClusterExistsWithCustomEncryptionKeyUsed(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { + client := acceptance.AzureProvider.Meta().(*clients.Client).Kusto.ClustersClient + ctx := acceptance.AzureProvider.Meta().(*clients.Client).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) } - kustoCluster := rs.Primary.Attributes["name"] - resourceGroup := rs.Primary.Attributes["resource_group_name"] - - // Ensure resource group exists in API - ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext - conn := acceptance.AzureProvider.Meta().(*clients.Client).Kusto.ClustersClient - - resp, err := conn.Get(ctx, resourceGroup, kustoCluster) + id, err := parse.KustoClusterID(rs.Primary.ID) if err != nil { - return fmt.Errorf("Bad: Get on Kusto ClustersClient: %+v", err) + return err } - if resp.StatusCode == http.StatusNotFound { - return fmt.Errorf("Bad: Kusto Cluster %q (resource group: %q) does not exist", kustoCluster, resourceGroup) + resp, err := client.Get(ctx, id.ResourceGroup, id.Name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Kusto Cluster %q (resource group: %q) does not exist", id.Name, id.ResourceGroup) + } + + return fmt.Errorf("Bad: Get on kustoClustersClient: %+v", err) } if props := resp.ClusterProperties; props != nil { - return fmt.Errorf("Kusto Cluster encryption properties not found: %s", resourceName) + if encryption := props.KeyVaultProperties; encryption != nil { + if vaultURI := encryption.KeyVaultURI; vaultURI == nil { + return fmt.Errorf("Kusto Cluster KeyVault URI is not set") + } + if keyName := encryption.KeyName; keyName == nil { + return fmt.Errorf("Kusto Cluster KeyVault key name is not set") + } + if keyVersion := encryption.KeyVersion; keyVersion == nil { + return fmt.Errorf("Kusto Cluster KeyVault key version is not set") + } + } else { + return fmt.Errorf("Kusto Cluster encryption properties not found: %s", resourceName) + } } return nil From aec4d41d46afdbacd54bc27677c6d4c8dd56092f Mon Sep 17 00:00:00 2001 From: Jochen Rauschenbusch Date: Fri, 17 Jul 2020 16:47:25 +0200 Subject: [PATCH 13/15] fix acc test --- .../kusto_cluster_customer_managed_key_test.go | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go b/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go index 684217759187..eb1524f303a3 100644 --- a/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go +++ b/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go @@ -86,7 +86,7 @@ func TestAccAzureRMKustoClusterCustomerManagedKey_updateKey(t *testing.T) { }) } -func testCheckAzureRMKustoClusterExistsWithCustomEncryptionKeyUsed(resourceName string) resource.TestCheckFunc { +func testCheckAzureRMKustoClusterExistsWithDefaultValues(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { client := acceptance.AzureProvider.Meta().(*clients.Client).Kusto.ClustersClient ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext @@ -113,17 +113,7 @@ func testCheckAzureRMKustoClusterExistsWithCustomEncryptionKeyUsed(resourceName if props := resp.ClusterProperties; props != nil { if encryption := props.KeyVaultProperties; encryption != nil { - if vaultURI := encryption.KeyVaultURI; vaultURI == nil { - return fmt.Errorf("Kusto Cluster KeyVault URI is not set") - } - if keyName := encryption.KeyName; keyName == nil { - return fmt.Errorf("Kusto Cluster KeyVault key name is not set") - } - if keyVersion := encryption.KeyVersion; keyVersion == nil { - return fmt.Errorf("Kusto Cluster KeyVault key version is not set") - } - } else { - return fmt.Errorf("Kusto Cluster encryption properties not found: %s", resourceName) + return fmt.Errorf("Kusto Cluster encryption properties still found: %s", resourceName) } } From 6ec6d3cfcbd62887c0b8081bb88d519b4a33c6f0 Mon Sep 17 00:00:00 2001 From: Jochen Rauschenbusch Date: Fri, 17 Jul 2020 16:49:48 +0200 Subject: [PATCH 14/15] refactor function name --- .../kusto/tests/kusto_cluster_customer_managed_key_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go b/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go index eb1524f303a3..141e54a2bf6e 100644 --- a/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go +++ b/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go @@ -34,7 +34,7 @@ func TestAccAzureRMKustoClusterCustomerManagedKey_basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( // Then ensure the encryption settings on the Kusto cluster // have been reverted to their default state - testCheckAzureRMKustoClusterExistsWithCustomEncryptionKeyUsed("azurerm_kusto_cluster.test"), + testCheckAzureRMKustoClusterExistsWithoutCustomerManagedKey("azurerm_kusto_cluster.test"), ), }, }, @@ -86,7 +86,7 @@ func TestAccAzureRMKustoClusterCustomerManagedKey_updateKey(t *testing.T) { }) } -func testCheckAzureRMKustoClusterExistsWithDefaultValues(resourceName string) resource.TestCheckFunc { +func testCheckAzureRMKustoClusterExistsWithoutCustomerManagedKey(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { client := acceptance.AzureProvider.Meta().(*clients.Client).Kusto.ClustersClient ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext From bf622907b5ca275f6d370e5ba1b11c1eb0dda616 Mon Sep 17 00:00:00 2001 From: Jochen Rauschenbusch Date: Fri, 17 Jul 2020 17:03:26 +0200 Subject: [PATCH 15/15] refactor acc tests --- ...kusto_cluster_customer_managed_key_test.go | 48 +++++++++++++++---- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go b/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go index 141e54a2bf6e..e78cd21a8228 100644 --- a/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go +++ b/azurerm/internal/services/kusto/tests/kusto_cluster_customer_managed_key_test.go @@ -24,7 +24,10 @@ func TestAccAzureRMKustoClusterCustomerManagedKey_basic(t *testing.T) { { Config: testAccAzureRMKustoClusterCustomerManagedKey_basic(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMKustoClusterCustomerManagedKeyExists(data.ResourceName), + testCheckAzureRMKustoClusterWithCustomerManagedKeyExists(data.ResourceName), + resource.TestCheckResourceAttrSet(data.ResourceName, "key_vault_id"), + resource.TestCheckResourceAttrSet(data.ResourceName, "key_name"), + resource.TestCheckResourceAttrSet(data.ResourceName, "key_version"), ), }, data.ImportStep(), @@ -52,7 +55,10 @@ func TestAccAzureRMKustoClusterCustomerManagedKey_requiresImport(t *testing.T) { { Config: testAccAzureRMKustoClusterCustomerManagedKey_basic(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMKustoClusterCustomerManagedKeyExists(data.ResourceName), + testCheckAzureRMKustoClusterWithCustomerManagedKeyExists(data.ResourceName), + resource.TestCheckResourceAttrSet(data.ResourceName, "key_vault_id"), + resource.TestCheckResourceAttrSet(data.ResourceName, "key_name"), + resource.TestCheckResourceAttrSet(data.ResourceName, "key_version"), ), }, data.RequiresImportErrorStep(testAccAzureRMKustoClusterCustomerManagedKey_requiresImport), @@ -71,14 +77,17 @@ func TestAccAzureRMKustoClusterCustomerManagedKey_updateKey(t *testing.T) { { Config: testAccAzureRMKustoClusterCustomerManagedKey_basic(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMKustoClusterCustomerManagedKeyExists(data.ResourceName), + testCheckAzureRMKustoClusterWithCustomerManagedKeyExists(data.ResourceName), + resource.TestCheckResourceAttrSet(data.ResourceName, "key_vault_id"), + resource.TestCheckResourceAttrSet(data.ResourceName, "key_name"), + resource.TestCheckResourceAttrSet(data.ResourceName, "key_version"), ), }, data.ImportStep(), { Config: testAccAzureRMKustoClusterCustomerManagedKey_updated(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMKustoClusterCustomerManagedKeyExists(data.ResourceName), + testCheckAzureRMKustoClusterWithCustomerManagedKeyExists(data.ResourceName), ), }, data.ImportStep(), @@ -86,7 +95,7 @@ func TestAccAzureRMKustoClusterCustomerManagedKey_updateKey(t *testing.T) { }) } -func testCheckAzureRMKustoClusterExistsWithoutCustomerManagedKey(resourceName string) resource.TestCheckFunc { +func testCheckAzureRMKustoClusterWithCustomerManagedKeyExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { client := acceptance.AzureProvider.Meta().(*clients.Client).Kusto.ClustersClient ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext @@ -112,8 +121,8 @@ func testCheckAzureRMKustoClusterExistsWithoutCustomerManagedKey(resourceName st } if props := resp.ClusterProperties; props != nil { - if encryption := props.KeyVaultProperties; encryption != nil { - return fmt.Errorf("Kusto Cluster encryption properties still found: %s", resourceName) + if encryption := props.KeyVaultProperties; encryption == nil { + return fmt.Errorf("Kusto Cluster encryption properties not found: %s", resourceName) } } @@ -121,16 +130,35 @@ func testCheckAzureRMKustoClusterExistsWithoutCustomerManagedKey(resourceName st } } -func testCheckAzureRMKustoClusterCustomerManagedKeyExists(resourceName string) resource.TestCheckFunc { +func testCheckAzureRMKustoClusterExistsWithoutCustomerManagedKey(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { + client := acceptance.AzureProvider.Meta().(*clients.Client).Kusto.ClustersClient + ctx := acceptance.AzureProvider.Meta().(*clients.Client).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) } - if kustoClusterId := rs.Primary.Attributes["cluster_id"]; kustoClusterId == "" { - return fmt.Errorf("Unable to read Kusto cluster id: %s", resourceName) + id, err := parse.KustoClusterID(rs.Primary.ID) + if err != nil { + return err + } + + resp, err := client.Get(ctx, id.ResourceGroup, id.Name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Kusto Cluster %q (resource group: %q) does not exist", id.Name, id.ResourceGroup) + } + + return fmt.Errorf("Bad: Get on kustoClustersClient: %+v", err) + } + + if props := resp.ClusterProperties; props != nil { + if encryption := props.KeyVaultProperties; encryption != nil { + return fmt.Errorf("Kusto Cluster encryption properties still found: %s", resourceName) + } } return nil