实战 | 用腾讯云 AI 助手逆向导出 Terraform:存量 CVM / COS / VPC 资源一键代码化
适用读者:中高级运维、后端开发、云架构师
关键词:Terraform · 存量资源导入 · AI 生成 HCL · 逆向 IaC · 资源依赖 · 避坑指南
全文约 15 分钟阅读,附可复制提示词 与资源识别失败避坑清单,建议收藏。
0. 一句话背景
很多团队把 Terraform 用起来了,但存量 云资源(控制台时代手点出来的 CVM、COS、VPC)一直游离在 IaC 之外。要么不敢动,要么靠人肉照着控制台抄一份 HCL------抄完还不敢 apply。本文给出第三条路:让腾讯云 AI 代码助手(CodeBuddy)读懂控制台存量资源,辅助生成 Terraform HCL,再用 terraform import 把资源纳入 State,最后人工修正 AI 输出的关键字段,完成真正的"逆向 IaC"。
1. 先想清楚:存量资源代码化,为什么这么难?
先看三条路径的对比,避免一上来就踩"伪 IaC"的坑。
| 路径 | 做法 | 痛点 |
|---|---|---|
| ① 全量重写 | 按业务重新设计 TF 模板,原地重建资源 | 停机窗口、数据迁移、变更审批,基本只适用于灰度新业务 |
| ② 纯手动 import | 控制台抄 ID → terraform import → 手写补齐配置 |
资源一多就变成体力活,字段差异全靠肉眼,容易漏 |
| ③ AI 辅助逆向(本文) | AI 生成 HCL → import 入 State → 对照 state show 修正 → plan 归零 |
需要掌握 AI 输出的修正方法,否则 AI 会把坑也一起抄进来 |
核心认知 :terraform import 只能把资源导入 State ,配置文件(HCL)还是要人写或 AI 写。所以"逆向 IaC"= AI 写配置 + import 拉状态 + 人工修正 diff 三步闭环,缺一不可。
2. 前置准备(10 分钟)
2.1 环境清单
bash
# 1. 安装 Terraform(≥ 1.5,推荐 1.6+)
terraform version
# 2. 准备腾讯云凭据(建议子账号 + 最小权限策略,别用主账号密钥)
# Windows PowerShell:
$env:TENCENTCLOUD_SECRET_ID = "AKIDxxxxxxxxxxxxxxxx"
$env:TENCENTCLOUD_SECRET_KEY = "xxxxxxxxxxxxxxxxxxxxxxxx"
# macOS / Linux:
# export TENCENTCLOUD_SECRET_ID="..."
# export TENCENTCLOUD_SECRET_KEY="..."
2.2 最小工程骨架
hcl
# versions.tf
terraform {
required_version = ">= 1.5"
required_providers {
tencentcloud = {
source = "tencentcloudstack/tencentcloud"
version = "~> 1.79"
}
}
}
# provider.tf
provider "tencentcloud" {
region = "ap-guangzhou" # 按你资源实际所在区域改
}
小技巧:先用
tccli(腾讯云 CLI)或控制台确认资源真实所在 region,AI 猜的 region 常常是错的。
3. 实战一:存量 CVM 实例逆向
3.1 给 AI 的提示词(可直接复制)
把下面这段发给腾讯云 AI 代码助手(CodeBuddy 对话窗口 / IDE 内对话):
text
我有一台存量腾讯云 CVM 实例,需要纳入 Terraform 管理。
已知信息:
- 实例 ID:ins-web-prod-01
- 所在区域:ap-guangzhou
- 实例名称:web-prod-01
- 项目:默认项目
请帮我:
1. 使用 tencentcloudstack/tencentcloud provider(1.79.x)生成该实例的 resource "tencentcloud_instance" HCL 配置;
2. 字段必须严格使用 provider 文档里的 HCL 属性名,不要使用 API 的驼峰字段名;
3. 只输出必要的核心字段(image_id / instance_type / 系统盘 / 网络 / 安全组 / key),不要臆造我没有提供的值;
4. 同时给出对应的 terraform import 命令。
3.2 AI 输出(示意)
hcl
resource "tencentcloud_instance" "web_prod_01" {
instance_name = "web-prod-01"
availability_zone = "ap-guangzhou-3"
image_id = "img-xxxxxxxxxxxx"
instance_type = "S5.SMALL1"
system_disk_type = "CLOUD_SSD"
system_disk_size = 50
internet_max_bandwidth_out = 5
allocate_public_ip = true
security_groups = ["sg-xxxxxxxx"]
vpc_id = "vpc-xxxxxxxx"
subnet_id = "subnet-xxxxxxxx"
key_name = "key-xxxxxxxx"
tags = {
"env" = "prod"
}
}
bash
terraform import tencentcloud_instance.web_prod_01 ins-web-prod-01
3.3 坑 1:image_id 识别失败(AI 最常见的翻车点)
- 现象 :控制台 CVM 详情页只显示镜像名称 (如 "TencentOS Server 3.1"),不显示
img-xxx形式的镜像 ID。AI 会直接编一个看似合理的img-xxxxxxxx。 - 后果 :import 后
terraform plan报image_id变更;严重时 apply 会把实例重装系统。 - 解法:用 data source 查询真实镜像 ID,再把 ID 固化进配置:
hcl
data "tencentcloud_images" "this" {
image_name_regex = "TencentOS Server 3.1"
}
# 核对:terraform console 里执行
# data.tencentcloud_images.this.image_id
原则 :
image_id、instance_type、磁盘类型这类"详情页看不到、但变了会动资源"的字段,必须用 data source / CLI 核实,禁止让 AI 猜。
3.4 坑 2:预付费(包年包月)实例的隐藏字段
- 存量实例如果是包年包月 ,AI 往往漏掉
instance_charge_type = "PREPAID"和instance_charge_type_prepaid块,导致 plan 出现"会退费重购"级别的差异。 - 核实命令:
bash
tccli cvm DescribeInstances --InstanceIds '["ins-web-prod-01"]' | findstr InstanceChargeType
修正后:
hcl
resource "tencentcloud_instance" "web_prod_01" {
# ... 上述字段 ...
instance_charge_type = "PREPAID"
instance_charge_type_prepaid {
period = 1 # 单位:月
renew_flag = "NOTIFY_AND_AUTO_RENEW"
}
}
4. 实战二:存量 COS Bucket 逆向
4.1 提示词(可直接复制)
text
我有一台存量腾讯云 COS 存储桶,需要纳入 Terraform 管理。
已知信息:
- Bucket 名称:app-backup-1250000000(注意:这是全局唯一名称,带 APPID 后缀)
- 区域:ap-guangzhou
- 访问权限:私有读写
- 开启了版本控制,并有一条 30 天自动清理历史版本的规则
请生成:
1. resource "tencentcloud_cos_bucket" 的 HCL,覆盖 acl、版本控制、生命周期规则;
2. 不要生成桶内已有对象的管理代码(对象不归 TF 管,避免误删数据);
3. 给出 terraform import 命令。
4.2 坑 3:acl 的默认值 diff
- AI 不写
acl时,provider 默认值可能是private,而存量桶若是public-read,plan 会一直有差异。 - 解法 :显式声明
acl,并确认桶真实权限(COS 控制台 → 权限管理 → 存储桶访问权限,或用tccli cos/coscmd核实)。
hcl
resource "tencentcloud_cos_bucket" "app_backup" {
bucket = "app-backup-1250000000"
acl = "private" # 与桶实际权限保持一致
versioning_enable = true
lifecycle_rule {
id = "clean-history"
filter = ""
expiration {
days = 30
}
}
}
bash
terraform import tencentcloud_cos_bucket.app_backup app-backup-1250000000
4.3 坑 4:AI 给 COS 编造 region 参数
- 经典错误输出:
hcl
resource "tencentcloud_cos_bucket" "app_backup" {
bucket = "app-backup-1250000000"
region = "ap-guangzhou" # ← 报错:Unsupported argument
}
Error: Unsupported argument
on main.tf line 12, in resource "tencentcloud_cos_bucket" "app_backup":
12: region = "ap-guangzhou"
An argument named "region" is not expected here.
- 原因 :COS 的 region 由
provider "tencentcloud"的region决定,bucket 资源本身没有region属性。 - 解法 :删掉该行;如果桶在多区域,就拆多个
provider别名(alias)而不是在资源里写 region。
规律 :AI 会把"控制台里能看到的配置"当成"HCL 属性名"。遇到
Unsupported argument,优先查 provider 文档确认字段,而不是让 AI 换个写法硬编。
5. 实战三:VPC + 子网 + 安全组(资源依赖场景)
这是"资源依赖报错"的高发区,也是最能体现 AI 价值的地方------一次生成一整套关联资源。
5.1 提示词(可直接复制)
text
我有以下存量腾讯云网络资源,全部要纳入 Terraform 管理,请生成完整 HCL 并给出 import 命令:
1. VPC:vpc-prod(vpc-xxxxxxxx),CIDR 10.0.0.0/16,默认路由表;
2. 子网:subnet-app-a(subnet-xxxxxxxx),CIDR 10.0.1.0/24,可用区 ap-guangzhou-3,属于上述 VPC;
3. 安全组:sg-web(sg-xxxxxxxx),属于上述 VPC,入站规则允许 443 来自 0.0.0.0/0、22 来自办公网段 10.20.0.0/16;
要求:
- 资源之间用显式引用(tencentcloud_vpc.vpc_prod.id 这种写法),不要硬编码 ID;
- 字段严格符合 tencentcloudstack/tencentcloud 1.79.x 的 HCL schema;
- 输出顺序:vpc → subnet → security_group → security_group_rule。
5.2 AI 输出(示意,依赖用引用串联)
hcl
resource "tencentcloud_vpc" "vpc_prod" {
name = "vpc-prod"
cidr_block = "10.0.0.0/16"
}
resource "tencentcloud_subnet" "subnet_app_a" {
vpc_id = tencentcloud_vpc.vpc_prod.id
name = "subnet-app-a"
cidr_block = "10.0.1.0/24"
availability_zone = "ap-guangzhou-3"
}
resource "tencentcloud_security_group" "sg_web" {
name = "sg-web"
description = "web 安全组"
vpc_id = tencentcloud_vpc.vpc_prod.id
}
resource "tencentcloud_security_group_rule" "https" {
security_group_id = tencentcloud_security_group.sg_web.id
type = "ingress"
cidr_ip = "0.0.0.0/0"
ip_protocol = "TCP"
port_range = "443"
policy = "ACCEPT"
}
resource "tencentcloud_security_group_rule" "ssh" {
security_group_id = tencentcloud_security_group.sg_web.id
type = "ingress"
cidr_ip = "10.20.0.0/16"
ip_protocol = "TCP"
port_range = "22"
policy = "ACCEPT"
}
5.3 坑 5:import 阶段没有依赖报错,apply 阶段才爆
-
现象 :
terraform import逐个执行都成功(import 只写 State、不校验配置依赖);但terraform plan/apply时报错:Error: creating TencentCloud CVM instance: TencentCloudSDKError
Code=InvalidParameterValue.SubnetNotExist
Message=subnet 'subnet-xxxxxxxx' not belong to vpc 'vpc-xxxxxxxx' -
原因 :AI 生成的子网/安全组虽然字段齐全,但实际存量关系与你声明的引用对不上(例如安全组实际挂在另一个 VPC 下),引用关系一旦写错,Terraform 会按错误的依赖图去 apply。
-
解法 :先查关系,再让 AI 生成。用 data source 把真实归属查出来,作为"事实输入"喂给 AI:
hcl
data "tencentcloud_vpc" "vpc_prod" {
name = "vpc-prod"
}
data "tencentcloud_subnets" "app" {
vpc_id = data.tencentcloud_vpc.vpc_prod.id
}
data "tencentcloud_security_groups" "sg_web" {
name = "sg-web"
}
然后核对输出里的 vpc_id、subnet_id 是否和 data source 一致。
5.4 坑 6:子网 CIDR 与路由表关联被 AI 漏掉
- 存量 VPC 里子网通常绑定到非默认路由表 (
rtb-xxx),AI 只生成 VPC + 子网时,会丢掉tencentcloud_route_table_association,导致流量路径和线上不一致。 - 补上关联资源:
hcl
resource "tencentcloud_route_table_association" "app" {
subnet_id = tencentcloud_subnet.subnet_app_a.id
route_table_id = "rtb-xxxxxxxx" # 控制台核实后的真实路由表 ID
}
提醒 :路由表里若有多条手工加的条目(如对等连接、NAT、专线路由),也要逐条确认是否纳入 TF 管理,否则以后
terraform apply可能与线上路由"打架"。
6. AI 输出后,人工修正要点(通用清单)
不管资源类型是什么,AI 交稿后请按这个顺序过一遍:
- 字段名对 schema :对照 terraform-provider-tencentcloud 文档 逐字段核对,
Unsupported argument一律删掉,别让 AI 硬编。 - ID 必须核实 :
image_id、instance_type、route_table_id、nat_id等"改了会动资源"的字段,全部用控制台 /tccli/ data source 核实,禁止使用 AI 猜测值。 - 付费与计费字段显式声明 :
instance_charge_type、bandwidth_charge_type、COS 的acl,不写就有默认值 diff。 - 依赖用引用而非硬编码 :
tencentcloud_vpc.vpc_prod.id这种写法,让 Terraform 自己排依赖图,别写死字符串。 terraform import逐个入 State :import 前先terraform state list看基线;导入后terraform state show <addr>对比实际属性。plan归零才算完 :标准是No changes. Your infrastructure matches the configuration.,有 diff 就回到第 2 步继续修。- 敏感字段处理 :
password、secret 类字段不要写死在 HCL 里,改用变量 + 环境变量 / 密钥管理;AI 生成的代码里出现明文密钥要立即剔除。 - 先 dry-run 后动真格 :任何
apply之前,terraform plan输出里出现destroy/Force replacement字样,先停下来人工确认------那往往意味着配置和存量资源有根本性偏差。
7. 常见资源识别失败避坑清单(收藏向)
| 资源 | AI 易错点 | 表现 | 正确姿势 |
|---|---|---|---|
| CVM | image_id 靠猜 |
plan 显示重装系统 | data source 查真实镜像 ID |
| CVM | 漏 instance_charge_type |
包年包月被 plan 成按量/重建 | tccli cvm DescribeInstances 核实 |
| CVM | key_name vs password 混用 |
互斥报错 / 登录失效 | 二选一,且密码不入库 |
| COS | 给资源写 region |
Unsupported argument |
删掉,region 由 provider 控制 |
| COS | acl 默认值 |
权限 diff 永远消不掉 | 显式声明并核对真实权限 |
| COS | 把存量对象写进 TF | apply 可能误删业务数据 | 对象用 coscmd 管理,不入 TF |
| VPC | cidr_block 填错 |
与现网网段冲突 | 控制台 VPC 详情核实 CIDR |
| 子网 | 依赖的 VPC ID 写死错误值 | SubnetNotExist |
data source 查归属,用引用 |
| 路由表 | 漏 route_table_association |
流量路径与线上不一致 | 补关联资源,核对条目 |
| 安全组 | 规则 type/port_range 写反 |
入站出站规则错位 | 对照控制台规则逐条核对 |
| CLB | 后端绑定漏 tencentcloud_clb_attachment |
转发不生效 | 单独生成 attachment 资源 |
| CDB | 只生成实例不生成只读/备库 | 高可用拓扑丢失 | 数据库类资源逐拓扑核对 |
8. 可复用提示词模板(直接套用)
模板 A:单个资源逆向
text
我有一台存量腾讯云【资源名】,ID 为【ID】,位于【region】,需要纳入 Terraform 管理。
请生成 resource "tencentcloud_【资源类型】" 的 HCL:
1. provider 版本 tencentcloudstack/tencentcloud ~> 1.79,字段名严格按 HCL schema;
2. 只写我能确认存在的字段,无法确认的字段留注释 TODO,禁止臆造;
3. 不包含敏感信息明文;给出 terraform import 命令。
模板 B:批量资源 + 依赖关系
text
以下存量腾讯云资源互相有依赖关系,请一次性生成完整 HCL 并用资源引用串联:
【按层级列出:VPC → 子网 → 安全组 → 实例 → 绑定的其他资源,附各自 ID 与 region】
要求:依赖引用用 tencentcloud_xxx.yyy.id 写法;输出顺序按依赖层级;给出每个资源的 import 命令。
模板 C:AI 修正追问(Plan 有 diff 时)
text
terraform plan 显示以下差异,请诊断原因并修正 HCL:
【粘贴 plan 输出中 + / - / ~ 的关键行】
注意:涉及 image_id、instance_type、计费类型的变更禁止出现在修正方案里,除非确认是误配置。
9. 两条路线怎么选
- 路线一(本文主线) :CodeBuddy AI 助手生成 HCL + 本地
terraform import。适合已经用 Terraform、想逐步纳管存量资源的团队,门槛低、完全可控。 - 路线二(官方托管) :腾讯云 云资源自动化 for Terraform(TIC) 的存量资源导入能力,由平台侧扫描并生成模板/State。适合大范围一次性纳管、想省掉本地环境维护的场景。
两条路线可以混合:先用 TIC 扫一遍拿事实基线,再让 AI 基于基线生成 / 修正 HCL,人工审查后落库。
10. 总结:逆向 IaC 的三条铁律
- AI 只负责"生成初稿",不负责"事实":所有 ID、计费、归属关系,必须以控制台 / CLI / data source 为准。
- import 只是第一步,plan 归零才是终点 :
terraform import不校验配置,No changes才是纳管完成的唯一标准。 - 敏感字段与依赖图是红线:明文密钥不入库,依赖关系必须用资源引用表达,宁可多写 data source 也不要硬编码。
做到这三点,"控制台点出来的历史包袱"就能平稳变成"可审计、可回滚、可评审"的代码资产------这大概就是运维从救火走向平台的底气。