Skip to content

Commit e370900

Browse files
authored
fix(cvm): [124249242] tencentcloud_instance support modify placement_group_id (#3383)
* add * add * add * add * add * add
1 parent 99f1c28 commit e370900

File tree

4 files changed

+209
-6
lines changed

4 files changed

+209
-6
lines changed

.changelog/3383.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
resource/tencentcloud_instance: support modify `placement_group_id`
3+
```

tencentcloud/services/cvm/resource_tc_instance.go

Lines changed: 138 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,14 @@ func ResourceTencentCloudInstance() *schema.Resource {
108108
"placement_group_id": {
109109
Type: schema.TypeString,
110110
Optional: true,
111-
ForceNew: true,
112111
Description: "The ID of a placement group.",
113112
},
113+
"force_replace_placement_group_id": {
114+
Type: schema.TypeBool,
115+
Optional: true,
116+
RequiredWith: []string{"placement_group_id"},
117+
Description: "Whether to force the instance host to be replaced. Value range: true: Allows the instance to change the host and restart the instance. Local disk machines do not support specifying this parameter; false: Does not allow the instance to change the host and only join the placement group on the current host. This may cause the placement group to fail to change. Only useful for change `placement_group_id`, Default is false.",
118+
},
114119
// payment
115120
"instance_charge_type": {
116121
Type: schema.TypeString,
@@ -576,8 +581,18 @@ func resourceTencentCloudInstanceCreate(d *schema.ResourceData, meta interface{}
576581
}
577582
}
578583

579-
if v, ok := d.GetOk("placement_group_id"); ok {
580-
request.DisasterRecoverGroupIds = []*string{helper.String(v.(string))}
584+
var (
585+
rpgFlag bool
586+
)
587+
588+
if v, ok := d.GetOkExists("force_replace_placement_group_id"); ok {
589+
rpgFlag = v.(bool)
590+
}
591+
592+
if !rpgFlag {
593+
if v, ok := d.GetOk("placement_group_id"); ok {
594+
request.DisasterRecoverGroupIds = []*string{helper.String(v.(string))}
595+
}
581596
}
582597

583598
// network
@@ -835,6 +850,57 @@ func resourceTencentCloudInstanceCreate(d *schema.ResourceData, meta interface{}
835850
return err
836851
}
837852

853+
// set placement group id
854+
if rpgFlag {
855+
if v, ok := d.GetOk("placement_group_id"); ok && v != "" {
856+
request := cvm.NewModifyInstancesDisasterRecoverGroupRequest()
857+
request.InstanceIds = helper.Strings([]string{instanceId})
858+
request.DisasterRecoverGroupId = helper.String(v.(string))
859+
request.Force = helper.Bool(rpgFlag)
860+
err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError {
861+
result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ModifyInstancesDisasterRecoverGroup(request)
862+
if e != nil {
863+
return tccommon.RetryError(e)
864+
} else {
865+
log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString())
866+
}
867+
868+
return nil
869+
})
870+
871+
if err != nil {
872+
return err
873+
}
874+
875+
// wait
876+
err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError {
877+
instance, errRet := cvmService.DescribeInstanceById(ctx, instanceId)
878+
if errRet != nil {
879+
return tccommon.RetryError(errRet, tccommon.InternalError)
880+
}
881+
882+
if instance != nil && *instance.InstanceState == CVM_STATUS_LAUNCH_FAILED {
883+
//LatestOperationCodeMode
884+
if instance.LatestOperationErrorMsg != nil {
885+
return resource.NonRetryableError(fmt.Errorf("cvm instance %s launch failed. Error msg: %s.\n", *instance.InstanceId, *instance.LatestOperationErrorMsg))
886+
}
887+
888+
return resource.NonRetryableError(fmt.Errorf("cvm instance %s launch failed, this resource will not be stored to tfstate and will auto removed\n.", *instance.InstanceId))
889+
}
890+
891+
if instance != nil && *instance.InstanceState == CVM_STATUS_RUNNING {
892+
return nil
893+
}
894+
895+
return resource.RetryableError(fmt.Errorf("cvm instance status is %s, retry...", *instance.InstanceState))
896+
})
897+
898+
if err != nil {
899+
return err
900+
}
901+
}
902+
}
903+
838904
// Wait for the tags attached to the vm since tags attachment it's async while vm creation.
839905
if tags := helper.GetTags(d, "tags"); len(tags) > 0 {
840906
tcClient := meta.(tccommon.ProviderMeta).GetAPIV3Conn()
@@ -988,6 +1054,10 @@ func resourceTencentCloudInstanceRead(d *schema.ResourceData, meta interface{})
9881054
_ = d.Set("uuid", instance.Uuid)
9891055
}
9901056

1057+
if instance.DisasterRecoverGroupId != nil {
1058+
_ = d.Set("placement_group_id", instance.DisasterRecoverGroupId)
1059+
}
1060+
9911061
if *instance.InstanceChargeType == CVM_CHARGE_TYPE_CDHPAID {
9921062
_ = d.Set("cdh_instance_type", instance.InstanceType)
9931063
}
@@ -2027,6 +2097,7 @@ func resourceTencentCloudInstanceUpdate(d *schema.ResourceData, meta interface{}
20272097
return err
20282098
}
20292099
}
2100+
20302101
if d.HasChange("user_data_raw") {
20312102
userDataRaw := d.Get("user_data_raw").(string)
20322103
userData := base64.StdEncoding.EncodeToString([]byte(userDataRaw))
@@ -2040,6 +2111,70 @@ func resourceTencentCloudInstanceUpdate(d *schema.ResourceData, meta interface{}
20402111
return err
20412112
}
20422113
}
2114+
2115+
if d.HasChange("placement_group_id") || d.HasChange("force_replace_placement_group_id") {
2116+
oldPGI, newPGI := d.GetChange("placement_group_id")
2117+
oldPGIStr := oldPGI.(string)
2118+
newPGIStr := newPGI.(string)
2119+
if newPGIStr == "" {
2120+
// wait cvm support delete DisasterRecoverGroupId
2121+
return fmt.Errorf("Deleting `placement_group_id` is not currently supported.")
2122+
} else {
2123+
if oldPGIStr == newPGIStr {
2124+
return fmt.Errorf("It is not possible to change only `force_replace_placement_group_id`, it needs to be modified together with `placement_group_id`.")
2125+
}
2126+
2127+
request := cvm.NewModifyInstancesDisasterRecoverGroupRequest()
2128+
if v, ok := d.GetOkExists("force_replace_placement_group_id"); ok {
2129+
request.Force = helper.Bool(v.(bool))
2130+
}
2131+
2132+
request.InstanceIds = helper.Strings([]string{instanceId})
2133+
request.DisasterRecoverGroupId = helper.String(newPGIStr)
2134+
err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError {
2135+
result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ModifyInstancesDisasterRecoverGroup(request)
2136+
if e != nil {
2137+
return tccommon.RetryError(e)
2138+
} else {
2139+
log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString())
2140+
}
2141+
2142+
return nil
2143+
})
2144+
2145+
if err != nil {
2146+
return err
2147+
}
2148+
2149+
// wait
2150+
err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError {
2151+
instance, errRet := cvmService.DescribeInstanceById(ctx, instanceId)
2152+
if errRet != nil {
2153+
return tccommon.RetryError(errRet, tccommon.InternalError)
2154+
}
2155+
2156+
if instance != nil && *instance.InstanceState == CVM_STATUS_LAUNCH_FAILED {
2157+
//LatestOperationCodeMode
2158+
if instance.LatestOperationErrorMsg != nil {
2159+
return resource.NonRetryableError(fmt.Errorf("cvm instance %s launch failed. Error msg: %s.\n", *instance.InstanceId, *instance.LatestOperationErrorMsg))
2160+
}
2161+
2162+
return resource.NonRetryableError(fmt.Errorf("cvm instance %s launch failed, this resource will not be stored to tfstate and will auto removed\n.", *instance.InstanceId))
2163+
}
2164+
2165+
if instance != nil && *instance.InstanceState == CVM_STATUS_RUNNING {
2166+
return nil
2167+
}
2168+
2169+
return resource.RetryableError(fmt.Errorf("cvm instance status is %s, retry...", *instance.InstanceState))
2170+
})
2171+
2172+
if err != nil {
2173+
return err
2174+
}
2175+
}
2176+
}
2177+
20432178
d.Partial(false)
20442179

20452180
return resourceTencentCloudInstanceRead(d, meta)

tencentcloud/services/cvm/resource_tc_instance.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ Provides a CVM instance resource.
22

33
~> **NOTE:** You can launch an CVM instance for a VPC network via specifying parameter `vpc_id`. One instance can only belong to one VPC.
44

5-
~> **NOTE:** At present, 'PREPAID' instance cannot be deleted directly and must wait it to be outdated and released automatically.
5+
~> **NOTE:** At present, `PREPAID` instance cannot be deleted directly and must wait it to be outdated and released automatically.
6+
7+
~> **NOTE:** Currently, the `placement_group_id` field only supports setting and modification, but not deletion.
68

79
Example Usage
810

@@ -200,6 +202,36 @@ resource "tencentcloud_instance" "example" {
200202
}
201203
```
202204

205+
Create CVM instance with placement_group_id
206+
207+
```hcl
208+
resource "tencentcloud_instance" "example" {
209+
instance_name = "tf-example"
210+
availability_zone = "ap-guangzhou-6"
211+
image_id = "img-eb30mz89"
212+
instance_type = "S5.MEDIUM4"
213+
system_disk_size = 50
214+
system_disk_name = "sys_disk_1"
215+
hostname = "user"
216+
project_id = 0
217+
vpc_id = "vpc-i5yyodl9"
218+
subnet_id = "subnet-hhi88a58"
219+
placement_group_id = "ps-ejt4brtz"
220+
force_replace_placement_group_id = false
221+
222+
data_disks {
223+
data_disk_type = "CLOUD_HSSD"
224+
data_disk_size = 100
225+
encrypt = false
226+
data_disk_name = "data_disk_1"
227+
}
228+
229+
tags = {
230+
tagKey = "tagValue"
231+
}
232+
}
233+
```
234+
203235
Import
204236

205237
CVM instance can be imported using the id, e.g.

website/docs/r/instance.html.markdown

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ Provides a CVM instance resource.
1313

1414
~> **NOTE:** You can launch an CVM instance for a VPC network via specifying parameter `vpc_id`. One instance can only belong to one VPC.
1515

16-
~> **NOTE:** At present, 'PREPAID' instance cannot be deleted directly and must wait it to be outdated and released automatically.
16+
~> **NOTE:** At present, `PREPAID` instance cannot be deleted directly and must wait it to be outdated and released automatically.
17+
18+
~> **NOTE:** Currently, the `placement_group_id` field only supports setting and modification, but not deletion.
1719

1820
## Example Usage
1921

@@ -211,6 +213,36 @@ resource "tencentcloud_instance" "example" {
211213
}
212214
```
213215

216+
### Create CVM instance with placement_group_id
217+
218+
```hcl
219+
resource "tencentcloud_instance" "example" {
220+
instance_name = "tf-example"
221+
availability_zone = "ap-guangzhou-6"
222+
image_id = "img-eb30mz89"
223+
instance_type = "S5.MEDIUM4"
224+
system_disk_size = 50
225+
system_disk_name = "sys_disk_1"
226+
hostname = "user"
227+
project_id = 0
228+
vpc_id = "vpc-i5yyodl9"
229+
subnet_id = "subnet-hhi88a58"
230+
placement_group_id = "ps-ejt4brtz"
231+
force_replace_placement_group_id = false
232+
233+
data_disks {
234+
data_disk_type = "CLOUD_HSSD"
235+
data_disk_size = 100
236+
encrypt = false
237+
data_disk_name = "data_disk_1"
238+
}
239+
240+
tags = {
241+
tagKey = "tagValue"
242+
}
243+
}
244+
```
245+
214246
## Argument Reference
215247

216248
The following arguments are supported:
@@ -229,6 +261,7 @@ The following arguments are supported:
229261
* `disable_monitor_service` - (Optional, Bool) Disable enhance service for monitor, it is enabled by default. When this options is set, monitor agent won't be installed. Modifications may lead to the reinstallation of the instance's operating system.
230262
* `disable_security_service` - (Optional, Bool) Disable enhance service for security, it is enabled by default. When this options is set, security agent won't be installed. Modifications may lead to the reinstallation of the instance's operating system.
231263
* `force_delete` - (Optional, Bool) Indicate whether to force delete the instance. Default is `false`. If set true, the instance will be permanently deleted instead of being moved into the recycle bin. Note: only works for `PREPAID` instance.
264+
* `force_replace_placement_group_id` - (Optional, Bool) Whether to force the instance host to be replaced. Value range: true: Allows the instance to change the host and restart the instance. Local disk machines do not support specifying this parameter; false: Does not allow the instance to change the host and only join the placement group on the current host. This may cause the placement group to fail to change. Only useful for change `placement_group_id`, Default is false.
232265
* `hostname` - (Optional, String) The hostname of the instance. Windows instance: The name should be a combination of 2 to 15 characters comprised of letters (case insensitive), numbers, and hyphens (-). Period (.) is not supported, and the name cannot be a string of pure numbers. Other types (such as Linux) of instances: The name should be a combination of 2 to 60 characters, supporting multiple periods (.). The piece between two periods is composed of letters (case insensitive), numbers, and hyphens (-). Modifications may lead to the reinstallation of the instance's operating system.
233266
* `hpc_cluster_id` - (Optional, String, ForceNew) High-performance computing cluster ID. If the instance created is a high-performance computing instance, you need to specify the cluster in which the instance is placed, otherwise it cannot be specified.
234267
* `instance_charge_type_prepaid_period` - (Optional, Int) The tenancy (time unit is month) of the prepaid instance, NOTE: it only works when instance_charge_type is set to `PREPAID`. Valid values are `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `24`, `36`, `48`, `60`.
@@ -244,7 +277,7 @@ The following arguments are supported:
244277
* `key_name` - (Optional, String, **Deprecated**) Please use `key_ids` instead. The key pair to use for the instance, it looks like `skey-16jig7tx`. Modifications may lead to the reinstallation of the instance's operating system.
245278
* `orderly_security_groups` - (Optional, List: [`String`]) A list of orderly security group IDs to associate with.
246279
* `password` - (Optional, String) Password for the instance. In order for the new password to take effect, the instance will be restarted after the password change. Modifications may lead to the reinstallation of the instance's operating system.
247-
* `placement_group_id` - (Optional, String, ForceNew) The ID of a placement group.
280+
* `placement_group_id` - (Optional, String) The ID of a placement group.
248281
* `private_ip` - (Optional, String) The private IP to be assigned to this instance, must be in the provided subnet and available.
249282
* `project_id` - (Optional, Int) The project the instance belongs to, default to 0.
250283
* `running_flag` - (Optional, Bool) Set instance to running or stop. Default value is true, the instance will shutdown when this flag is false.

0 commit comments

Comments
 (0)