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 生成,适合临时会话和浏览器登录后的短时操作,但令牌有有效期,不适合长期无人值守的流水线。

OCI Provider 认证方式与身份来源 Terraform 执行环境 本地开发机 API Key / 安全令牌 CI/CD Runner 实例 Instance Principal OCI Functions / 容器 Resource Principal 临时交互会话 Security Token 身份凭证来源 用户 RSA 密钥对 公钥上传 / 私钥本地 实例元数据服务 动态组 + IAM 策略 资源自身身份 资源主体策略 短期会话令牌 有效期受限 OCI 租户与区域 生产租户 cn-hangzhou prod 分区 测试租户 cn-shanghai test 分区 开发租户 cn-beijing dev 分区 共享服务租户 cn-hangzhou shared 分区 IAM 策略按动态组 / 用户组授权 最小权限 · 分区隔离 · 审计日志 每个 Provider 别名绑定一个租户 + 区域

二、多环境与多租户的 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 隔离框架下平滑演进。