Terraform Version
Terraform v1.12.0
on darwin_amd64
+ provider registry.terraform.io/tencentcloudstack/tencentcloud v1.83.9
Affected Resource(s)
tencentcloud_route_table_entry
Terraform Configuration Files
resource "tencentcloud_route_table_entry" "this" {
route_table_id = tencentcloud_route_table.this.id
destination_cidr_block = "0.0.0.0/0"
next_type = "HAVIP"
next_hub = "havip-xxxxxxxx"
description = "example-route"
}
Expected Behavior
terraform apply 成功后,再次执行 terraform plan 应输出:
No changes. Your infrastructure matches the configuration.
Actual Behavior
terraform apply 执行成功(Apply complete! Resources: 1 added, 0 changed, 0 destroyed.),再次执行 terraform plan 输出 Plan: 1 to add, 0 to change, 1 to destroy.,提示 tencentcloud_route_table_entry 需要 replace:
# tencentcloud_route_table_entry.this must be replaced
-/+ resource "tencentcloud_route_table_entry" "this" {
~ next_hub = "intranat-xxxxxxxx" -> "havip-xxxxxxxx" # forces replacement
~ next_type = "INTRANAT" -> "HAVIP" # forces replacement
}
terraform state show 证明 state 中实际记录的是 API 返回值,而非用户配置值:
# tencentcloud_route_table_entry.this:
resource "tencentcloud_route_table_entry" "this" {
destination_cidr_block = "0.0.0.0/0"
next_hub = "intranat-xxxxxxxx" # API 返回值,非用户配置的 havip-xxxxxxxx
next_type = "INTRANAT" # API 返回值,非用户配置的 HAVIP
route_table_id = "rtb-xxxxxxxx"
id = "538005.rtb-xxxxxxxx"
}
根本原因:腾讯云后端在创建 next_type = "HAVIP" 的路由条目时,会将其归一化:next_type 被转换为 "INTRANAT",next_hub 从 HAVIP ID(havip-*)被替换为对应的内网 NAT 资源 ID(intranat-*)。Provider 的 Read 逻辑直接将 API 返回值写回 state,未做反向映射,导致 state 与用户配置永久不一致。由于 next_type 和 next_hub 均为 ForceNew 字段,每次 plan 都会触发 destroy + create,形成无法收敛的循环。
Steps to Reproduce
- 配置
tencentcloud_route_table_entry,设置 next_type = "HAVIP",next_hub 为有效的 HAVIP ID
- 执行
terraform apply,apply 成功
- 执行
terraform state show tencentcloud_route_table_entry.this,观察到 next_type 已变为 "INTRANAT",next_hub 已变为 intranat-* 前缀的 ID
- 再次执行
terraform plan,出现 forces replacement 变更,且永远无法收敛
Important Factoids
- HAVIP 路由在腾讯云底层由 INTRANAT(内网 NAT)承载,API 创建后会自动将
next_type 从 HAVIP 转换为 INTRANAT,并将 next_hub 替换为对应的 INTRANAT 资源 ID
- Provider Read 逻辑未对此做反向映射,将 API 返回的归一化值直接写入 state
next_type 与 next_hub 均为 ForceNew 字段,导致每次 plan 均触发 replace,配置永远无法收敛
References
Terraform Version
Affected Resource(s)
tencentcloud_route_table_entryTerraform Configuration Files
Expected Behavior
terraform apply成功后,再次执行terraform plan应输出:Actual Behavior
terraform apply执行成功(Apply complete! Resources: 1 added, 0 changed, 0 destroyed.),再次执行terraform plan输出Plan: 1 to add, 0 to change, 1 to destroy.,提示tencentcloud_route_table_entry需要 replace:terraform state show证明 state 中实际记录的是 API 返回值,而非用户配置值:根本原因:腾讯云后端在创建
next_type = "HAVIP"的路由条目时,会将其归一化:next_type被转换为"INTRANAT",next_hub从 HAVIP ID(havip-*)被替换为对应的内网 NAT 资源 ID(intranat-*)。Provider 的 Read 逻辑直接将 API 返回值写回 state,未做反向映射,导致 state 与用户配置永久不一致。由于next_type和next_hub均为 ForceNew 字段,每次 plan 都会触发 destroy + create,形成无法收敛的循环。Steps to Reproduce
tencentcloud_route_table_entry,设置next_type = "HAVIP",next_hub为有效的 HAVIP IDterraform apply,apply 成功terraform state show tencentcloud_route_table_entry.this,观察到next_type已变为"INTRANAT",next_hub已变为intranat-*前缀的 IDterraform plan,出现forces replacement变更,且永远无法收敛Important Factoids
next_type从HAVIP转换为INTRANAT,并将next_hub替换为对应的 INTRANAT 资源 IDnext_type与next_hub均为 ForceNew 字段,导致每次 plan 均触发 replace,配置永远无法收敛References