Skip to content

Commit 5ae3faa

Browse files
authored
docs(cynosdb): [135298064]update readonly instance field description (#4319)
* docs(cynosdb): update readonly instance field description * feat(cynosdb): support modifying instance_name for readonly instance
1 parent c9ebb31 commit 5ae3faa

13 files changed

Lines changed: 345 additions & 5 deletions

File tree

.changelog/4319.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_cynosdb_readonly_instance: support `instance_name` modification via `ModifyInstanceName` API
3+
```
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
schema: spec-driven
2+
created: 2026-07-17
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# add-cynosdb-readonly-instance-name-modify
2+
3+
Support instance_name modification for tencentcloud_cynosdb_readonly_instance via ModifyInstanceName API
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
## Context
2+
3+
`tencentcloud_cynosdb_readonly_instance` 资源当前的 `instance_name` 字段为 `ForceNew`,修改实例名称会触发资源销毁重建。腾讯云 TDSQL-C MySQL 提供了 `ModifyInstanceName` 接口(cynosdb v20190107),支持对已存在的实例修改名称,请求参数为 `InstanceId``InstanceName`,无需异步轮询(同步返回)。
4+
5+
现有代码结构:
6+
- 资源文件:`tencentcloud/services/cynosdb/resource_tc_cynosdb_readonly_instance.go`
7+
- 服务层:`tencentcloud/services/cynosdb/service_tencentcloud_cynosdb.go`(已有 `ModifyClusterName` 等同类方法可参考)
8+
- 测试:`tencentcloud/services/cynosdb/resource_tc_cynosdb_readonly_instance_test.go`(现有 Terraform acc 测试套件)
9+
10+
## Goals / Non-Goals
11+
12+
**Goals:**
13+
- 使 `instance_name` 字段支持就地更新,调用 `ModifyInstanceName` API 完成修改。
14+
- 在服务层封装 `ModifyInstanceName` 调用,遵循 `WriteRetryTimeout` 重试与 `tccommon.RetryError` 错误包装的现有模式。
15+
- 保持向后兼容:不改变现有 state 格式与 ID 规则。
16+
17+
**Non-Goals:**
18+
- 不修改 `instance_name``Required` 属性。
19+
- 不调整其它字段(如 `vpc_id`/`subnet_id` 仍不支持变更)。
20+
- 不引入新的 schema 字段。
21+
22+
## Decisions
23+
24+
### Decision 1: 移除 instance_name 的 ForceNew
25+
26+
**选择**:将 `instance_name``ForceNew: true` 删除,使其成为可更新字段。
27+
28+
**理由**`ModifyInstanceName` API 支持修改实例名称,无需重建资源。移除 `ForceNew` 是接入该 API 的前提。
29+
30+
**替代方案**:保留 `ForceNew` 并新增一个独立字段——会导致语义重复且用户体验割裂,弃用。
31+
32+
### Decision 2: 在 Update 方法中增加 instance_name 变更分支
33+
34+
**选择**:在 `resourceTencentCloudCynosdbReadonlyInstanceUpdate` 中新增 `if d.HasChange("instance_name")` 分支,调用 `cynosdbService.ModifyInstanceName(ctx, instanceId, instanceName)`
35+
36+
**理由**:与现有 `instance_cpu_core`/`instance_memory_size`、维护窗口等分支保持一致的 `d.HasChange` 模式。
37+
38+
### Decision 3: 服务层方法签名与重试策略
39+
40+
**选择**:在 `service_tencentcloud_cynosdb.go` 中新增:
41+
```go
42+
func (me *CynosdbService) ModifyInstanceName(ctx context.Context, instanceId string, instanceName string) (errRet error)
43+
```
44+
内部使用 `resource.Retry(tccommon.WriteRetryTimeout, ...)` + `tccommon.RetryError(err)`,与 `ModifyClusterName` 方法保持一致。
45+
46+
**理由**:写操作遵循 provider 现有重试模式;请求参数仅 `InstanceId` 与 `InstanceName`,无需额外封装。
47+
48+
### Decision 4: 单元测试使用 gomonkey mock
49+
50+
**选择**:在 `resource_tc_cynosdb_readonly_instance_test.go` 中新增 `TestUnitCynosdbReadonlyInstance_UpdateInstanceName`,使用 gomonkey mock `UseCynosdbClient`、`ModifyInstanceName`、`DescribeInstances`(用于 Read)。
51+
52+
**理由**:本变更新增了 CRUD 逻辑分支,按照代码生成要求使用 mock 进行业务逻辑单元测试,可独立运行无需云资源。
53+
54+
## Risks / Trade-offs
55+
56+
- **[风险] 旧 state 中 instance_name 为 ForceNew,升级后行为变化** → 缓解:仅是从"重建"变为"就地更新",对用户而言是行为增强,不会破坏已有配置;首次 apply 不会触发任何变更。
57+
- **[风险] ModifyInstanceName 接口偶发失败** → 缓解:通过 `WriteRetryTimeout` 重试机制覆盖。
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
## Why
2+
3+
`tencentcloud_cynosdb_readonly_instance` 资源当前的 `instance_name` 字段被标记为 `ForceNew`,用户修改实例名称时会导致资源重建。腾讯云 TDSQL-C MySQL 提供了 `ModifyInstanceName` 接口用于修改实例名称,应在 Terraform 中接入该接口,使 `instance_name` 支持就地更新,避免不必要的重建。
4+
5+
## What Changes
6+
7+
- 移除 `tencentcloud_cynosdb_readonly_instance` 资源中 `instance_name` 字段的 `ForceNew`,使其支持更新。
8+
-`resourceTencentCloudCynosdbReadonlyInstanceUpdate` 中新增 `d.HasChange("instance_name")` 分支,调用云 API `ModifyInstanceName` 完成实例名称修改。
9+
-`service_tencentcloud_cynosdb.go` 中新增 `ModifyInstanceName` 服务方法,封装 `ModifyInstanceName` API 调用(含 `WriteRetryTimeout` 重试)。
10+
- 更新文档 `website/docs/r/cynosdb_readonly_instance.html.markdown`,将 `instance_name``ForceNew` 标记移除。
11+
- 更新 `.changelog/4319.txt`,将变更描述从"update instance_name field description"改为支持 `instance_name` 修改的增强说明。
12+
-`resource_tc_cynosdb_readonly_instance_test.go` 中补充 `instance_name` 更新的单元测试用例���使用 gomonkey mock 云 API)。
13+
14+
## Capabilities
15+
16+
### New Capabilities
17+
- `cynosdb-readonly-instance-name-modify`: 支持通过 `ModifyInstanceName` 接口就地修改 `tencentcloud_cynosdb_readonly_instance``instance_name` 字段。
18+
19+
### Modified Capabilities
20+
<!-- 无需修改已有 spec 层面的行为契约 -->
21+
22+
## Impact
23+
24+
- **代码文件**
25+
- `tencentcloud/services/cynosdb/resource_tc_cynosdb_readonly_instance.go`(schema、update)
26+
- `tencentcloud/services/cynosdb/service_tencentcloud_cynosdb.go`(新增服务方法)
27+
- `tencentcloud/services/cynosdb/resource_tc_cynosdb_readonly_instance_test.go`(单元测试)
28+
- **文档文件**`website/docs/r/cynosdb_readonly_instance.html.markdown`
29+
- **changelog**`.changelog/4319.txt`
30+
- **API**`ModifyInstanceName`(cynosdb v20190107)
31+
- **向后兼容**:仅将 `ForceNew` 字段改为可更新,原有 state 与配置完全兼容,不会触发重建。
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
## ADDED Requirements
2+
3+
### Requirement: instance_name supports in-place update
4+
5+
The `tencentcloud_cynosdb_readonly_instance` resource SHALL allow the `instance_name` field to be updated in-place without recreating the resource. When `instance_name` changes, the provider SHALL call the `ModifyInstanceName` API to update the instance name on the cloud, then refresh state.
6+
7+
#### Scenario: Update instance_name triggers ModifyInstanceName API
8+
9+
- **WHEN** the user updates `instance_name` in the Terraform configuration for an existing `tencentcloud_cynosdb_readonly_instance`
10+
- **THEN** the provider SHALL call `ModifyInstanceName` with the instance ID and the new instance name, and SHALL NOT recreate the resource
11+
12+
#### Scenario: instance_name is no longer ForceNew
13+
14+
- **WHEN** the schema for `instance_name` is inspected
15+
- **THEN** the field SHALL be `Required` and `String`, and SHALL NOT have `ForceNew` set
16+
17+
#### Scenario: Read reflects updated instance_name
18+
19+
- **WHEN** `ModifyInstanceName` succeeds and a subsequent Read is performed
20+
- **THEN** the provider SHALL set `instance_name` in state to the value returned by the `DescribeInstanceById` API
21+
22+
#### Scenario: ModifyInstanceName failure is retried
23+
24+
- **WHEN** the `ModifyInstanceName` API returns an error
25+
- **THEN** the provider SHALL wrap the error with `tccommon.RetryError` and retry within `WriteRetryTimeout`
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
## 1. 服务层方法
2+
3+
- [x] 1.1 在 `tencentcloud/services/cynosdb/service_tencentcloud_cynosdb.go` 中新增 `ModifyInstanceName(ctx, instanceId, instanceName)` 方法,使用 `cynosdb.NewModifyInstanceNameRequest()`,设置 `InstanceId``InstanceName`,内部使用 `resource.Retry(tccommon.WriteRetryTimeout, ...)` + `tccommon.RetryError(err)`,参考 `ModifyClusterName` 方法实现
4+
5+
## 2. 资源 Schema 与 Update 逻辑
6+
7+
- [x] 2.1 在 `tencentcloud/services/cynosdb/resource_tc_cynosdb_readonly_instance.go``ResourceTencentCloudCynosdbReadonlyInstance()` 中,移除 `instance_name` 字段的 `ForceNew: true`
8+
- [x] 2.2 在 `resourceTencentCloudCynosdbReadonlyInstanceUpdate` 中,新增 `if d.HasChange("instance_name")` 分支,读取新值并调用 `cynosdbService.ModifyInstanceName(ctx, instanceId, instanceName)`,处理 error
9+
10+
## 3. 单元测试
11+
12+
- [x] 3.1 在 `tencentcloud/services/cynosdb/resource_tc_cynosdb_readonly_instance_test.go` 中新增 `TestUnitCynosdbReadonlyInstance_UpdateInstanceName`,使用 gomonkey mock `UseCynosdbClient``ModifyInstanceName``DescribeInstances`,验证 Update 路径调用 ModifyInstanceName 且不报错
13+
- [x] 3.2 执行 `go test ./tencentcloud/services/cynosdb/ -run "TestUnitCynosdbReadonlyInstance_UpdateInstanceName" -v -count=1 -gcflags="all=-l"` 确保测试通过
14+
15+
## 4. 文档与 changelog
16+
17+
- [x] 4.1 更新 `website/docs/r/cynosdb_readonly_instance.html.markdown`,移除 `instance_name``ForceNew` 标记(由 `make doc` 在收尾阶段生成,本任务仅准备 .md 源文件)
18+
- [x] 4.2 更新 `.changelog/4319.txt`,将变更描述改为 `resource/tencentcloud_cynosdb_readonly_instance: support instance_name modification via ModifyInstanceName API`(enhancement)
19+
20+
## 5. 验证
21+
22+
- [x] 5.1 确认所有修改的 Go 文件可正确编译(由后续流程的 go build 验证)
23+
24+
## 6. 额外修复
25+
26+
- [x] 6.1 修复 `resource_tc_cynosdb_cluster_v2_test.go` 中 sweeper 名称冲突(master 预先存在的问题:与 `resource_tc_cynosdb_cluster_test.go` 注册了同名 `tencentcloud_cynosdb` sweeper,导致 `log.Fatalf` 阻断整个包的测试运行),将 v2 的 sweeper 重命名为 `tencentcloud_cynosdb_v2`
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# cynosdb-readonly-instance-name-modify Specification
2+
3+
## Purpose
4+
TBD - created by archiving change add-cynosdb-readonly-instance-name-modify. Update Purpose after archive.
5+
## Requirements
6+
### Requirement: instance_name supports in-place update
7+
8+
The `tencentcloud_cynosdb_readonly_instance` resource SHALL allow the `instance_name` field to be updated in-place without recreating the resource. When `instance_name` changes, the provider SHALL call the `ModifyInstanceName` API to update the instance name on the cloud, then refresh state.
9+
10+
#### Scenario: Update instance_name triggers ModifyInstanceName API
11+
12+
- **WHEN** the user updates `instance_name` in the Terraform configuration for an existing `tencentcloud_cynosdb_readonly_instance`
13+
- **THEN** the provider SHALL call `ModifyInstanceName` with the instance ID and the new instance name, and SHALL NOT recreate the resource
14+
15+
#### Scenario: instance_name is no longer ForceNew
16+
17+
- **WHEN** the schema for `instance_name` is inspected
18+
- **THEN** the field SHALL be `Required` and `String`, and SHALL NOT have `ForceNew` set
19+
20+
#### Scenario: Read reflects updated instance_name
21+
22+
- **WHEN** `ModifyInstanceName` succeeds and a subsequent Read is performed
23+
- **THEN** the provider SHALL set `instance_name` in state to the value returned by the `DescribeInstanceById` API
24+
25+
#### Scenario: ModifyInstanceName failure is retried
26+
27+
- **WHEN** the `ModifyInstanceName` API returns an error
28+
- **THEN** the provider SHALL wrap the error with `tccommon.RetryError` and retry within `WriteRetryTimeout`
29+

tencentcloud/services/cynosdb/resource_tc_cynosdb_cluster_v2_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ import (
1717
)
1818

1919
func init() {
20-
resource.AddTestSweepers("tencentcloud_cynosdb", &resource.Sweeper{
21-
Name: "tencentcloud_cynosdb",
20+
resource.AddTestSweepers("tencentcloud_cynosdb_v2", &resource.Sweeper{
21+
Name: "tencentcloud_cynosdb_v2",
2222
F: func(r string) error {
2323
logId := tccommon.GetLogId(tccommon.ContextNil)
2424
ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId)

tencentcloud/services/cynosdb/resource_tc_cynosdb_readonly_instance.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ func ResourceTencentCloudCynosdbReadonlyInstance() *schema.Resource {
2727
"instance_name": {
2828
Type: schema.TypeString,
2929
Required: true,
30-
ForceNew: true,
31-
Description: "Name of instance.",
30+
Description: "Instance name.",
3231
},
3332
"force_delete": {
3433
Type: schema.TypeBool,
@@ -223,6 +222,14 @@ func resourceTencentCloudCynosdbReadonlyInstanceUpdate(d *schema.ResourceData, m
223222

224223
d.Partial(true)
225224

225+
if d.HasChange("instance_name") {
226+
instanceName := d.Get("instance_name").(string)
227+
err := cynosdbService.ModifyInstanceName(ctx, instanceId, instanceName)
228+
if err != nil {
229+
return err
230+
}
231+
}
232+
226233
if d.HasChange("instance_cpu_core") || d.HasChange("instance_memory_size") {
227234
cpu := int64(d.Get("instance_cpu_core").(int))
228235
memory := int64(d.Get("instance_memory_size").(int))

0 commit comments

Comments
 (0)