创新方案
在 Terraform Provider…
当需要向配置传递令牌、密码、短期证书等敏感值且绝不能写入 state 或 plan 时,用 Plugin Framework 实现临时资源。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
在 Terraform Provider通用
解决思路
- 判断是否该用临时资源:只读的非敏感查询用 data source;敏感且仅在 apply 时需要的值(如 provider 块用的数据库密码、write-only 属性的令牌)用 ephemeral resource;下游托管资源必须存储的敏感值用普通 resource/data source 并尽量配合 write-only 属性;会在操作中途过期的凭证(STS 风格令牌、短 TTL 租约)用带 Renew 的 ephemeral resource。
- 实现 Open 方法(必需):在 plan 和/或 apply 需要结果时获取或创建值;没有 state 可刷新,也没有东西可导入。
- 实现 Renew 方法(可选):当墙钟时间超过 Open/Renew 返回的 RenewAt 时被调用,用于在 Terraform 仍在运行时过期的值;Renew 不能返回新结果,只能延长/刷新 Open 产出的内容(例如重新租用同一凭证);如果值本身在续期时会变化,说明该 API 在此意义上不可续期,Open 必须返回更长寿的值。
- 实现 Close 方法(可选):在 Terraform 用完该值后调用,在此撤销租约或删除临时凭证。
- 用 resp.Private 在 Open 中传递字节(如续期/撤销所需的 lease ID),由 Renew 和 Close 通过 req.Private.GetKey 接收。
- 在结构体上声明接口断言:ephemeral.EphemeralResource、ephemeral.EphemeralResourceWithConfigure、ephemeral.EphemeralResourceWithRenew、ephemeral.EphemeralResourceWithClose。
- 实现 Metadata 方法,设置 resp.TypeName = req.ProviderTypeName + "_token" 之类的名称。
- 在 Schema 中定义属性:输入属性(如 role_name)用 Required;输出属性(如 token、lease_id)用 Computed;秘密属性额外标记 Sensitive: true。
- 在 Open 中用 req.Config.Get(ctx, &data) 读取配置,调用客户端获取值,把结果写入 data,并通过 resp.Result.Set(ctx, &data) 返回。
- 在 Open 中设置 resp.RenewAt = lease.ExpiresAt.Add(-2 * time.Minute),即在真实过期前留出安全余量;Terraform 是惰性续期而非精确定时。
- 在 Renew 中从 req.Private 取回 lease ID,调用客户端续期,并更新 resp.RenewAt。
- 在 Close 中从 req.Private 取回 lease ID,调用客户端撤销租约;若上游值无法撤销,则跳过 Close,而不是实现一个暗示会撤销的空操作。
- Configure 沿用与 resource 相同的 ProviderData 类型转换模式,客户端来自 provider 的 Configure 中设置的 resp.EphemeralResourceData。
- 在 provider 上实现 provider.ProviderWithEphemeralResources 接口,并在 EphemeralResources() 方法中返回各临时资源的构造函数。
- 在 provider 的 Configure 中,与 ResourceData/DataSourceData 一起设置 resp.EphemeralResourceData = client。
- 设计规则:绝不记录该值,绝不把它放进 diagnostic;秘密属性仍标记 Sensitive: true 以保护其自身生命周期输出的渲染;不使用 plan modifier、不支持 import、不设 id 约定;schema 输入遵循 data source 参数规则,暴露 API 的标识符(如 role_name)而非自造名称。
- 测试:临时结果永不进入 state,因此通过 echoprovider 把临时值回显到一个可检查的普通资源来间接断言;至少覆盖一个基本的 open-and-use 测试以及各属性测试与必填字段测试;用 tfversion.SkipBelow(tfversion.Version1_10_0) 做版本门控。
- 文档:在 docs/ephemeral-resources/<name>.md 用 tfplugindocs 生成注册表文档,并明确说明续期/撤销行为,让用户知道结束 Terraform 运行是否会撤销凭证。
- 按清单自检:值确实不能持久化;Open 已实现且 Renew/Close 仅在 API 支持时实现;秘密属性 Sensitive: true 且值从不记录或进入 diagnostic;lease/handle 通过 Private 而非结果传递;RenewAt 留有余量;已在 EphemeralResources() 注册并在 Configure 设置 EphemeralResourceData;有回显 provider 的验收测试并按 Terraform >= 1.10 门控;文档页说明生命周期、续期与撤销行为。
适用边界 · 注意事项
- 值不需要持久化时不必用临时资源——普通 data source 更简单。
- 下游托管资源必须把敏感值作为属性存储时,应使用普通 resource/data source 并尽量配合 write-only 属性,而非临时资源。
- 上游值无法撤销时不要实现 Close,以免产生暗示会撤销的空操作。