Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 49 additions & 23 deletions tencentcloud/resource_tc_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -543,29 +543,6 @@ func resourceTencentCloudInstance() *schema.Resource {
Description: "Expired time of the instance.",
},
},
CustomizeDiff: func(ctx context.Context, d *schema.ResourceDiff, meta interface{}) error {
// 腾讯云的CVM实例在修改实例类型时,需要强制创建新的实例,否则api进行关机操作失败不会主动恢复原有状态
// 这些选项会触发update中ResetInstanceXXX导致强制重启,所以必须设置为强制创建新的实例
resetInstanceOptions := []string{
"instance_type",
"image_id",
"hostname",
"disable_security_service",
"disable_monitor_service",
"disable_automation_service",
"keep_image_login",
}
for _, option := range resetInstanceOptions {
oldValue, newValue := d.GetChange(option)
if oldValue != newValue {
err := d.ForceNew(option)
if err != nil {
return err
}
}
}
return nil
},
}
}

Expand Down Expand Up @@ -1154,6 +1131,38 @@ func resourceTencentCloudInstanceUpdate(d *schema.ResourceData, meta interface{}
client: meta.(*TencentCloudClient).apiV3Conn,
}

// recover instance power status
defer func() {
var instance *cvm.Instance
var target string
if err != nil {
return
} else if instance, err = cvmService.DescribeInstanceById(ctx, instanceId); err != nil {
return
} else if *instance.InstanceState == CVM_STATUS_STOPPED && d.Get("running_flag").(bool) {
err = cvmService.StartInstance(ctx, instanceId)
target = CVM_STATUS_RUNNING
} else if *instance.InstanceState == CVM_STATUS_RUNNING && !d.Get("running_flag").(bool) {
err = cvmService.StopInstance(ctx, instanceId, d.Get("stopped_mode").(string)) // default is "KEEP_CHARGING"
target = CVM_STATUS_STOPPED
} else {
return
}

if err != nil {
return
}
err = resource.Retry(2*readRetryTimeout, func() *resource.RetryError {
instance, errRet := cvmService.DescribeInstanceById(ctx, instanceId)
if errRet != nil {
return retryError(errRet, InternalError)
} else if *instance.InstanceState != target {
return resource.RetryableError(fmt.Errorf("cvm instance status is %s, retry...", *instance.InstanceState))
}
return nil
})
}()

d.Partial(true)

// Get the latest instance info from actual resource.
Expand Down Expand Up @@ -1301,6 +1310,23 @@ func resourceTencentCloudInstanceUpdate(d *schema.ResourceData, meta interface{}
d.HasChange("disable_automation_service") ||
d.HasChange("keep_image_login") {

err = cvmService.StopInstance(ctx, instanceId, "KEEP_CHARGING")
if err != nil {
return
}
err = resource.Retry(2*readRetryTimeout, func() *resource.RetryError {
instance, errRet := cvmService.DescribeInstanceById(ctx, instanceId)
if errRet != nil {
return retryError(errRet, InternalError)
} else if *instance.InstanceState != CVM_STATUS_STOPPED {
return resource.RetryableError(fmt.Errorf("cvm instance status is %s, retry...", *instance.InstanceState))
}
return nil
})
if err != nil {
return
}

request := cvm.NewResetInstanceRequest()
request.InstanceId = helper.String(d.Id())

Expand Down
18 changes: 17 additions & 1 deletion tencentcloud/service_tencentcloud_cvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,10 +286,26 @@ func (me *CvmService) ModifyProjectId(ctx context.Context, instanceId string, pr

func (me *CvmService) ModifyInstanceType(ctx context.Context, instanceId, instanceType string) error {
logId := getLogId(ctx)
// 根据文档 https://cloud.tencent.com/document/api/213/15744 中的建议,先停止实例再修改实例类型
err := me.StopInstance(ctx, instanceId, "KEEP_CHARGING")
if err != nil {
return err
}
err = resource.Retry(2*readRetryTimeout, func() *resource.RetryError {
instance, errRet := me.DescribeInstanceById(ctx, instanceId)
if errRet != nil {
return retryError(errRet, InternalError)
} else if *instance.InstanceState != CVM_STATUS_STOPPED {
return resource.RetryableError(fmt.Errorf("cvm instance status is %s, retry...", *instance.InstanceState))
}
return nil
})
if err != nil {
return err
}
request := cvm.NewResetInstancesTypeRequest()
request.InstanceIds = []*string{&instanceId}
request.InstanceType = &instanceType
request.ForceStop = helper.Bool(true)

ratelimit.Check(request.GetAction())
response, err := me.client.UseCvmClient().ResetInstancesType(request)
Expand Down
Loading