如何在运行Terraform plan前将.tfvar文件直接下载到ADO代理机
当前采用Terraform Enterprise Cloud + Azure DevOps YAML流水线完成Azure基础设施部署,核心需求为将.tfvar变量文件与Terraform主代码目录完全分离,统一存放在名为config的独立代码仓库中。
- 直接通过
terraform plan --var-file参数引用config仓库内tfvars文件的方案无法落地原因:团队使用全局统一管控的流水线模板,
fmt/validate/plan/apply全链路Terraform命令均由模板封装执行,不允许修改模板内容。现有模板固定逻辑为:仅扫描Terraform执行当前目录下的.tfvars文件,通过内置bash命令将其重命名为.auto.tfvars后,交由Terraform自动识别加载,不支持自定义传参指定其他路径的var-file。
期望的落地路径为:现有模板默认会将全量Terraform目录复制到ADO Agent运行容器中,只要能让config仓库存储的.tfvar文件在Agent容器内、且处于Terraform执行目录下可被模板扫描识别,方案即可生效。
目前初步构思的两个思路暂未跑通:
- 编写shell脚本将config仓库的tfvars文件复制到Agent容器,但要求文件必须放置在Terraform目录内——模板只会将Terraform目录的内容复制到运行容器,其他路径的文件不会被识别
- 在Terraform配置中集成shell脚本,实现运行时自动将tfvars文件从config仓库下载到容器内,暂未确认可行性
方案1:ADO多仓库检出+前置复制(最推荐,零侵入)
完全不需要修改全局模板,也不需要调整Terraform代码,仅需要在自有业务流水线引用全局模板之前,增加多仓库检出和文件复制步骤即可:
- 在流水线中配置同时检出Terraform主代码仓库和独立的config仓库
- 在Terraform模板执行前,通过简单bash命令将对应环境的tfvars文件复制到Terraform主代码的根目录
- 后续正常调用全局模板,模板会自动扫描到目录内的tfvars文件,按原有逻辑重命名加载
核心配置示例:
steps: # 检出独立config仓库 - checkout: git://<你的ADO项目名>/config persistCredentials: true path: s/config-repo # 检出Terraform主代码仓库 - checkout: self path: s/terraform-main # 复制对应环境的tfvars到Terraform执行根目录 - bash: | cp $(Build.SourcesDirectory)/config-repo/envs/$(DeploymentEnv).tfvars $(Build.SourcesDirectory)/terraform-main/ displayName: 同步变量文件到Terraform执行目录 # 后续正常引用全局Terraform模板即可,无需改动模板逻辑
注意提前给ADO构建服务账号分配config仓库的读权限,避免检出失败。
方案2:Terraform external数据源自动拉取(次选,无需调整流水线检出配置)
如果不方便修改流水线的多检出配置,可以在Terraform公共配置中使用external数据源,在Terraform执行初始化阶段自动拉取config仓库的tfvars文件到当前执行目录,全程不需要改动全局模板:
核心配置示例:
data "external" "fetch_env_tfvars" { program = ["bash", "-c", <<EOT # 复用ADO流水线自动注入的系统访问凭证拉取config仓库文件 curl -s -H "Authorization: Bearer $SYSTEM_ACCESSTOKEN" \ "<你的ADO组织地址>/<你的项目名>/_apis/git/repositories/config/items?path=/envs/${var.deployment_env}.tfvars&api-version=7.1" \ -o ./${var.deployment_env}.tfvars echo '{"status":"fetched"}' EOT ] }
使用时需要在Terraform执行阶段将SYSTEM_ACCESSTOKEN以环境变量形式透传,同时给构建服务账号分配config仓库的读权限即可。
方案3:全局模板Hook位前置执行
大部分企业内部的全局Terraform模板都会预留pre-plan/pre-apply这类自定义前置任务挂载点,如果你们用的模板支持,直接在前置Hook里添加Git拉取或文件下载任务,把对应tfvars下载到Terraform执行目录即可,不需要改Terraform代码,也不需要调整主流水线的检出逻辑。
内容的提问来源于stack exchange,提问作者anand malla

