为何Terraform每次计划变更时都会重建BigQuery Dataset访问资源?
问题
我用Terraform管理BigQuery基础设施,最近用到google_bigquery_dataset_access资源,它可以给特定类型的所有资源或单独视图授予数据集访问权限。
我在foo数据集模块里做了如下配置(dataset.tf):
resource "google_bigquery_dataset_access" "dataset_authorization" { dataset_id = "foo" dataset { dataset { project_id = "some-project" dataset_id = "bar" } target_types = ["VIEWS"] } } module "foo_dataset" { source = <path to google provider google_bigquery_dataset> version = "some_version" dataset_id = "foo" description = "lorem ipsum" location = "some_location" project = "some-project" }
但现在只要配置里任意位置有变更(哪怕和foo模块无关),Terraform计划都会显示该访问资源有变更并尝试重建,apply输出如下:
# module.foo.module.foo_dataset.google_bigquery_dataset.dataset has changed ~ resource "google_bigquery_dataset" "dataset" { ~ etag = "VH7HJLt5Avl4zcT1spXxtA==" -> "ZQFENhnM/wOpJrgaccOfgQ==" id = "some-project:foo" ~ last_modified_time = 1667311213019 -> 1667312336825
就算完全没修改foo模块,etag和last_modified_time也会变,这是为什么?
原因及解决办法
这是因为**google_bigquery_dataset_access资源的变更会直接修改目标数据集的元数据**,导致数据集的etag和last_modified_time自动更新。而Terraform会把这些元数据变化当成数据集资源的变更,每次执行plan/apply时都会检测到差异。
具体来说,当你通过google_bigquery_dataset_access给foo数据集添加访问权限时,BigQuery后台会更新foo数据集的元数据(包括etag和修改时间)。但你的google_bigquery_dataset资源(也就是模块中定义的那个)会和远端状态做对比,发现这些字段和本地状态不一致,就会标记为变更。
解决办法有两种:
- 将
google_bigquery_dataset_access与对应的google_bigquery_dataset放在同一个模块内,让Terraform能关联两者的状态,避免误判变更。 - 忽略
etag和last_modified_time字段的差异,在google_bigquery_dataset资源中添加lifecycle配置:
module "foo_dataset" { source = <path to google provider google_bigquery_dataset> version = "some_version" dataset_id = "foo" description = "lorem ipsum" location = "some_location" project = "some-project" lifecycle { ignore_changes = [ etag, last_modified_time, ] } }
这样Terraform就不会再因为这两个字段的自动更新而标记数据集为变更了。
内容的提问来源于stack exchange,提问作者Dasph
相关产品推荐
相关产品推荐

