diff --git a/CHANGELOG.md b/CHANGELOG.md index 67e0fbc84e8fc..96bfdd6d2104a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,12 @@ ## 2.16.0 (Unreleased) +DEPENDENCIES + +* updating `github.com/Azure/go-autorest/azure/cli` to `v0.3.1` [GH-7433] + ENHANCEMENTS +* authentication: Azure CLI - support for access tokens in custom directories [GH-7433] * `azurerm_app_service_environment` - support a value of `Web, Publishing` for the `internal_load_balancing_mode` property [GH-7346] * `azurerm_kusto_cluster` - support for the `identity` block [GH-7367] * `azurerm_kusto_cluster` - support for `virtual_network_configuration` block [GH-7369] diff --git a/azurerm/internal/services/kusto/kusto_cluster_resource.go b/azurerm/internal/services/kusto/kusto_cluster_resource.go index beeaac70010ec..22174aa8d21bc 100644 --- a/azurerm/internal/services/kusto/kusto_cluster_resource.go +++ b/azurerm/internal/services/kusto/kusto_cluster_resource.go @@ -110,6 +110,31 @@ func resourceArmKustoCluster() *schema.Resource { Optional: true, }, + "key_vault": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: azure.ValidateKeyVaultChildName, + }, + "key_version": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + "key_vault_uri": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.IsURLWithHTTPS, + }, + }, + }, + }, + "virtual_network_configuration": { Type: schema.TypeList, Optional: true, @@ -232,6 +257,25 @@ func resourceArmKustoClusterCreateUpdate(d *schema.ResourceData, meta interface{ d.SetId(*resp.ID) + if v, ok := d.GetOk("key_vault"); ok { + keyVaultProperties := expandKustoClusterKeyVault(v.([]interface{})) + + clusterUpdate := kusto.ClusterUpdate{ + ClusterProperties: &kusto.ClusterProperties{ + KeyVaultProperties: keyVaultProperties, + }, + } + + future, err := client.Update(ctx, resourceGroup, name, clusterUpdate) + if err != nil { + return fmt.Errorf("Error creating or updating Kusto Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for completion of Kusto Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + } + return resourceArmKustoClusterRead(d, meta) } @@ -279,6 +323,7 @@ func resourceArmKustoClusterRead(d *schema.ResourceData, meta interface{}) error d.Set("enable_streaming_ingest", clusterProperties.EnableStreamingIngest) d.Set("enable_purge", clusterProperties.EnablePurge) d.Set("virtual_network_configuration", flatteKustoClusterVNET(clusterProperties.VirtualNetworkConfiguration)) + d.Set("key_vault", flatteKustoClusterKeyVault(clusterProperties.KeyVaultProperties)) d.Set("uri", clusterProperties.URI) d.Set("data_ingestion_uri", clusterProperties.DataIngestionURI) } @@ -366,6 +411,23 @@ func expandKustoClusterVNET(input []interface{}) *kusto.VirtualNetworkConfigurat } } +func expandKustoClusterKeyVault(input []interface{}) *kusto.KeyVaultProperties { + if len(input) == 0 && input[0] != nil { + return nil + } + + keyVault := input[0].(map[string]interface{}) + keyName := keyVault["key_name"].(string) + keyVersion := keyVault["key_version"].(string) + uri := keyVault["key_vault_uri"].(string) + + return &kusto.KeyVaultProperties{ + KeyName: &keyName, + KeyVersion: &keyVersion, + KeyVaultURI: &uri, + } +} + func flattenKustoClusterSku(sku *kusto.AzureSku) []interface{} { if sku == nil { return []interface{}{} @@ -410,3 +472,32 @@ func flatteKustoClusterVNET(vnet *kusto.VirtualNetworkConfiguration) []interface return []interface{}{output} } + +func flatteKustoClusterKeyVault(keyVault *kusto.KeyVaultProperties) []interface{} { + if keyVault == nil { + return []interface{}{} + } + + keyName := "" + if keyVault.KeyName != nil { + keyName = *keyVault.KeyName + } + + keyVersion := "" + if keyVault.KeyVersion != nil { + keyVersion = *keyVault.KeyVersion + } + + keyVaultURI := "" + if keyVault.KeyVaultURI != nil { + keyVaultURI = *keyVault.KeyVaultURI + } + + output := map[string]interface{}{ + "key_name": keyName, + "key_version": keyVersion, + "key_vault_uri": keyVaultURI, + } + + return []interface{}{output} +} diff --git a/azurerm/internal/services/kusto/tests/kusto_cluster_resource_test.go b/azurerm/internal/services/kusto/tests/kusto_cluster_resource_test.go index d00e29eb28113..f1714895bf73b 100644 --- a/azurerm/internal/services/kusto/tests/kusto_cluster_resource_test.go +++ b/azurerm/internal/services/kusto/tests/kusto_cluster_resource_test.go @@ -150,6 +150,29 @@ func TestAccAzureRMKustoCluster_zones(t *testing.T) { }) } +func TestAccAzureRMKustoCluster_keyVault(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_kusto_cluster", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMKustoClusterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMKustoCluster_keyVault(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKustoClusterExists(data.ResourceName), + resource.TestCheckResourceAttr(data.ResourceName, "key_vault.#", "1"), + resource.TestCheckResourceAttr(data.ResourceName, "key_vault.0.key_name", ""), + resource.TestCheckResourceAttr(data.ResourceName, "key_vault.0.key_version", ""), + resource.TestCheckResourceAttrSet(data.ResourceName, "key_vault.0.key_vault_uri"), + ), + }, + data.ImportStep(), + }, + }) +} + func TestAccAzureRMKustoCluster_identitySystemAssigned(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_kusto_cluster", "test") @@ -381,6 +404,50 @@ resource "azurerm_kusto_cluster" "test" { `, data.RandomInteger, data.Locations.Primary, data.RandomString) } +func testAccAzureRMKustoCluster_keyVault(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +data "azurerm_client_config" "current" {} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_key_vault" "test" { + name = "acctestkc%s-vault" + 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" +} + +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" + } + + key_vault { + key_name = "acctestkc%s" + key_version = "1" + key_vault_uri = azurerm_key_vault.test.vault_uri + } +} +`, data.RandomInteger, data.Locations.Primary, data.RandomString, data.RandomString, data.RandomString) +} + func testCheckAzureRMKustoClusterDestroy(s *terraform.State) error { client := acceptance.AzureProvider.Meta().(*clients.Client).Kusto.ClustersClient ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext diff --git a/website/docs/r/kusto_cluster.html.markdown b/website/docs/r/kusto_cluster.html.markdown index 2ac81770333c4..edc2b1526c90a 100644 --- a/website/docs/r/kusto_cluster.html.markdown +++ b/website/docs/r/kusto_cluster.html.markdown @@ -56,6 +56,8 @@ The following arguments are supported: * `virtual_network_configuration`- (Optional) A `virtual_network_configuration` block as defined below. +* `key_vault` - (Optional) A `key_vault` block as defined below. + * `tags` - (Optional) A mapping of tags to assign to the resource. * `zones` - (Optional) A list of Availability Zones in which the cluster instances should be created in. Changing this forces a new resource to be created. @@ -92,6 +94,16 @@ An `identity` block supports the following: ~> **NOTE:** When `type` is set to `SystemAssigned`, the Principal ID can be retrieved after the cluster has been created. More details are available below. See [documentation](https://docs.microsoft.com/en-us/azure/active-directory/managed-service-identity/overview) for additional information. +--- + +A `key_vault` block supports the following: + +* `key_name` - (Required) The name of the key vault key. + +* `key_version` - (Required) The version of the key vault key. + +* `uri` - (Required) The Uri of the key vault. + ## Attributes Reference The following attributes are exported: