4. OCI Provider认证与配置治理
在 Terraform 中,OCI Provider 是连接声明式配置与 Oracle Cloud Infrastructure 真实资源的桥梁。Provider 的认证方式决定了 Terraform 以什么身份、什么权限、在哪个租户与区域中执行操作。如果认证配置混乱,轻则出现“本地能跑、CI 报错”,重则把测试环境资源误建到生产租户,甚至因密钥泄露导致租户被入侵。因此,本章的重点不是“把 Provider 写出来”,而是建立一套可隔离、可审计、可安全存储的认证与配置治理方案。
一、OCI Provider 的三种认证方式
OCI Provider 支持多种认证路径,实际工程中最常用的是 API 密钥、实例主体和资源主体,安全令牌则更多用于交互式与临时场景。它们解决的是不同身份来源问题,不能混为一谈。
API 密钥(API Key)是最传统的方式。其原理是:在 OCI 控制台为用户生成一对 RSA 密钥,公钥上传到用户账户,私钥保存在本地或密钥管理系统中。Terraform 通过 tenancy_ocid、user_ocid、fingerprint、private_key_path 和 region 五个核心参数完成身份声明。它适合本地开发、CI/CD 中代表某个服务账号执行,但私钥一旦泄露,攻击者即可在权限范围内操作租户,因此必须配合最小权限策略和密钥轮换。
实例主体(Instance Principal)用于运行在 OCI 计算实例上的 Terraform。它不需要在实例上保存任何用户私钥,而是由实例的元数据服务动态签发短期凭证。配置时通常只需声明 auth = "InstancePrincipal",再通过动态组(Dynamic Group)和 IAM 策略授权该组管理目标资源。它的优势是“无长期密钥”,非常适合自动化流水线中的 Runner 实例。
资源主体(Resource Principal)则面向 OCI 函数、容器实例等资源本身。它让资源以自身身份调用 OCI API,同样避免硬编码密钥。安全令牌(Security Token)通常由 oci session authenticate 生成,适合临时会话和浏览器登录后的短时操作,但令牌有有效期,不适合长期无人值守的流水线。
二、多环境与多租户的 Provider 隔离
真实项目中,同一套 Terraform 代码往往要部署到开发、测试、生产等多个环境,甚至跨多个租户。如果所有环境共用一个 Provider 配置,就无法保证“同一份代码、不同目标”的可控性。OCI Provider 通过 alias 和 provider 块实现隔离。
推荐做法是:为每个“租户 + 区域 + 环境”组合定义一个带别名的 Provider。例如:
provider "oci" {
alias = "prod_hz"
tenancy_ocid = var.prod_tenancy_ocid
user_ocid = var.prod_user_ocid
fingerprint = var.prod_fingerprint
private_key_path = var.prod_private_key_path
region = "cn-hangzhou"
}
provider "oci" {
alias = "test_sh"
tenancy_ocid = var.test_tenancy_ocid
user_ocid = var.test_user_ocid
fingerprint = var.test_fingerprint
private_key_path = var.test_private_key_path
region = "cn-shanghai"
}
在资源或模块中通过 provider = oci.prod_hz 显式指定目标。这样,同一份模块代码可以被不同环境复用,而不会因为默认 Provider 而误操作。对于跨租户场景,建议把租户级参数放入独立的 terraform.tfvars 或变量文件,并通过工作区(workspace)或目录结构区分环境,避免在代码中硬编码任何 OCID 和密钥路径。
private_key_path 指向仓库内的文件。推荐使用环境变量 OCI_PRIVATE_KEY_PATH 或密钥管理服务(Vault)动态注入,并在 CI 中通过短期凭证或实例主体替代长期密钥。
三、安全存储与密钥治理
认证配置的治理核心是“密钥不落盘、权限最小化、轮换可审计”。具体可以从三个层面落地。
第一层:密钥存储。API 私钥不应提交到 Git,也不应明文写在 .tfvars 中。本地开发可使用 ~/.oci/config 配合 OCI_CONFIG_FILE 环境变量;CI/CD 中应使用 OCI Vault、GitHub Secrets、GitLab CI Variables 等受控存储,并在运行时以文件或环境变量注入。对于实例主体和资源主体,则完全不需要私钥,应优先采用。
第二层:权限边界。每个认证身份都应绑定独立的 IAM 策略。例如,生产环境的 Terraform 身份只允许管理 prod 分区中的计算、网络和存储资源,不允许访问 test 分区;测试环境身份则相反。策略中应使用 where target.compartment_id 或标签条件限制范围,避免“一个身份管所有”。
第三层:轮换与审计。API 密钥应设置有效期并定期轮换,轮换后同步更新 Vault 和 CI 变量。所有 Terraform 执行应开启 OCI 审计日志,记录 user_ocid、tenancy_ocid、请求时间和操作对象。一旦发现异常调用,可以快速定位到具体身份和密钥。
四、配置治理检查清单
在把 Terraform 接入真实租户之前,建议逐项确认以下内容。它既是配置规范,也是排障时的对照依据。
| 检查项 | 推荐做法 | 判断依据 |
|---|---|---|
| 认证方式选择 | CI/CD 优先实例主体,本地用 API Key,临时用安全令牌 | 是否仍有长期私钥落在 Runner 磁盘上 |
| Provider 别名 | 每个租户+区域+环境一个 alias | 资源是否显式指定 provider,而非依赖默认 |
| 密钥存储 | Vault / CI Secrets / 环境变量,不提交 Git | 仓库中是否出现 private_key 或 OCID 明文 |
| IAM 权限 | 按分区和标签最小授权 | 测试身份能否操作生产资源 |
| 轮换与审计 | 密钥定期轮换,开启审计日志 | 能否追溯到某次变更的执行身份 |
完成上述治理后,Terraform 的认证配置就不再是“能跑就行”的临时脚本,而是一套可复制、可审计、可交接的工程规范。后续无论是新增区域、扩展租户,还是把执行环境从本地迁移到流水线,都可以在既有 Provider 隔离框架下平滑演进。