diff --git a/azurerm/internal/services/kusto/kusto_cluster_resource.go b/azurerm/internal/services/kusto/kusto_cluster_resource.go index beeaac70010ec..4117a183e0462 100644 --- a/azurerm/internal/services/kusto/kusto_cluster_resource.go +++ b/azurerm/internal/services/kusto/kusto_cluster_resource.go @@ -95,6 +95,31 @@ func resourceArmKustoCluster() *schema.Resource { }, }, + "optimized_auto_scale": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "minimum_instances": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(0, 1000), + }, + "maximum_instances": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(0, 1000), + }, + }, + }, + }, + "enable_disk_encryption": { Type: schema.TypeBool, Optional: true, @@ -184,7 +209,10 @@ func resourceArmKustoClusterCreateUpdate(d *schema.ResourceData, meta interface{ zones := azure.ExpandZones(d.Get("zones").([]interface{})) + optimizedAutoScale := expandOptimizedAutoScale(d.Get("optimized_auto_scale").([]interface{})) + clusterProperties := kusto.ClusterProperties{ + OptimizedAutoscale: optimizedAutoScale, EnableDiskEncryption: utils.Bool(d.Get("enable_disk_encryption").(bool)), EnableStreamingIngest: utils.Bool(d.Get("enable_streaming_ingest").(bool)), EnablePurge: utils.Bool(d.Get("enable_purge").(bool)), @@ -273,6 +301,9 @@ func resourceArmKustoClusterRead(d *schema.ResourceData, meta interface{}) error if err := d.Set("zones", azure.FlattenZones(clusterResponse.Zones)); err != nil { return fmt.Errorf("Error setting `zones`: %+v", err) } + if err := d.Set("optimized_auto_scale", flattenOptimizedAutoScale(clusterResponse.OptimizedAutoscale)); err != nil { + return fmt.Errorf("Error setting `optimized_auto_scale`: %+v", err) + } if clusterProperties := clusterResponse.ClusterProperties; clusterProperties != nil { d.Set("enable_disk_encryption", clusterProperties.EnableDiskEncryption) @@ -322,6 +353,56 @@ func validateAzureRMKustoClusterName(v interface{}, k string) (warnings []string return warnings, errors } +func expandOptimizedAutoScale(input []interface{}) *kusto.OptimizedAutoscale { + if len(input) == 0 { + return nil + } + + config := input[0].(map[string]interface{}) + enabled := config["enabled"].(bool) + minimumInstances := int32(config["minimum_instances"].(int)) + maximumInstances := int32(config["maximum_instances"].(int)) + + var version int32 = 1 + optimizedAutoScale := &kusto.OptimizedAutoscale{ + Version: &version, + IsEnabled: &enabled, + Minimum: &minimumInstances, + Maximum: &maximumInstances, + } + + return optimizedAutoScale +} + +func flattenOptimizedAutoScale(optimizedAutoScale *kusto.OptimizedAutoscale) []interface{} { + if optimizedAutoScale == nil { + return []interface{}{} + } + + enabled := false + if optimizedAutoScale.IsEnabled != nil { + enabled = *optimizedAutoScale.IsEnabled + } + + maxInstances := 0 + if optimizedAutoScale.Maximum != nil { + maxInstances = int(*optimizedAutoScale.Maximum) + } + + minInstances := 0 + if optimizedAutoScale.Minimum != nil { + minInstances = int(*optimizedAutoScale.Minimum) + } + + return []interface{}{ + map[string]interface{}{ + "enabled": enabled, + "maximum_instances": maxInstances, + "minimum_instances": minInstances, + }, + } +} + func expandKustoClusterSku(d *schema.ResourceData) (*kusto.AzureSku, error) { skuList := d.Get("sku").([]interface{}) 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..6fec36e3f2f98 100644 --- a/azurerm/internal/services/kusto/tests/kusto_cluster_resource_test.go +++ b/azurerm/internal/services/kusto/tests/kusto_cluster_resource_test.go @@ -195,6 +195,50 @@ func TestAccAzureRMKustoCluster_vnet(t *testing.T) { }) } +func TestAccAzureRMKustoCluster_optimizedAutoScale(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_optimizedAutoScale(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKustoClusterExists(data.ResourceName), + resource.TestCheckResourceAttr(data.ResourceName, "optimized_auto_scale.#", "1"), + resource.TestCheckResourceAttr(data.ResourceName, "optimized_auto_scale.0.minimum_instances", "2"), + resource.TestCheckResourceAttr(data.ResourceName, "optimized_auto_scale.0.maximum_instances", "3"), + resource.TestCheckResourceAttr(data.ResourceName, "optimized_auto_scale.0.enabled", "true"), + ), + }, + data.ImportStep(), + { + Config: testAccAzureRMKustoCluster_optimizedAutoScaleUpdate(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKustoClusterExists(data.ResourceName), + resource.TestCheckResourceAttr(data.ResourceName, "optimized_auto_scale.#", "1"), + resource.TestCheckResourceAttr(data.ResourceName, "optimized_auto_scale.0.minimum_instances", "3"), + resource.TestCheckResourceAttr(data.ResourceName, "optimized_auto_scale.0.maximum_instances", "4"), + resource.TestCheckResourceAttr(data.ResourceName, "optimized_auto_scale.0.enabled", "true"), + ), + }, + { + Config: testAccAzureRMKustoCluster_optimizedAutoScaleDisable(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKustoClusterExists(data.ResourceName), + resource.TestCheckResourceAttr(data.ResourceName, "optimized_auto_scale.#", "1"), + resource.TestCheckResourceAttr(data.ResourceName, "optimized_auto_scale.0.minimum_instances", "3"), + resource.TestCheckResourceAttr(data.ResourceName, "optimized_auto_scale.0.maximum_instances", "4"), + resource.TestCheckResourceAttr(data.ResourceName, "optimized_auto_scale.0.enabled", "false"), + ), + }, + data.ImportStep(), + }, + }) +} + func testAccAzureRMKustoCluster_basic(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { @@ -381,6 +425,94 @@ resource "azurerm_kusto_cluster" "test" { `, data.RandomInteger, data.Locations.Primary, data.RandomString) } +func testAccAzureRMKustoCluster_optimizedAutoScale(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_kusto_cluster" "test" { + name = "acctestkc%s" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + + sku { + name = "Standard_D11_v2" + capacity = 2 + } + + optimized_auto_scale { + minimum_instances = 2 + maximum_instances = 3 + } +} +`, data.RandomInteger, data.Locations.Primary, data.RandomString) +} + +func testAccAzureRMKustoCluster_optimizedAutoScaleUpdate(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_kusto_cluster" "test" { + name = "acctestkc%s" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + + sku { + name = "Standard_D11_v2" + capacity = 2 + } + + optimized_auto_scale { + minimum_instances = 3 + maximum_instances = 4 + } +} +`, data.RandomInteger, data.Locations.Primary, data.RandomString) +} + +func testAccAzureRMKustoCluster_optimizedAutoScaleDisable(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_kusto_cluster" "test" { + name = "acctestkc%s" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + + sku { + name = "Standard_D11_v2" + capacity = 2 + } + + optimized_auto_scale { + minimum_instances = 3 + maximum_instances = 4 + enabled = false + } +} +`, data.RandomInteger, data.Locations.Primary, 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..d78e2f50c9229 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. +* `optimized_auto_scale` - (Optional) An `optimized_auto_scale` 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 `optimized_auto_scale` block supports the following: + +* `enabled` - (Optional) A boolean value that indicate if the optimized autoscale feature is enabled or not. Default is `true`. + +* `minimum_instances` - (Required) The minimum number of allowed instances. Must between `0` and `1000`. + +* `maximum_instances` - (Required) The maximum number of allowed instances. Must between `0` and `1000`. + ## Attributes Reference The following attributes are exported: