如何让Terraform对google_bigquery_job等状态超时资源仅执行一次apply?
解决方案
以下几个方案都可以实现需求,可根据实际场景选择:
方案1:添加lifecycle规则忽略状态校验
在现有google_bigquery_job资源块中添加lifecycle配置即可,首次apply成功后,Terraform将不再比对该资源的远程状态,也就不会触发重建逻辑:
resource "google_bigquery_job" "your_dml_job" { job_id = "your_unique_job_id" query { query = <<-EOT create or replace table_a as( select *, null as new_column from table_a ) EOT # 其他query原有配置 } # 其他资源原有配置 lifecycle { ignore_changes = all } }
如果后续需要修改DML重新执行,只需修改job_id或者临时移除ignore_changes配置即可。
方案2:执行完成后移除状态中的资源记录
确认首次apply执行成功、DML已生效后,直接在本地执行命令移除该资源的状态记录:terraform state rm google_bigquery_job.your_dml_job
移除后Terraform将完全不再管控该资源,自然不会再触发任何校验、重建逻辑。该方案适合确定该DML永远不需要二次执行的场景。
方案3:改用null_resource执行一次性DML
如果不想受BigQuery job 6个月保留期的限制,也可以改用null_resource配合bq命令行执行DML,只要SQL内容不变就永远不会重复执行:
resource "null_resource" "one_off_dml" { triggers = { # 用SQL内容的哈希作为触发器,内容不变则不会重新执行 dml_content_hash = sha256(<<-EOT create or replace table_a as( select *, null as new_column from table_a ) EOT) } provisioner "local-exec" { command = <<-EOT bq query --use_legacy_sql=false '${replace(<<-INNER create or replace table_a as( select *, null as new_column from table_a ) INNER , "'", "\\'")}' EOT } }
该方案需要运行Terraform的环境提前安装好bq命令行工具,且持有对应BigQuery资源的操作权限。
内容的提问来源于stack exchange,提问作者BigBearZab
相关产品推荐
相关产品推荐

