diff --git a/.changelog/2772.txt b/.changelog/2772.txt new file mode 100644 index 0000000000..0c6e6367e2 --- /dev/null +++ b/.changelog/2772.txt @@ -0,0 +1,7 @@ +```release-note:enhancement +resource/tencentcloud_as_scaling_group: support `health_check_type` and `lb_health_check_grace_period` +``` + +```release-note:enhancement +resource/tencentcloud_as_lifecycle_hook: support import and parameter `lifecycle_command` +``` \ No newline at end of file diff --git a/tencentcloud/services/as/resource_tc_as_lifecycle_hook.go b/tencentcloud/services/as/resource_tc_as_lifecycle_hook.go index 44ab420753..024c20fba0 100644 --- a/tencentcloud/services/as/resource_tc_as_lifecycle_hook.go +++ b/tencentcloud/services/as/resource_tc_as_lifecycle_hook.go @@ -20,7 +20,9 @@ func ResourceTencentCloudAsLifecycleHook() *schema.Resource { Read: resourceTencentCloudAsLifecycleHookRead, Update: resourceTencentCloudAsLifecycleHookUpdate, Delete: resourceTencentCloudAsLifecycleHookDelete, - + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, Schema: map[string]*schema.Schema{ "scaling_group_id": { Type: schema.TypeString, @@ -62,8 +64,8 @@ func ResourceTencentCloudAsLifecycleHook() *schema.Resource { "notification_target_type": { Type: schema.TypeString, Optional: true, - ValidateFunc: tccommon.ValidateAllowedStringValue([]string{"CMQ_QUEUE", "CMQ_TOPIC"}), - Description: "Target type. Valid values: `CMQ_QUEUE`, `CMQ_TOPIC`.", + ValidateFunc: tccommon.ValidateAllowedStringValue([]string{"CMQ_QUEUE", "CMQ_TOPIC", "TDMQ_CMQ_QUEUE", "TDMQ_CMQ_TOPIC"}), + Description: "Target type. Valid values: `CMQ_QUEUE`, `CMQ_TOPIC`, `TDMQ_CMQ_QUEUE`, `TDMQ_CMQ_TOPIC`.", }, "notification_queue_name": { Type: schema.TypeString, @@ -75,6 +77,27 @@ func ResourceTencentCloudAsLifecycleHook() *schema.Resource { Optional: true, Description: "For CMQ_TOPIC type, a name of topic must be set.", }, + "lifecycle_command": { + Type: schema.TypeList, + MaxItems: 1, + Computed: true, + Optional: true, + Description: "Remote command execution object. `NotificationTarget` and `LifecycleCommand` cannot be specified at the same time.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "command_id": { + Type: schema.TypeString, + Required: true, + Description: "Remote command ID. It is required to execute a command.", + }, + "parameters": { + Type: schema.TypeString, + Optional: true, + Description: "Custom parameter. The field type is JSON encoded string. For example, {\"varA\": \"222\"}.", + }, + }, + }, + }, }, } } @@ -117,6 +140,17 @@ func resourceTencentCloudAsLifecycleHookCreate(d *schema.ResourceData, meta inte } } + if dMap, ok := helper.InterfacesHeadMap(d, "lifecycle_command"); ok { + lifecycleCommand := as.LifecycleCommand{} + if v, ok := dMap["command_id"]; ok { + lifecycleCommand.CommandId = helper.String(v.(string)) + } + if v, ok := dMap["parameters"]; ok { + lifecycleCommand.Parameters = helper.String(v.(string)) + } + request.LifecycleCommand = &lifecycleCommand + } + response, err := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseAsClient().CreateLifecycleHook(request) if err != nil { log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", @@ -175,6 +209,16 @@ func resourceTencentCloudAsLifecycleHookRead(d *schema.ResourceData, meta interf _ = d.Set("notification_topic_name", *lifecycleHook.NotificationTarget.TopicName) } } + if lifecycleHook.LifecycleCommand != nil { + commandMap := map[string]interface{}{} + if lifecycleHook.LifecycleCommand.CommandId != nil { + commandMap["command_id"] = lifecycleHook.LifecycleCommand.CommandId + } + if lifecycleHook.LifecycleCommand.Parameters != nil { + commandMap["parameters"] = lifecycleHook.LifecycleCommand.Parameters + } + _ = d.Set("lifecycle_command", []interface{}{commandMap}) + } return nil }) if err != nil { @@ -221,6 +265,17 @@ func resourceTencentCloudAsLifecycleHookUpdate(d *schema.ResourceData, meta inte } } + if dMap, ok := helper.InterfacesHeadMap(d, "lifecycle_command"); ok { + lifecycleCommand := as.LifecycleCommand{} + if v, ok := dMap["command_id"]; ok { + lifecycleCommand.CommandId = helper.String(v.(string)) + } + if v, ok := dMap["parameters"]; ok { + lifecycleCommand.Parameters = helper.String(v.(string)) + } + request.LifecycleCommand = &lifecycleCommand + } + response, err := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseAsClient().UpgradeLifecycleHook(request) if err != nil { log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", diff --git a/tencentcloud/services/as/resource_tc_as_lifecycle_hook.md b/tencentcloud/services/as/resource_tc_as_lifecycle_hook.md index a43331d9f7..daa66f13b7 100644 --- a/tencentcloud/services/as/resource_tc_as_lifecycle_hook.md +++ b/tencentcloud/services/as/resource_tc_as_lifecycle_hook.md @@ -45,12 +45,12 @@ resource "tencentcloud_as_scaling_group" "example" { } resource "tencentcloud_as_lifecycle_hook" "example" { - scaling_group_id = tencentcloud_as_scaling_group.example.id - lifecycle_hook_name = "tf-as-lifecycle-hook" - lifecycle_transition = "INSTANCE_LAUNCHING" - default_result = "CONTINUE" - heartbeat_timeout = 500 - notification_metadata = "tf test" + scaling_group_id = tencentcloud_as_scaling_group.example.id + lifecycle_hook_name = "tf-as-lifecycle-hook" + lifecycle_transition = "INSTANCE_LAUNCHING" + default_result = "CONTINUE" + heartbeat_timeout = 500 + notification_metadata = "tf test" } ``` @@ -82,4 +82,28 @@ resource "tencentcloud_as_lifecycle_hook" "example" { notification_target_type = "CMQ_TOPIC" notification_topic_name = "lifcyclehook" } +``` + +Use TAT Command + +```hcl +resource "tencentcloud_as_lifecycle_hook" "example" { + default_result = "CONTINUE" + heartbeat_timeout = 300 + lifecycle_hook_name = "test" + lifecycle_transition = "INSTANCE_TERMINATING" + scaling_group_id = tencentcloud_as_scaling_group.example.id + + lifecycle_command { + command_id = "cmd-xxxx" + } +} +``` + +Import + +lifecycle hook can be imported using the id, e.g. + +``` +terraform import tencentcloud_as_lifecycle_hook.example lifecycle_hook_id ``` \ No newline at end of file diff --git a/tencentcloud/services/as/resource_tc_as_scaling_group.go b/tencentcloud/services/as/resource_tc_as_scaling_group.go index dccd5f4597..5ce9ebc7b8 100644 --- a/tencentcloud/services/as/resource_tc_as_scaling_group.go +++ b/tencentcloud/services/as/resource_tc_as_scaling_group.go @@ -174,6 +174,18 @@ func ResourceTencentCloudAsScalingGroup() *schema.Resource { Optional: true, Description: "Enable unhealthy instance replacement. If set to `true`, AS will replace instances that are found unhealthy in the CLB health check.", }, + "health_check_type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Health check type of instances in a scaling group.
  • CVM: confirm whether an instance is healthy based on the network status. If the pinged instance is unreachable, the instance will be considered unhealthy. For more information, see [Instance Health Check](https://intl.cloud.tencent.com/document/product/377/8553?from_cn_redirect=1)
  • CLB: confirm whether an instance is healthy based on the CLB health check status. For more information, see [Health Check Overview](https://intl.cloud.tencent.com/document/product/214/6097?from_cn_redirect=1).
    If the parameter is set to `CLB`, the scaling group will check both the network status and the CLB health check status. If the network check indicates unhealthy, the `HealthStatus` field will return `UNHEALTHY`. If the CLB health check indicates unhealthy, the `HealthStatus` field will return `CLB_UNHEALTHY`. If both checks indicate unhealthy, the `HealthStatus` field will return `UNHEALTHY|CLB_UNHEALTHY`. Default value: `CLB`.", + }, + "lb_health_check_grace_period": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Grace period of the CLB health check during which the `IN_SERVICE` instances added will not be marked as `CLB_UNHEALTHY`.
    Valid range: 0-7200, in seconds. Default value: `0`.", + }, "tags": { Type: schema.TypeMap, Optional: true, @@ -294,6 +306,14 @@ func resourceTencentCloudAsScalingGroupCreate(d *schema.ResourceData, meta inter request.MultiZoneSubnetPolicy = helper.String(v.(string)) } + if v, ok := d.GetOk("health_check_type"); ok { + request.HealthCheckType = helper.String(v.(string)) + } + + if v, ok := d.GetOkExists("lb_health_check_grace_period"); ok { + request.LoadBalancerHealthCheckGracePeriod = helper.IntUint64(v.(int)) + } + var ( scalingMode = d.Get("scaling_mode").(string) replaceMonitorUnhealthy = d.Get("replace_monitor_unhealthy").(bool) @@ -418,6 +438,9 @@ func resourceTencentCloudAsScalingGroupRead(d *schema.ResourceData, meta interfa _ = d.Set("termination_policies", helper.StringsInterfaces(scalingGroup.TerminationPolicySet)) _ = d.Set("retry_policy", scalingGroup.RetryPolicy) _ = d.Set("create_time", scalingGroup.CreatedTime) + _ = d.Set("retry_policy", scalingGroup.RetryPolicy) + _ = d.Set("health_check_type", scalingGroup.HealthCheckType) + _ = d.Set("lb_health_check_grace_period", scalingGroup.LoadBalancerHealthCheckGracePeriod) if v, ok := d.GetOk("multi_zone_subnet_policy"); ok && v.(string) != "" { _ = d.Set("multi_zone_subnet_policy", scalingGroup.MultiZoneSubnetPolicy) } @@ -568,6 +591,13 @@ func resourceTencentCloudAsScalingGroupUpdate(d *schema.ResourceData, meta inter } } + if d.HasChange("health_check_type") || d.HasChange("lb_health_check_grace_period") { + request.HealthCheckType = helper.String(d.Get("health_check_type").(string)) + if v, ok := d.GetOkExists("lb_health_check_grace_period"); ok { + request.LoadBalancerHealthCheckGracePeriod = helper.IntUint64(v.(int)) + } + } + if err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { ratelimit.Check(request.GetAction()) diff --git a/tencentcloud/services/as/resource_tc_as_scaling_group.md b/tencentcloud/services/as/resource_tc_as_scaling_group.md index 52d39ccf59..5e54f30be3 100644 --- a/tencentcloud/services/as/resource_tc_as_scaling_group.md +++ b/tencentcloud/services/as/resource_tc_as_scaling_group.md @@ -36,12 +36,15 @@ resource "tencentcloud_as_scaling_config" "example" { } 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] + 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] + health_check_type = "CLB" + replace_load_balancer_unhealthy = true + lb_health_check_grace_period = 30 } ``` diff --git a/website/docs/r/as_lifecycle_hook.html.markdown b/website/docs/r/as_lifecycle_hook.html.markdown index ae89f9a18f..0f9c8097e5 100644 --- a/website/docs/r/as_lifecycle_hook.html.markdown +++ b/website/docs/r/as_lifecycle_hook.html.markdown @@ -95,6 +95,22 @@ resource "tencentcloud_as_lifecycle_hook" "example" { } ``` +### Use TAT Command + +```hcl +resource "tencentcloud_as_lifecycle_hook" "example" { + default_result = "CONTINUE" + heartbeat_timeout = 300 + lifecycle_hook_name = "test" + lifecycle_transition = "INSTANCE_TERMINATING" + scaling_group_id = tencentcloud_as_scaling_group.example.id + + lifecycle_command { + command_id = "cmd-xxxx" + } +} +``` + ## Argument Reference The following arguments are supported: @@ -104,11 +120,17 @@ The following arguments are supported: * `scaling_group_id` - (Required, String, ForceNew) ID of a scaling group. * `default_result` - (Optional, String) Defines the action the AS group should take when the lifecycle hook timeout elapses or if an unexpected failure occurs. Valid values: `CONTINUE` and `ABANDON`. The default value is `CONTINUE`. * `heartbeat_timeout` - (Optional, Int) Defines the amount of time, in seconds, that can elapse before the lifecycle hook times out. Valid value ranges: (30~7200). and default value is `300`. +* `lifecycle_command` - (Optional, List) Remote command execution object. `NotificationTarget` and `LifecycleCommand` cannot be specified at the same time. * `notification_metadata` - (Optional, String) Contains additional information that you want to include any time AS sends a message to the notification target. * `notification_queue_name` - (Optional, String) For CMQ_QUEUE type, a name of queue must be set. -* `notification_target_type` - (Optional, String) Target type. Valid values: `CMQ_QUEUE`, `CMQ_TOPIC`. +* `notification_target_type` - (Optional, String) Target type. Valid values: `CMQ_QUEUE`, `CMQ_TOPIC`, `TDMQ_CMQ_QUEUE`, `TDMQ_CMQ_TOPIC`. * `notification_topic_name` - (Optional, String) For CMQ_TOPIC type, a name of topic must be set. +The `lifecycle_command` object supports the following: + +* `command_id` - (Required, String) Remote command ID. It is required to execute a command. +* `parameters` - (Optional, String) Custom parameter. The field type is JSON encoded string. For example, {"varA": "222"}. + ## Attributes Reference In addition to all arguments above, the following attributes are exported: @@ -117,3 +139,11 @@ In addition to all arguments above, the following attributes are exported: +## Import + +lifecycle hook can be imported using the id, e.g. + +``` +terraform import tencentcloud_as_lifecycle_hook.example lifecycle_hook_id +``` + diff --git a/website/docs/r/as_scaling_group.html.markdown b/website/docs/r/as_scaling_group.html.markdown index 4a6b515413..7b33582951 100644 --- a/website/docs/r/as_scaling_group.html.markdown +++ b/website/docs/r/as_scaling_group.html.markdown @@ -47,12 +47,15 @@ resource "tencentcloud_as_scaling_config" "example" { } 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] + 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] + health_check_type = "CLB" + replace_load_balancer_unhealthy = true + lb_health_check_grace_period = 30 } ``` @@ -127,6 +130,8 @@ The following arguments are supported: * `default_cooldown` - (Optional, Int) Default cooldown time in second, and default value is `300`. * `desired_capacity` - (Optional, Int) Desired volume of CVM instances, which is between `max_size` and `min_size`. * `forward_balancer_ids` - (Optional, List) List of application load balancers, which can't be specified with `load_balancer_ids` together. +* `health_check_type` - (Optional, String) Health check type of instances in a scaling group.
  • CVM: confirm whether an instance is healthy based on the network status. If the pinged instance is unreachable, the instance will be considered unhealthy. For more information, see [Instance Health Check](https://intl.cloud.tencent.com/document/product/377/8553?from_cn_redirect=1)
  • CLB: confirm whether an instance is healthy based on the CLB health check status. For more information, see [Health Check Overview](https://intl.cloud.tencent.com/document/product/214/6097?from_cn_redirect=1).
    If the parameter is set to `CLB`, the scaling group will check both the network status and the CLB health check status. If the network check indicates unhealthy, the `HealthStatus` field will return `UNHEALTHY`. If the CLB health check indicates unhealthy, the `HealthStatus` field will return `CLB_UNHEALTHY`. If both checks indicate unhealthy, the `HealthStatus` field will return `UNHEALTHY|CLB_UNHEALTHY`. Default value: `CLB`. +* `lb_health_check_grace_period` - (Optional, Int) Grace period of the CLB health check during which the `IN_SERVICE` instances added will not be marked as `CLB_UNHEALTHY`.
    Valid range: 0-7200, in seconds. Default value: `0`. * `load_balancer_ids` - (Optional, List: [`String`]) ID list of traditional load balancers. * `multi_zone_subnet_policy` - (Optional, String) Multi zone or subnet strategy, Valid values: PRIORITY and EQUALITY. * `project_id` - (Optional, Int) Specifies to which project the scaling group belongs.