Terraform如何按GCS工件存在性条件触发CloudBuild并等待完成
可行性结论
Terraform 原生没有你设想的if_does_not_exist_trigger类的数据源参数,但可以通过内置能力组合完全实现你需要的编排逻辑,不需要依赖第三方插件或外部编排系统。
具体实现方案
你之前的方案存在两个核心问题:
- 原生
google_storage_bucket_object数据源在查询对象不存在时会直接报错中断流程,无法做分支判断 - 你定义的
google_cloudbuild_trigger资源仅会在GitHub收到对应分支推送事件时自动触发构建,Terraform创建/更新触发器资源本身不会主动执行构建任务
按照以下步骤调整配置即可:
1. 替换对象存在性探测逻辑
用HTTP数据源直接调用GCS的API探测模板对象是否存在,关闭默认的状态码报错逻辑,通过返回的HTTP状态码判断对象是否存在:
# 加载当前GCP认证信息 data "google_client_config" "current" {} # 探测目标模板文件是否存在 data "http" "flex_template_exists" { url = "https://storage.googleapis.com/storage/v1/b/${google_storage_bucket.project_store.name}/o/${urlencode("path/to/flex/template.json")}" request_headers = { Authorization = "Bearer ${data.google_client_config.current.access_token}" } # 404等非200状态不直接中断执行 error_on_status_code = false } locals { # 200代表模板存在,404代表不存在 template_exists = data.http.flex_template_exists.status_code == 200 }
2. 增加条件触发构建的逻辑
用null_resource加条件计数,仅当模板不存在时才主动触发Cloud Build构建,通过gcloud命令的--wait参数阻塞等待构建完成,再推进后续流程:
resource "null_resource" "trigger_build_when_missing" { # 模板存在时count为0,不创建该资源、不执行构建 count = local.template_exists ? 0 : 1 provisioner "local-exec" { # 触发对应分支的构建,等待构建完成后再退出 command = "gcloud builds triggers run ${google_cloudbuild_trigger.build_pipeline.id} --branch=my-branch --project=${var.google_project_id} --wait" } depends_on = [google_cloudbuild_trigger.build_pipeline] }
3. 调整Dataflow作业的依赖声明
给Dataflow作业增加对探测逻辑和条件构建资源的依赖,确保不管是复用现有模板还是等待新构建完成,都在模板就绪后再创建作业:
resource "google_dataflow_flex_template_job" "dataflow_job" { provider = google-beta name = "dataflow_job" container_spec_gcs_path = "${google_storage_bucket.project_store.url}/path/to/flex/template.json" project = var.google_project_id parameters = { ... } depends_on = [ google_bigquery_table.tables, data.http.flex_template_exists, null_resource.trigger_build_when_missing ] }
注意事项
- 执行Terraform的身份需要持有三个权限:GCS存储对象查看权限、Cloud Build触发器执行权限、Cloud Build构建任务查看权限,否则探测和触发流程会失败
- 存在性判断发生在
terraform plan阶段:如果执行plan时模板不存在,apply阶段会先触发构建、等构建完成再部署Dataflow作业;如果plan时模板已存在,会直接跳过构建步骤复用现有工件 - 该逻辑仅适合需要复用未变更工件的场景,如果需要每次代码提交都重新构建模板,不要加存在判断,直接将构建作为固定前置步骤即可
- 不要直接使用
google_storage_bucket_object数据源做存在性探测:该数据源查询不到对象时会直接抛出错误终止流程,无法实现分支判断
内容的提问来源于stack exchange,提问作者Arindam
相关产品推荐
相关产品推荐

