每个实现的terraform都具有.tfvars中的值

每个实现的terraform都具有.tfvars中的值,terraform,terraform-provider-gcp,terraform0.14.7,Terraform,Terraform Provider Gcp,Terraform0.14.7,我有一个common.tfvars文件,其中变量的定义如下: bqtable_date_partition = [ { dataset = "d1", table_name = "d1-t1", part_col = "partition_date", part_type = "DAY", schema_file = "data_tables/d1-t1.json" }, { dat

我有一个common.tfvars文件,其中变量的定义如下:

bqtable_date_partition = [
  { dataset = "d1", table_name = "d1-t1", part_col = "partition_date",
  part_type = "DAY", schema_file = "data_tables/d1-t1.json" },

  { dataset = "d1", table_name = "d1-t2", part_col = "tran_dt",
  part_type = "DAY", schema_file = "data_tables/d1-t2.json" },

  { dataset = "d2", table_name = "d2-t1", part_col = "tran_dt",
  part_type = "DAY", schema_file = "data_tables/d2-t1.json" },
]
我在main.tf文件中引用这个var,并使用以下资源定义:

resource "google_bigquery_table" "bq_tables_dt_pt" {
  count      = length(var.bqtable_date_partition)
  project    = var.project_id
  dataset_id = "${var.bqtable_date_partition[count.index].dataset}_${var.env}"
  table_id   = var.bqtable_date_partition[count.index].table_name
  time_partitioning {
    type  = var.bqtable_date_partition[count.index].part_type
    field = var.bqtable_date_partition[count.index].part_col
  }
  schema     = file("${path.module}/tables/${var.bqtable_date_partition[count.index].schema_file}")
  depends_on = [google_bigquery_dataset.crte_bq_dataset]
  labels = {
    env        = var.env
    ind        = "corp"
  }
}
我想将资源定义更改为使用“for_each”而不是“count”来循环列表:


我将count改为for_each的目的是消除对变量“bqtable_date_partition”元素写入顺序的依赖性

我这样做:

resource "google_bigquery_table" "bq_tables_dt_pt" {
  for_each   = var.bqtable_date_partition
  project    = var.project_id
  dataset_id = "${each.value.dataset}_${var.env}"
  table_id   = each.value.table_name
  time_partitioning {
    type  = each.value.part_type
    field = each.value.part_col
  }
  schema     = file("${path.module}/tables/${each.value.schema_file}")
  depends_on = [google_bigquery_dataset.crte_bq_dataset]
  labels = {
    env        = var.env
    ind        = "corp"
  }
}
我得到了如下预期的错误:

给定的“for_each”参数值不合适:“for_each” 参数必须是一个映射或一组字符串,并且您提供了 字符串映射的类型列表的值

有人能帮我修改一下资源定义中的“for_each”吗


Terraform版本-0.14.x

错误表示它只接受地图或字符串集。因此,我们必须将输入变量转换为映射或字符串集

基本上,这里我们将每个输入转换为以下格式。并且仅引用新创建的映射中的值

{
  "0" = {
    "dataset" = "d1"
    "part_col" = "partition_date"
    "part_type" = "DAY"
    "schema_file" = "data_tables/d1-t1.json"
    "table_name" = "d1-t1"
  }
  "1" = {
    "dataset" = "d1"
    "part_col" = "tran_dt"
    "part_type" = "DAY"
    "schema_file" = "data_tables/d1-t2.json"
    "table_name" = "d1-t2"
  }
  "2" = {
    "dataset" = "d2"
    "part_col" = "tran_dt"
    "part_type" = "DAY"
    "schema_file" = "data_tables/d2-t1.json"
    "table_name" = "d2-t1"
  }
}

对于每个,使用
有两个主要要求:

  • 对于要声明的每个资源实例,必须有一个具有一个元素的集合
  • 必须有某种方法从该集合的每个元素派生出一个唯一标识符,Terraform将使用该标识符作为唯一实例密钥
您的集合似乎满足这两个标准,假设
表_名称
是跨越所有这些值的唯一字符串,因此剩下的就是将集合投影到地图中,以便Terraform可以从关键点看到您打算使用
表_名称
作为唯一跟踪关键点的关键点:

resource "google_bigquery_table" "bq_tables_dt_pt" {
  for_each = {
    for o in var.bqtable_date_partition : o.table_name => o
  }

  # ...
}
在这里,我使用了一个从序列到映射的项目,其中每个元素都由其
table\u name
属性中的值标识


如果您能够更改此模块的接口,则可以通过更改变量的声明以期望使用映射而不是列表来简化操作,这样可以避免投影的需要,并向模块调用方明确表ID必须是唯一的:

variable "bqtable_date_partition" {
  type = map(object({
    dataset     = string
    part_col    = string
    part_type   = string
    schema_file = string
  }))
}

然后,您可以像以前一样,将
var.bqtable\u date\u分区直接分配给
for\u each
,因为它已经是合适的类型了。但也需要更改调用模块以传递映射值而不是列表值,因此,如果您的模块有许多调用者,这些调用者都需要更新才能保持兼容,那么这可能是不实际的。

我将count改为for\u each的目的是消除对变量“bqtable\u date\u partition”元素写入顺序的依赖性。我尝试了你的解决方案,但在这一点上,我也觉得看到这个计划,顺序会很重要,在我的计划中,它说它会破坏3个资源,创造3个。
variable "bqtable_date_partition" {
  type = map(object({
    dataset     = string
    part_col    = string
    part_type   = string
    schema_file = string
  }))
}