Skip to content
Open
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
3 changes: 3 additions & 0 deletions .changelog/4156.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-resource
tencentcloud_ga2_global_accelerator
```
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -958,6 +958,7 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.89/go.mod h
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.90/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.94/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.95/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.101/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.102 h1:3n7BpLOPnE9Rv3Y9Jxgl/XaQX3GzktO+dEaAbtVbjSk=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.102/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/config v1.3.80 h1:chnsNBeJn3MieFLki4hpbzoml5NiTvLVzOTqYRVxQho=
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-05-27
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
## Context

当前 Terraform Provider 已有 GA2 服务的基础设施:
- `tencentcloud/services/ga2/service_tencentcloud_ga2.go` 提供了 `Ga2Service`、`WaitForGa2TaskFinish` 等公共方法
- `tencentcloud/services/ga2/resource_tc_ga2_endpoint_group.go` 是同产品下已有的资源实现,可作为模式参考
- vendor 中已包含 `github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ga2/v20250115` SDK

所有 GA2 写操作(Create/Modify/Delete)均为异步接口,返回 TaskId,需通过 `DescribeTaskResult` 轮询任务状态直到 SUCCESS。已有的 `WaitForGa2TaskFinish` 方法可直接复用。

## Goals / Non-Goals

**Goals:**
- 实现 `tencentcloud_ga2_global_accelerator` 资源的完整 CRUD
- 复用已有的 `Ga2Service` 和 `WaitForGa2TaskFinish` 异步等待机制
- 支持 Import 功能(通过 global_accelerator_id 导入)
- 在 service 层新增 `DescribeGa2GlobalAcceleratorById` 方法供 Read 使用
- 使用 gomonkey mock 方式编写单元测试

**Non-Goals:**
- 不实现 tags 的独立更新(ModifyGlobalAccelerator 不支持 tags 参数)
- 不实现 instance_charge_type 的变更(仅创建时指定)
- 不实现数据源(本次仅新增 RESOURCE_KIND_GENERAL 资源)

## Decisions

### 1. 资源 ID 使用 GlobalAcceleratorId

**决策**: 使用 `CreateGlobalAccelerator` 返回的 `GlobalAcceleratorId` 作为 Terraform 资源 ID(单一 ID,无需复合 ID)。

**理由**: 该 ID 是全球加速实例的唯一标识,Modify 和 Delete 接口均只需此 ID。

### 2. 异步操作使用已有的 WaitForGa2TaskFinish

**决策**: Create/Modify/Delete 操作完成后,调用 `Ga2Service.WaitForGa2TaskFinish` 等待任务完成。

**理由**: 该方法已在 endpoint_group 资源中验证可用,使用 `DescribeTaskResult` 接口轮询,避免重复实现。

### 3. instance_charge_type 和 tags 设为 ForceNew

**决策**: `instance_charge_type` 和 `tags` 字段设为 ForceNew,因为 ModifyGlobalAccelerator 接口不支持修改这两个字段。

**理由**: 云 API 的 Modify 接口仅支持 Name、Description、CrossBorderType、CrossBorderPromiseFlag 四个字段的修改。

### 4. Read 方法通过 DescribeGlobalAccelerators + Filter 实现

**决策**: 在 service 层新增 `DescribeGa2GlobalAcceleratorById` 方法,使用 `global-accelerator-id` Filter 查询单个实例。

**理由**: DescribeGlobalAccelerators 接口支持通过 Filters 按 ID 过滤,与 endpoint_group 的模式一致。

### 5. Schema 中声明 Timeouts

**决策**: 为 Create/Update/Delete 声明 20 分钟超时,与 endpoint_group 资源保持一致。

**理由**: 异步操作需要超时控制,20 分钟是同产品其他资源的标准超时时间。

## Risks / Trade-offs

- [Tags 不可更新] → 设为 ForceNew,用户修改 tags 会触发资源重建。这是 API 限制,无法规避。
- [instance_charge_type 不可更新] → 设为 ForceNew,与 API 能力对齐。
- [异步操作可能超时] → 使用 schema Timeouts 机制,用户可自定义超时时间。
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
## Why

TencentCloud Global Accelerator (GA2) 产品需要通过 Terraform 管理全球加速实例的生命周期(创建、查询、修改、删除),当前 provider 中尚未提供该资源,用户无法通过 IaC 方式管理 GA2 全球加速实例。

## What Changes

- 新增 Terraform 资源 `tencentcloud_ga2_global_accelerator`,支持全球加速实例的完整 CRUD 生命周期管理
- 支持创建时指定名称、计费模式、描述、跨境类型、跨境承诺标志和标签
- 支持修改名称、描述、跨境类型和跨境承诺标志
- 支持删除全球加速实例
- 所有写操作(Create/Modify/Delete)为异步接口,需轮询实例状态直到操作完成
- 在 provider.go 和 provider.md 中注册新资源

## Capabilities

### New Capabilities

- `ga2-global-accelerator-resource`: 全球加速实例的 CRUD 资源管理,包括创建、读取、更新、删除操作,以及异步操作的状态轮询

### Modified Capabilities

(无)

## Impact

- 新增文件: `tencentcloud/services/ga2/resource_tc_ga2_global_accelerator.go`
- 新增文件: `tencentcloud/services/ga2/resource_tc_ga2_global_accelerator_test.go`
- 新增文件: `tencentcloud/services/ga2/resource_tc_ga2_global_accelerator.md`
- 修改文件: `tencentcloud/provider.go`(注册资源)
- 修改文件: `tencentcloud/provider.md`(添加资源文档引用)
- 可能修改: `tencentcloud/services/ga2/service_tencentcloud_ga2.go`(添加服务层方法)
- 依赖: `github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ga2/v20250115`(已在 vendor 中)
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
## ADDED Requirements

### Requirement: Create global accelerator instance

The system SHALL provide a Terraform resource `tencentcloud_ga2_global_accelerator` that creates a GA2 global accelerator instance by calling the `CreateGlobalAccelerator` API with the following parameters:
- `name` (Required, string): Instance name, max 60 bytes
- `instance_charge_type` (Optional, string, ForceNew): Billing mode, valid values: `PREPAID`, `POSTPAID`. Default: `POSTPAID`
- `description` (Optional, string): Description, max 100 bytes
- `cross_border_type` (Optional, string): Cross-border type, valid values: `HighQuality`, `Unicom`
- `cross_border_promise_flag` (Optional, bool): Cross-border service promise flag
- `tags` (Optional, map of string, ForceNew): Tag information

After successful creation, the system SHALL set the resource ID to the returned `GlobalAcceleratorId` and wait for the async task to complete by polling `DescribeTaskResult` until status is SUCCESS.

#### Scenario: Successful creation with required parameters only

- **WHEN** user provides a valid `name` in the Terraform configuration
- **THEN** the system calls `CreateGlobalAccelerator` API, sets the resource ID to the returned `GlobalAcceleratorId`, waits for the task to complete, and reads back the resource state

#### Scenario: Successful creation with all parameters

- **WHEN** user provides `name`, `instance_charge_type`, `description`, `cross_border_type`, `cross_border_promise_flag`, and `tags`
- **THEN** the system calls `CreateGlobalAccelerator` API with all provided parameters, sets the resource ID, waits for the task to complete, and reads back the resource state

#### Scenario: Creation fails with nil response

- **WHEN** the `CreateGlobalAccelerator` API returns a nil response or nil `GlobalAcceleratorId`
- **THEN** the system returns a NonRetryableError

### Requirement: Read global accelerator instance

The system SHALL read the global accelerator instance state by calling `DescribeGlobalAccelerators` API with a `global-accelerator-id` filter. The system SHALL set the following computed attributes from the response:
- `name` (string)
- `description` (string)
- `instance_charge_type` (string)
- `cross_border_type` (string)
- `create_time` (Computed, string)
- `state` (Computed, string)
- `status` (Computed, string)
- `ddos_id` (Computed, string)
- `cname` (Computed, string)

#### Scenario: Successful read

- **WHEN** the resource exists and `DescribeGlobalAccelerators` returns a matching instance
- **THEN** the system sets all computed and configured attributes from the `GlobalAcceleratorSet` response

#### Scenario: Resource not found

- **WHEN** `DescribeGlobalAccelerators` returns an empty `GlobalAcceleratorSet` for the given ID
- **THEN** the system removes the resource from state (calls `d.SetId("")`)

### Requirement: Update global accelerator instance

The system SHALL update the global accelerator instance by calling `ModifyGlobalAccelerator` API when any of the following fields change: `name`, `description`, `cross_border_type`, `cross_border_promise_flag`. After the API call, the system SHALL wait for the async task to complete.

The fields `instance_charge_type` and `tags` are ForceNew and SHALL NOT be included in the update request.

#### Scenario: Update name and description

- **WHEN** user changes `name` or `description` in the Terraform configuration
- **THEN** the system calls `ModifyGlobalAccelerator` with the new values and the `GlobalAcceleratorId`, waits for the task to complete, and reads back the resource state

#### Scenario: Update cross-border settings

- **WHEN** user changes `cross_border_type` or `cross_border_promise_flag`
- **THEN** the system calls `ModifyGlobalAccelerator` with the updated values, waits for the task to complete, and reads back the resource state

### Requirement: Delete global accelerator instance

The system SHALL delete the global accelerator instance by calling `DeleteGlobalAccelerator` API with the `GlobalAcceleratorId`. After the API call, the system SHALL wait for the async task to complete.

#### Scenario: Successful deletion

- **WHEN** user destroys the Terraform resource
- **THEN** the system calls `DeleteGlobalAccelerator` with the resource ID, waits for the task to complete

#### Scenario: Resource already deleted

- **WHEN** `DeleteGlobalAccelerator` returns a resource not found error
- **THEN** the system treats the deletion as successful (no error)

### Requirement: Import global accelerator instance

The system SHALL support importing an existing global accelerator instance using its `GlobalAcceleratorId`.

#### Scenario: Successful import

- **WHEN** user runs `terraform import tencentcloud_ga2_global_accelerator.example <global_accelerator_id>`
- **THEN** the system reads the instance state using `DescribeGlobalAccelerators` and populates all attributes

### Requirement: Register resource in provider

The system SHALL register `tencentcloud_ga2_global_accelerator` in `tencentcloud/provider.go` resource map and add the corresponding entry in `tencentcloud/provider.md`.

#### Scenario: Resource is available after registration

- **WHEN** the provider is initialized
- **THEN** `tencentcloud_ga2_global_accelerator` is available as a valid resource type
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
## 1. Service Layer

- [x] 1.1 Add `DescribeGa2GlobalAcceleratorById` method to `tencentcloud/services/ga2/service_tencentcloud_ga2.go` that queries a single global accelerator instance by ID using `DescribeGlobalAccelerators` API with `global-accelerator-id` filter

## 2. Resource Implementation

- [x] 2.1 Create `tencentcloud/services/ga2/resource_tc_ga2_global_accelerator.go` with schema definition including all input fields (`name`, `instance_charge_type`, `description`, `cross_border_type`, `cross_border_promise_flag`, `tags`) and computed fields (`create_time`, `state`, `status`, `ddos_id`, `cname`), with Timeouts block and Import support
- [x] 2.2 Implement `resourceTencentCloudGa2GlobalAcceleratorCreate` function that calls `CreateGlobalAccelerator` API, validates response, sets resource ID, and waits for async task completion via `WaitForGa2TaskFinish`
- [x] 2.3 Implement `resourceTencentCloudGa2GlobalAcceleratorRead` function that calls `DescribeGa2GlobalAcceleratorById`, handles not-found case, and sets all attributes from response
- [x] 2.4 Implement `resourceTencentCloudGa2GlobalAcceleratorUpdate` function that calls `ModifyGlobalAccelerator` API with changed fields (`name`, `description`, `cross_border_type`, `cross_border_promise_flag`) and waits for async task completion
- [x] 2.5 Implement `resourceTencentCloudGa2GlobalAcceleratorDelete` function that calls `DeleteGlobalAccelerator` API and waits for async task completion

## 3. Provider Registration

- [x] 3.1 Register `tencentcloud_ga2_global_accelerator` resource in `tencentcloud/provider.go` resource map
- [x] 3.2 Add `tencentcloud_ga2_global_accelerator` entry in `tencentcloud/provider.md`

## 4. Documentation

- [x] 4.1 Create `tencentcloud/services/ga2/resource_tc_ga2_global_accelerator.md` with Example Usage and Import sections

## 5. Unit Tests

- [x] 5.1 Create `tencentcloud/services/ga2/resource_tc_ga2_global_accelerator_test.go` with gomonkey-based unit tests covering Create, Read, Update, and Delete operations
99 changes: 99 additions & 0 deletions openspec/specs/ga2-global-accelerator-resource/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
## ADDED Requirements

### Requirement: Create global accelerator instance

The system SHALL provide a Terraform resource `tencentcloud_ga2_global_accelerator` that creates a GA2 global accelerator instance by calling the `CreateGlobalAccelerator` API with the following parameters:
- `name` (Required, string): Instance name, max 60 bytes
- `instance_charge_type` (Optional, string, ForceNew): Billing mode, valid values: `PREPAID`, `POSTPAID`. Default: `POSTPAID`
- `description` (Optional, string): Description, max 100 bytes
- `cross_border_type` (Optional, string): Cross-border type, valid values: `HighQuality`, `Unicom`
- `cross_border_promise_flag` (Optional, bool): Cross-border service promise flag
- `tags` (Optional, map of string, ForceNew): Tag information

After successful creation, the system SHALL set the resource ID to the returned `GlobalAcceleratorId` and wait for the async task to complete by polling `DescribeTaskResult` until status is SUCCESS.

#### Scenario: Successful creation with required parameters only

- **WHEN** user provides a valid `name` in the Terraform configuration
- **THEN** the system calls `CreateGlobalAccelerator` API, sets the resource ID to the returned `GlobalAcceleratorId`, waits for the task to complete, and reads back the resource state

#### Scenario: Successful creation with all parameters

- **WHEN** user provides `name`, `instance_charge_type`, `description`, `cross_border_type`, `cross_border_promise_flag`, and `tags`
- **THEN** the system calls `CreateGlobalAccelerator` API with all provided parameters, sets the resource ID, waits for the task to complete, and reads back the resource state

#### Scenario: Creation fails with nil response

- **WHEN** the `CreateGlobalAccelerator` API returns a nil response or nil `GlobalAcceleratorId`
- **THEN** the system returns a NonRetryableError

### Requirement: Read global accelerator instance

The system SHALL read the global accelerator instance state by calling `DescribeGlobalAccelerators` API with a `global-accelerator-id` filter. The system SHALL set the following computed attributes from the response:
- `name` (string)
- `description` (string)
- `instance_charge_type` (string)
- `cross_border_type` (string)
- `create_time` (Computed, string)
- `state` (Computed, string)
- `status` (Computed, string)
- `ddos_id` (Computed, string)
- `cname` (Computed, string)

#### Scenario: Successful read

- **WHEN** the resource exists and `DescribeGlobalAccelerators` returns a matching instance
- **THEN** the system sets all computed and configured attributes from the `GlobalAcceleratorSet` response

#### Scenario: Resource not found

- **WHEN** `DescribeGlobalAccelerators` returns an empty `GlobalAcceleratorSet` for the given ID
- **THEN** the system removes the resource from state (calls `d.SetId("")`)

### Requirement: Update global accelerator instance

The system SHALL update the global accelerator instance by calling `ModifyGlobalAccelerator` API when any of the following fields change: `name`, `description`, `cross_border_type`, `cross_border_promise_flag`. After the API call, the system SHALL wait for the async task to complete.

The fields `instance_charge_type` and `tags` are ForceNew and SHALL NOT be included in the update request.

#### Scenario: Update name and description

- **WHEN** user changes `name` or `description` in the Terraform configuration
- **THEN** the system calls `ModifyGlobalAccelerator` with the new values and the `GlobalAcceleratorId`, waits for the task to complete, and reads back the resource state

#### Scenario: Update cross-border settings

- **WHEN** user changes `cross_border_type` or `cross_border_promise_flag`
- **THEN** the system calls `ModifyGlobalAccelerator` with the updated values, waits for the task to complete, and reads back the resource state

### Requirement: Delete global accelerator instance

The system SHALL delete the global accelerator instance by calling `DeleteGlobalAccelerator` API with the `GlobalAcceleratorId`. After the API call, the system SHALL wait for the async task to complete.

#### Scenario: Successful deletion

- **WHEN** user destroys the Terraform resource
- **THEN** the system calls `DeleteGlobalAccelerator` with the resource ID, waits for the task to complete

#### Scenario: Resource already deleted

- **WHEN** `DeleteGlobalAccelerator` returns a resource not found error
- **THEN** the system treats the deletion as successful (no error)

### Requirement: Import global accelerator instance

The system SHALL support importing an existing global accelerator instance using its `GlobalAcceleratorId`.

#### Scenario: Successful import

- **WHEN** user runs `terraform import tencentcloud_ga2_global_accelerator.example <global_accelerator_id>`
- **THEN** the system reads the instance state using `DescribeGlobalAccelerators` and populates all attributes

### Requirement: Register resource in provider

The system SHALL register `tencentcloud_ga2_global_accelerator` in `tencentcloud/provider.go` resource map and add the corresponding entry in `tencentcloud/provider.md`.

#### Scenario: Resource is available after registration

- **WHEN** the provider is initialized
- **THEN** `tencentcloud_ga2_global_accelerator` is available as a valid resource type
1 change: 1 addition & 0 deletions tencentcloud/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -1722,6 +1722,7 @@ func Provider() *schema.Provider {
"tencentcloud_dayu_l7_rule_v2": dayuv2.ResourceTencentCloudDayuL7RuleV2(),
"tencentcloud_dayu_eip": dayuv2.ResourceTencentCloudDayuEip(),
"tencentcloud_ga2_endpoint_group": ga2.ResourceTencentCloudGa2EndpointGroup(),
"tencentcloud_ga2_global_accelerator": ga2.ResourceTencentCloudGa2GlobalAccelerator(),
"tencentcloud_gaap_proxy": gaap.ResourceTencentCloudGaapProxy(),
"tencentcloud_gaap_realserver": gaap.ResourceTencentCloudGaapRealserver(),
"tencentcloud_gaap_layer4_listener": gaap.ResourceTencentCloudGaapLayer4Listener(),
Expand Down
5 changes: 5 additions & 0 deletions tencentcloud/provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -2624,6 +2624,11 @@ tencentcloud_igtm_strategy
tencentcloud_igtm_package_instance
tencentcloud_igtm_package_task

Global Accelerator(GA2)
Resource
tencentcloud_ga2_endpoint_group
tencentcloud_ga2_global_accelerator

VCube
Resource
tencentcloud_vcube_application_and_video
Expand Down
Loading
Loading