From 51e421f1c3560e9262b758fc362b29f94ab827fd Mon Sep 17 00:00:00 2001 From: mikatong Date: Tue, 25 Nov 2025 16:11:10 +0800 Subject: [PATCH 1/2] support target tracking policy --- .../as/resource_tc_as_scaling_policy.go | 113 ++++++++++++------ .../as/resource_tc_as_scaling_policy.md | 53 ++++++++ .../as/resource_tc_as_scaling_policy_test.go | 65 +++++++++- .../docs/r/as_scaling_policy.html.markdown | 69 +++++++++-- 4 files changed, 255 insertions(+), 45 deletions(-) diff --git a/tencentcloud/services/as/resource_tc_as_scaling_policy.go b/tencentcloud/services/as/resource_tc_as_scaling_policy.go index 38f927bc04..63f72a18f2 100644 --- a/tencentcloud/services/as/resource_tc_as_scaling_policy.go +++ b/tencentcloud/services/as/resource_tc_as_scaling_policy.go @@ -35,56 +35,56 @@ func ResourceTencentCloudAsScalingPolicy() *schema.Resource { }, "adjustment_type": { Type: schema.TypeString, - Required: true, + Optional: true, ValidateFunc: tccommon.ValidateAllowedStringValue(SCALING_GROUP_ADJUSTMENT_TYPE), Description: "Specifies whether the adjustment is an absolute number or a percentage of the current capacity. Valid values: `CHANGE_IN_CAPACITY`, `EXACT_CAPACITY` and `PERCENT_CHANGE_IN_CAPACITY`.", }, "adjustment_value": { Type: schema.TypeInt, - Required: true, + Optional: true, Description: "Define the number of instances by which to scale.For `CHANGE_IN_CAPACITY` type or PERCENT_CHANGE_IN_CAPACITY, a positive increment adds to the current capacity and a negative value removes from the current capacity. For `EXACT_CAPACITY` type, it defines an absolute number of the existing Auto Scaling group size.", }, "comparison_operator": { Type: schema.TypeString, - Required: true, + Optional: true, ValidateFunc: tccommon.ValidateAllowedStringValue(SCALING_GROUP_COMPARISON_OPERATOR), Description: "Comparison operator. Valid values: `GREATER_THAN`, `GREATER_THAN_OR_EQUAL_TO`, `LESS_THAN`, `LESS_THAN_OR_EQUAL_TO`, `EQUAL_TO` and `NOT_EQUAL_TO`.", }, "metric_name": { Type: schema.TypeString, - Required: true, + Optional: true, ValidateFunc: tccommon.ValidateAllowedStringValue(SCALING_GROUP_METRIC_NAME), Description: "Name of an indicator. Valid values: `CPU_UTILIZATION`, `MEM_UTILIZATION`, `LAN_TRAFFIC_OUT`, `LAN_TRAFFIC_IN`, `WAN_TRAFFIC_OUT` and `WAN_TRAFFIC_IN`.", }, "threshold": { Type: schema.TypeInt, - Required: true, + Optional: true, Description: "Alarm threshold.", }, "period": { Type: schema.TypeInt, - Required: true, + Optional: true, ValidateFunc: tccommon.ValidateAllowedIntValue([]int{60, 300}), Description: "Time period in second. Valid values: `60` and `300`.", }, "continuous_time": { Type: schema.TypeInt, - Required: true, + Optional: true, ValidateFunc: tccommon.ValidateIntegerInRange(1, 10), Description: "Retry times. Valid value ranges: (1~10).", }, "statistic": { Type: schema.TypeString, Optional: true, - Default: SCALING_GROUP_STATISTIC_AVERAGE, + Computed: true, ValidateFunc: tccommon.ValidateAllowedStringValue(SCALING_GROUP_STATISTIC), Description: "Statistic types. Valid values: `AVERAGE`, `MAXIMUM` and `MINIMUM`. Default is `AVERAGE`.", }, "cooldown": { Type: schema.TypeInt, Optional: true, - Default: 300, - Description: "Cooldwon time in second. Default is `30`0.", + Computed: true, + Description: "Cooldwon time in second. Default is `300`.", }, "notification_user_group_ids": { Type: schema.TypeList, @@ -113,6 +113,7 @@ func ResourceTencentCloudAsScalingPolicy() *schema.Resource { "estimated_instance_warmup": { Type: schema.TypeInt, Optional: true, + Computed: true, Description: "Instance warm-up time, in seconds, applicable only to target tracking strategies. Value range is 0-3600, with a default warm-up time of 300 seconds.", }, "disable_scale_in": { @@ -132,18 +133,40 @@ func resourceTencentCloudAsScalingPolicyCreate(d *schema.ResourceData, meta inte request := as.NewCreateScalingPolicyRequest() request.AutoScalingGroupId = helper.String(d.Get("scaling_group_id").(string)) request.ScalingPolicyName = helper.String(d.Get("policy_name").(string)) - request.AdjustmentType = helper.String(d.Get("adjustment_type").(string)) - adjustMentValue := int64(d.Get("adjustment_value").(int)) - request.AdjustmentValue = &adjustMentValue - request.MetricAlarm = &as.MetricAlarm{} - request.MetricAlarm.ComparisonOperator = helper.String(d.Get("comparison_operator").(string)) - request.MetricAlarm.MetricName = helper.String(d.Get("metric_name").(string)) - request.MetricAlarm.Threshold = helper.IntUint64(d.Get("threshold").(int)) - request.MetricAlarm.Period = helper.IntUint64(d.Get("period").(int)) - request.MetricAlarm.ContinuousTime = helper.IntUint64(d.Get("continuous_time").(int)) - + if v, ok := d.GetOk("adjustment_type"); ok { + request.AdjustmentType = helper.String(v.(string)) + } + if v, ok := d.GetOkExists("adjustment_value"); ok { + request.AdjustmentValue = helper.IntInt64(v.(int)) + } + metricAlarm := &as.MetricAlarm{} + var hasMetricAlarm bool + if v, ok := d.GetOk("comparison_operator"); ok { + metricAlarm.ComparisonOperator = helper.String(v.(string)) + hasMetricAlarm = true + } + if v, ok := d.GetOk("metric_name"); ok { + metricAlarm.MetricName = helper.String(v.(string)) + hasMetricAlarm = true + } + if v, ok := d.GetOkExists("threshold"); ok { + metricAlarm.Threshold = helper.IntUint64(v.(int)) + hasMetricAlarm = true + } + if v, ok := d.GetOkExists("period"); ok { + metricAlarm.Period = helper.IntUint64(v.(int)) + hasMetricAlarm = true + } + if v, ok := d.GetOkExists("continuous_time"); ok { + metricAlarm.ContinuousTime = helper.IntUint64(v.(int)) + hasMetricAlarm = true + } if v, ok := d.GetOk("statistic"); ok { - request.MetricAlarm.Statistic = helper.String(v.(string)) + metricAlarm.Statistic = helper.String(v.(string)) + hasMetricAlarm = true + } + if hasMetricAlarm { + request.MetricAlarm = metricAlarm } if v, ok := d.GetOk("cooldown"); ok { request.Cooldown = helper.IntUint64(v.(int)) @@ -286,21 +309,43 @@ func resourceTencentCloudAsScalingPolicyUpdate(d *schema.ResourceData, meta inte request.ScalingPolicyName = helper.String(d.Get("policy_name").(string)) } if d.HasChange("adjustment_type") { - request.AdjustmentType = helper.String(d.Get("adjustment_type").(string)) + if v, ok := d.GetOk("adjustment_type"); ok { + request.AdjustmentType = helper.String(v.(string)) + } } if d.HasChange("adjustment_value") { - adjustmentValue := int64(d.Get("adjustment_value").(int)) - request.AdjustmentValue = &adjustmentValue - } - request.MetricAlarm = &as.MetricAlarm{} - - //these two parameter must pass together - request.MetricAlarm.ComparisonOperator = helper.String(d.Get("comparison_operator").(string)) - request.MetricAlarm.Threshold = helper.IntUint64(d.Get("threshold").(int)) - request.MetricAlarm.MetricName = helper.String(d.Get("metric_name").(string)) - request.MetricAlarm.Period = helper.IntUint64(d.Get("period").(int)) - request.MetricAlarm.ContinuousTime = helper.IntUint64(d.Get("continuous_time").(int)) - request.MetricAlarm.Statistic = helper.String(d.Get("statistic").(string)) + if v, ok := d.GetOkExists("adjustment_value"); ok { + request.AdjustmentValue = helper.IntInt64(v.(int)) + } + } + + if d.HasChange("comparison_operator") || d.HasChange("threshold") || d.HasChange("metric_name") || d.HasChange("period") || d.HasChange("continuous_time") || d.HasChange("statistic") { + request.MetricAlarm = &as.MetricAlarm{} + + if v, ok := d.GetOk("comparison_operator"); ok { + request.MetricAlarm.ComparisonOperator = helper.String(v.(string)) + } + + if v, ok := d.GetOkExists("threshold"); ok { + request.MetricAlarm.Threshold = helper.IntUint64(v.(int)) + } + + if v, ok := d.GetOk("metric_name"); ok { + request.MetricAlarm.MetricName = helper.String(v.(string)) + } + + if v, ok := d.GetOkExists("period"); ok { + request.MetricAlarm.Period = helper.IntUint64(v.(int)) + } + + if v, ok := d.GetOkExists("continuous_time"); ok { + request.MetricAlarm.ContinuousTime = helper.IntUint64(v.(int)) + } + + if v, ok := d.GetOk("statistic"); ok { + request.MetricAlarm.Statistic = helper.String(v.(string)) + } + } if d.HasChange("cooldown") { request.Cooldown = helper.IntUint64(d.Get("cooldown").(int)) diff --git a/tencentcloud/services/as/resource_tc_as_scaling_policy.md b/tencentcloud/services/as/resource_tc_as_scaling_policy.md index b3bb28423a..626286abd7 100644 --- a/tencentcloud/services/as/resource_tc_as_scaling_policy.md +++ b/tencentcloud/services/as/resource_tc_as_scaling_policy.md @@ -2,6 +2,8 @@ Provides a resource for an AS (Auto scaling) policy. Example Usage +Create Simple policy + ```hcl data "tencentcloud_availability_zones_by_product" "zones" { product = "as" @@ -55,4 +57,55 @@ resource "tencentcloud_as_scaling_policy" "example" { statistic = "AVERAGE" cooldown = 360 } +``` + +Create a Target tracking policy + +```hcl +data "tencentcloud_availability_zones_by_product" "zones" { + product = "as" +} + +data "tencentcloud_images" "image" { + image_type = ["PUBLIC_IMAGE"] + os_name = "TencentOS Server 3.2 (Final)" +} + +resource "tencentcloud_vpc" "vpc" { + name = "vpc-example" + cidr_block = "10.0.0.0/16" +} + +resource "tencentcloud_subnet" "subnet" { + vpc_id = tencentcloud_vpc.vpc.id + name = "subnet-example" + cidr_block = "10.0.0.0/16" + availability_zone = data.tencentcloud_availability_zones_by_product.zones.zones.0.name +} + +resource "tencentcloud_as_scaling_config" "example" { + configuration_name = "tf-example" + image_id = data.tencentcloud_images.image.images.0.image_id + instance_types = ["SA1.SMALL1", "SA2.SMALL1", "SA2.SMALL2", "SA2.SMALL4"] + instance_name_settings { + instance_name = "test-ins-name" + } +} + +resource "tencentcloud_as_scaling_group" "example" { + scaling_group_name = "tf-example" + configuration_id = tencentcloud_as_scaling_config.example.id + max_size = 1 + min_size = 0 + vpc_id = tencentcloud_vpc.vpc.id + subnet_ids = [tencentcloud_subnet.subnet.id] +} + +resource "tencentcloud_as_scaling_policy" "example" { + scaling_group_id = tencentcloud_as_scaling_group.scaling_group.id + policy_name = "tf-as-scaling-policy" + policy_type = "TARGET_TRACKING" + predefined_metric_type = "ASG_AVG_CPU_UTILIZATION" + target_value = 80 +} ``` \ No newline at end of file diff --git a/tencentcloud/services/as/resource_tc_as_scaling_policy_test.go b/tencentcloud/services/as/resource_tc_as_scaling_policy_test.go index 84d2364bbc..417053595a 100644 --- a/tencentcloud/services/as/resource_tc_as_scaling_policy_test.go +++ b/tencentcloud/services/as/resource_tc_as_scaling_policy_test.go @@ -13,7 +13,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" ) -func TestAccTencentCloudAsScalingPolicy(t *testing.T) { +func TestAccTencentCloudAsScalingPolicy_Basic(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ PreCheck: func() { tcacctest.AccPreCheck(t) }, @@ -58,6 +58,28 @@ func TestAccTencentCloudAsScalingPolicy(t *testing.T) { }) } +func TestAccTencentCloudAsScalingPolicy_TargetTracking(t *testing.T) { + t.Parallel() + resource.Test(t, resource.TestCase{ + PreCheck: func() { tcacctest.AccPreCheck(t) }, + Providers: tcacctest.AccProviders, + CheckDestroy: testAccCheckAsScalingPolicyDestroy, + Steps: []resource.TestStep{ + { + Config: TargetTrackingPolicy, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAsScalingPolicyExists("tencentcloud_as_scaling_policy.scaling_policy"), + resource.TestCheckResourceAttrSet("tencentcloud_as_scaling_policy.scaling_policy", "scaling_group_id"), + resource.TestCheckResourceAttr("tencentcloud_as_scaling_policy.scaling_policy", "policy_name", "tf-as-scaling-policy"), + resource.TestCheckResourceAttr("tencentcloud_as_scaling_policy.scaling_policy", "policy_type", "TARGET_TRACKING"), + resource.TestCheckResourceAttr("tencentcloud_as_scaling_policy.scaling_policy", "predefined_metric_type", "ASG_AVG_CPU_UTILIZATION"), + resource.TestCheckResourceAttr("tencentcloud_as_scaling_policy.scaling_policy", "target_value", "80"), + ), + }, + }, + }) +} + func testAccCheckAsScalingPolicyExists(n string) resource.TestCheckFunc { return func(s *terraform.State) error { logId := tccommon.GetLogId(tccommon.ContextNil) @@ -119,7 +141,7 @@ resource "tencentcloud_subnet" "subnet" { resource "tencentcloud_as_scaling_config" "launch_configuration" { configuration_name = "tf-as-configuration-policy" - image_id = "img-9qabwvbn" + image_id = "img-9qrfy1xt" instance_types = [data.tencentcloud_instance_types.default.instance_types.0.instance_type] } @@ -164,7 +186,7 @@ resource "tencentcloud_subnet" "subnet" { resource "tencentcloud_as_scaling_config" "launch_configuration" { configuration_name = "tf-as-configuration-policy" - image_id = "img-9qabwvbn" + image_id = "img-9qrfy1xt" instance_types = [data.tencentcloud_instance_types.default.instance_types.0.instance_type] } @@ -192,3 +214,40 @@ resource "tencentcloud_as_scaling_policy" "scaling_policy" { } ` } + +const TargetTrackingPolicy = tcacctest.DefaultAsVariable + ` +resource "tencentcloud_vpc" "vpc" { + name = "tf-as-vpc" + cidr_block = "10.2.0.0/16" +} + +resource "tencentcloud_subnet" "subnet" { + vpc_id = tencentcloud_vpc.vpc.id + name = "tf-as-subnet" + cidr_block = "10.2.11.0/24" + availability_zone = var.availability_zone +} + +resource "tencentcloud_as_scaling_config" "launch_configuration" { + configuration_name = "tf-as-configuration-policy" + image_id = "img-9qrfy1xt" + instance_types = [data.tencentcloud_instance_types.default.instance_types.0.instance_type] +} + +resource "tencentcloud_as_scaling_group" "scaling_group" { + scaling_group_name = "tf-as-scaling-group-policy" + configuration_id = tencentcloud_as_scaling_config.launch_configuration.id + max_size = 1 + min_size = 0 + vpc_id = tencentcloud_vpc.vpc.id + subnet_ids = [tencentcloud_subnet.subnet.id] +} + +resource "tencentcloud_as_scaling_policy" "scaling_policy" { + scaling_group_id = tencentcloud_as_scaling_group.scaling_group.id + policy_name = "tf-as-scaling-policy" + policy_type = "TARGET_TRACKING" + predefined_metric_type = "ASG_AVG_CPU_UTILIZATION" + target_value = 80 +} +` diff --git a/website/docs/r/as_scaling_policy.html.markdown b/website/docs/r/as_scaling_policy.html.markdown index 229b1ad02b..bd45997ba4 100644 --- a/website/docs/r/as_scaling_policy.html.markdown +++ b/website/docs/r/as_scaling_policy.html.markdown @@ -13,6 +13,8 @@ Provides a resource for an AS (Auto scaling) policy. ## Example Usage +### Create Simple policy + ```hcl data "tencentcloud_availability_zones_by_product" "zones" { product = "as" @@ -68,27 +70,78 @@ resource "tencentcloud_as_scaling_policy" "example" { } ``` +### Create a Target tracking policy + +```hcl +data "tencentcloud_availability_zones_by_product" "zones" { + product = "as" +} + +data "tencentcloud_images" "image" { + image_type = ["PUBLIC_IMAGE"] + os_name = "TencentOS Server 3.2 (Final)" +} + +resource "tencentcloud_vpc" "vpc" { + name = "vpc-example" + cidr_block = "10.0.0.0/16" +} + +resource "tencentcloud_subnet" "subnet" { + vpc_id = tencentcloud_vpc.vpc.id + name = "subnet-example" + cidr_block = "10.0.0.0/16" + availability_zone = data.tencentcloud_availability_zones_by_product.zones.zones.0.name +} + +resource "tencentcloud_as_scaling_config" "example" { + configuration_name = "tf-example" + image_id = data.tencentcloud_images.image.images.0.image_id + instance_types = ["SA1.SMALL1", "SA2.SMALL1", "SA2.SMALL2", "SA2.SMALL4"] + instance_name_settings { + instance_name = "test-ins-name" + } +} + +resource "tencentcloud_as_scaling_group" "example" { + scaling_group_name = "tf-example" + configuration_id = tencentcloud_as_scaling_config.example.id + max_size = 1 + min_size = 0 + vpc_id = tencentcloud_vpc.vpc.id + subnet_ids = [tencentcloud_subnet.subnet.id] +} + +resource "tencentcloud_as_scaling_policy" "example" { + scaling_group_id = tencentcloud_as_scaling_group.scaling_group.id + policy_name = "tf-as-scaling-policy" + policy_type = "TARGET_TRACKING" + predefined_metric_type = "ASG_AVG_CPU_UTILIZATION" + target_value = 80 +} +``` + ## Argument Reference The following arguments are supported: -* `adjustment_type` - (Required, String) Specifies whether the adjustment is an absolute number or a percentage of the current capacity. Valid values: `CHANGE_IN_CAPACITY`, `EXACT_CAPACITY` and `PERCENT_CHANGE_IN_CAPACITY`. -* `adjustment_value` - (Required, Int) Define the number of instances by which to scale.For `CHANGE_IN_CAPACITY` type or PERCENT_CHANGE_IN_CAPACITY, a positive increment adds to the current capacity and a negative value removes from the current capacity. For `EXACT_CAPACITY` type, it defines an absolute number of the existing Auto Scaling group size. -* `comparison_operator` - (Required, String) Comparison operator. Valid values: `GREATER_THAN`, `GREATER_THAN_OR_EQUAL_TO`, `LESS_THAN`, `LESS_THAN_OR_EQUAL_TO`, `EQUAL_TO` and `NOT_EQUAL_TO`. -* `continuous_time` - (Required, Int) Retry times. Valid value ranges: (1~10). -* `metric_name` - (Required, String) Name of an indicator. Valid values: `CPU_UTILIZATION`, `MEM_UTILIZATION`, `LAN_TRAFFIC_OUT`, `LAN_TRAFFIC_IN`, `WAN_TRAFFIC_OUT` and `WAN_TRAFFIC_IN`. -* `period` - (Required, Int) Time period in second. Valid values: `60` and `300`. * `policy_name` - (Required, String) Name of a policy used to define a reaction when an alarm is triggered. * `scaling_group_id` - (Required, String, ForceNew) ID of a scaling group. -* `threshold` - (Required, Int) Alarm threshold. -* `cooldown` - (Optional, Int) Cooldwon time in second. Default is `30`0. +* `adjustment_type` - (Optional, String) Specifies whether the adjustment is an absolute number or a percentage of the current capacity. Valid values: `CHANGE_IN_CAPACITY`, `EXACT_CAPACITY` and `PERCENT_CHANGE_IN_CAPACITY`. +* `adjustment_value` - (Optional, Int) Define the number of instances by which to scale.For `CHANGE_IN_CAPACITY` type or PERCENT_CHANGE_IN_CAPACITY, a positive increment adds to the current capacity and a negative value removes from the current capacity. For `EXACT_CAPACITY` type, it defines an absolute number of the existing Auto Scaling group size. +* `comparison_operator` - (Optional, String) Comparison operator. Valid values: `GREATER_THAN`, `GREATER_THAN_OR_EQUAL_TO`, `LESS_THAN`, `LESS_THAN_OR_EQUAL_TO`, `EQUAL_TO` and `NOT_EQUAL_TO`. +* `continuous_time` - (Optional, Int) Retry times. Valid value ranges: (1~10). +* `cooldown` - (Optional, Int) Cooldwon time in second. Default is `300`. * `disable_scale_in` - (Optional, Bool) Whether to disable scaling down applies only to the target tracking strategy; the default value is false. Value range: true: The target tracking strategy only triggers scaling up; false: The target tracking strategy triggers both scaling up and scaling down. * `estimated_instance_warmup` - (Optional, Int) Instance warm-up time, in seconds, applicable only to target tracking strategies. Value range is 0-3600, with a default warm-up time of 300 seconds. +* `metric_name` - (Optional, String) Name of an indicator. Valid values: `CPU_UTILIZATION`, `MEM_UTILIZATION`, `LAN_TRAFFIC_OUT`, `LAN_TRAFFIC_IN`, `WAN_TRAFFIC_OUT` and `WAN_TRAFFIC_IN`. * `notification_user_group_ids` - (Optional, List: [`String`]) An ID group of users to be notified when an alarm is triggered. +* `period` - (Optional, Int) Time period in second. Valid values: `60` and `300`. * `policy_type` - (Optional, String, ForceNew) Alarm triggering policy type, the default type is SIMPLE. Value range: SIMPLE: Simple policy; TARGET_TRACKING: Target tracking policy. * `predefined_metric_type` - (Optional, String) Predefined monitoring items, applicable only to target tracking policies, and required in target tracking policy scenarios. Value range: ASG_AVG_CPU_UTILIZATION: Average CPU utilization; ASG_AVG_LAN_TRAFFIC_OUT: Average intranet outbound bandwidth; ASG_AVG_LAN_TRAFFIC_IN: Average intranet inbound bandwidth; ASG_AVG_WAN_TRAFFIC_OUT: Average internet outbound bandwidth; ASG_AVG_WAN_TRAFFIC_IN: Average internet inbound bandwidth. * `statistic` - (Optional, String) Statistic types. Valid values: `AVERAGE`, `MAXIMUM` and `MINIMUM`. Default is `AVERAGE`. * `target_value` - (Optional, Int) Target value, applicable only to target tracking strategies, and required in target tracking strategy scenarios. ASG_AVG_CPU_UTILIZATION: [1, 100), Unit: %; ASG_AVG_LAN_TRAFFIC_OUT: >0, Unit: Mbps; ASG_AVG_LAN_TRAFFIC_IN: >0, Unit: Mbps; ASG_AVG_WAN_TRAFFIC_OUT: >0, Unit: Mbps; ASG_AVG_WAN_TRAFFIC_IN: >0, Unit: Mbps. +* `threshold` - (Optional, Int) Alarm threshold. ## Attributes Reference From a18dc6f3ad21d94b8488eaa9e6a1b160d6597940 Mon Sep 17 00:00:00 2001 From: mikatong Date: Tue, 25 Nov 2025 16:41:39 +0800 Subject: [PATCH 2/2] add changelog --- .changelog/3615.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/3615.txt diff --git a/.changelog/3615.txt b/.changelog/3615.txt new file mode 100644 index 0000000000..671812c5be --- /dev/null +++ b/.changelog/3615.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/tencentcloud_as_scaling_policy: support target tracking policy. +``` \ No newline at end of file