外部数据源如何判断Terraform当前执行的是plan、apply还是destroy操作
结论
Terraform 原生HCL没有提供内置变量或函数可以直接获取当前执行的操作类型(plan/apply/destroy),这是官方的有意设计:Terraform 遵循声明式配置原则,期望配置本身的逻辑与执行操作解耦,避免出现同一配置在不同操作下行为不一致的情况。
以下是可落地的变通方案:
方案1:环境变量透传(最推荐,兼容性最好)
执行Terraform命令时通过环境变量传递操作类型,HCL侧读取环境变量后通过query参数传给Python程序:
- 首先在HCL中定义变量接收环境变量值:
variable "tf_operation" { type = string description = "当前Terraform执行的操作类型,由执行命令时的环境变量TF_OPERATION传入" default = "unknown" } data "external" "example" { program = ["python", "${path.module}/example-data-source.py"] query = { id = "abc123" # 把操作类型传给Python程序 operation = var.tf_operation } }
- 执行命令时传入环境变量:
- 执行plan:
TF_OPERATION=plan terraform plan - 执行apply:
TF_OPERATION=apply terraform apply - 执行destroy:
TF_OPERATION=destroy terraform destroy
如果不想每次手动输入环境变量,可以写简单的Shell脚本封装命令,自动注入操作类型:
#!/bin/bash # 保存为tf_wrapper.sh,加执行权限 TF_OPERATION="$1" shift TF_OPERATION="$TF_OPERATION" terraform "$TF_OPERATION" "$@"
使用时直接执行./tf_wrapper.sh apply即可。
方案2:Python侧直接读取父进程参数(无需修改HCL)
Python程序可以直接读取调用自己的父进程(即Terraform进程)的启动参数,判断执行的操作类型:
import os import psutil def get_tf_operation(): # 获取当前进程的父进程 parent_proc = psutil.Process(os.getpid()).parent() # 校验父进程是否为Terraform进程 if parent_proc.name().startswith("terraform"): cmd_args = parent_proc.cmdline() if len(cmd_args) >= 2: # 第二个参数就是操作类型(plan/apply/destroy) return cmd_args[1] return "unknown" if __name__ == "__main__": current_op = get_tf_operation() # 后续根据current_op执行对应逻辑
该方案的局限性:
- 需要Python安装
psutil依赖包 - 如果Terraform是被其他脚本/工具间接调用,父进程链路存在中间层时,可能无法正确读取到Terraform的操作参数
注意事项
external数据源会在terraform plan阶段就执行,并非仅在apply阶段运行,如果你的Python程序包含会修改外部资源的逻辑,需要在代码中增加对plan操作的判断,避免预览阶段就执行实际变更。
内容的提问来源于stack exchange,提问作者Allan Xu
相关产品推荐
相关产品推荐

