运行时(非合成阶段)通过CDK访问Terraform数据源的可行方案
问题
Terraform项目要求Provider需提前以静态方式确定,无法借助Terraform数据源这类动态内容来定义Provider的数量与配置。我因需在预先未知的Azure订阅中部署管理资源,长期受此问题困扰,目前通过Terraform CDK用通用编程语言生成Provider块作为临时方案。但现在Provider信息可从Terraform数据源获取,我有两种选择:1. 在CDK代码中重新实现已有Terraform Provider数据源的数据逻辑;2. 从CDK代码中访问Terraform数据源以生成资源。我更倾向第二种方案,请问是否有无需临时部署HCL代码运行Terraform的干净实现方式?
解决方案
Terraform CDK的核心逻辑是在synth阶段(生成静态HCL前)确定所有Provider配置,而Terraform数据源是在plan/apply阶段执行,两者的执行时机差是核心矛盾。针对你倾向的第二种方案,有两种无需完整部署栈的干净实现思路:
1. 轻量预执行数据源模块
编写一个仅包含目标数据源的极简HCL模块(比如用于获取Azure订阅信息的azurerm_subscription),在CDK代码初始化阶段通过Shell命令调用Terraform CLI执行以下操作:
- 执行
terraform init初始化模块 - 执行
terraform refresh触发数据源获取数据 - 执行
terraform output导出数据源结果 - 用导出的结果动态生成CDK中的Provider块
这种方式仅临时执行数据源逻辑,不需要部署任何资源,属于官方认可的跨阶段数据传递方式,流程清晰易维护。
2. 基于CDK PreSynth钩子的动态数据源调用
借助Terraform CDK的PreSynth钩子能力,在生成正式HCL前创建临时栈并执行数据源:
- 在CDK代码中初始化一个临时Stack,仅添加需要的数据源资源
- 在PreSynth钩子中调用临时Stack的
synth()方法生成临时HCL文件 - 调用Terraform CLI执行
terraform refresh获取临时栈的数据源结果 - 销毁临时栈的文件和状态,用获取到的结果生成正式Provider配置
这种方式无需手动编写HCL模块,完全通过CDK代码封装,但需要额外处理临时栈的清理逻辑,避免残留文件占用空间。
需要注意:两种方式都需要确保执行数据源的身份(如Azure服务主体)拥有目标订阅的信息读取权限,因为数据源的执行是在synth阶段完成,和后续部署的身份可能需要一致或单独配置。
内容的提问来源于stack exchange,提问作者muffel

