Phase 5b:Resource Manager¶
目标¶
体验 OCI 托管的 Terraform 执行环境,和本机执行做比较。
Resource Manager 是什么¶
| 概念 | 意思 |
|---|---|
| Stack | 代码(zip / Git 等)+ 变量值 |
| Job | 对 Stack 执行一次 plan / apply / destroy / import |
和本机执行的区别:
| 本机 Terraform | Resource Manager | |
|---|---|---|
| state | 自己管(Phase 3 放在 bucket 里) | RM 保管,自带锁 |
| 认证 | API Key | 执行 Job 的用户的身份(不用发 API Key) |
| 执行记录 | 本机终端 | Job 日志留在 OCI |
| 其他 | Drift 检测、Resource Discovery、Console 表单(schema.yaml) |
|
| 费用 | RM 本身免费(建出来的资源照常计费) |
≒ AWS 的 CloudFormation(但用的是 Terraform 语法),或 HCP Terraform。
结构¶
05-resource-manager/
├── build-zip.ps1 stack/ + 04 的 network module → build/stack.zip
├── rm.py 用 OCI Python SDK 操作 RM
└── stack/ VCN + Private Subnet(不建 Gateway)
- stack 里没有 backend 块(state 交给 RM),provider 里不写认证(只写 region)
- module 不复制进 Git,打包时才放进 zip(源码只有一份)
- 标签
managed_by = "resource-manager",和本机 Terraform 管理的(terraform)区分开
流程和观察¶
| 步骤 | 结果 / 观察 |
|---|---|
| 查支持的版本 | RM 支持的 Terraform 最高 1.5.x(本机是 1.12+)→ 代码的 required_version 要兼容 |
| plan Job | 4 to add。排队(ACCEPTED)约 2 分钟,执行 10 秒 |
| apply Job | execution_plan_strategy = FROM_PLAN_JOB_ID:执行上面 plan Job 存下的计划(≒ terraform apply xxx.tfplan) |
| 手动改资源 | 用 API 把 VCN 名改成 tflab5-vcn-changed-by-hand |
| Drift 检测 | Stack DRIFTED、VCN MODIFIED、其余 3 个 IN_SYNC,能看到 expected / actual 的值 |
| 修复 drift | 再 plan → ~ display_name(in-place)→ apply → drift 检测全部 IN_SYNC |
| destroy Job | 4 destroyed |
| 删除 Stack | Job 记录和 RM 保管的 state 一起删除 |
Drift 检测只报告,不修复
修复方法有两种:再 plan → apply 把实际资源改回代码的样子,或者改代码迎合现状。 Drift 检测是 Work Request,不是 Job,所以 Job 列表里看不到。
- 每个 Job 都在全新的环境里执行,日志里能看到每次都重新
terraform init(provider 版本按 lock file 固定)
坑¶
本机装不了 OCI CLI:Windows 路径长度上限
pip install oci-cli → FileNotFoundError。原因是 Windows 的路径上限 259 字符(LongPathsEnabled = 0)。
oci-cli 里最长的文件相对路径有 229 字符 → 安装位置必须在 30 字符以内。
- 先查最长路径:
pip download <pkg> --no-deps,再用 Python 的 zipfile 看 namelist 里最长的那个。只看报错的那个文件会误判 - 对策:改用 Python SDK(
oci包)。CLI 本身就是 SDK 的包装,能做的事一样 - 其他选项:打开长路径(要管理员权限)/ 装到
C:\oci\这种短路径
SDK 的 drift 属性是 dict,不是 JSON 字符串
expected_properties / actual_properties 在 SDK 里已经是 dict(值本身是 JSON 编码过的字符串,所以带引号)。
对它再 json.loads 会报 TypeError。
PowerShell 5.1 的 zip,Linux 上解不开
Compress-Archive 的路径分隔符是 \。用 tar.exe -a -c -f x.zip -C <dir> . 打 zip。
pip install --quiet 看起来像卡住了
报错也看不到。排查时去掉 --quiet,日志写进文件。