根据条件阻止创建具有 for_each 的 Terraform 资源

Prevent a Terraform resource with for_each from being created depending on a condition

我正在使用以下资源创建 DynamoDB table,其中的项目来自 JSON 对象文件。

module "dynamodb_label" {
  source = "./modules/labels"

  enabled = var.ENABLE_TABLE
  name    = var.dynamodb_name

  context = module.this.context
}

locals {
  json_data               = file("./items.json")
  items                 = jsondecode(local.json_data)
}

module "dynamodb_table" {
  source = "./aws-dynamodb"

  count = var.ENABLE_TABLE ? 1 : 0

  hash_key                      = "schema"
  hash_key_type                 = "S"
  autoscale_write_target        = 50
  autoscale_read_target         = 50
  autoscale_min_read_capacity   = 5
  autoscale_max_read_capacity   = 1000
  autoscale_min_write_capacity  = 5
  autoscale_max_write_capacity  = 1000
  enable_autoscaler             = true
  enable_encryption             = true
  enable_point_in_time_recovery = true
  ttl_enabled                   = false

  dynamodb_attributes = [
    {
      name = "schema"
      type = "S"
    }
  ]

  context = module.dynamodb_label.context
}

resource "aws_dynamodb_table_item" "dynamodb_table_item" {
  for_each   = var.ENABLE_TABLE ? local.items : {}
  table_name = module.dynamodb_table.table_name
  hash_key   = "schema"
  item       = jsonencode(each.value)

  depends_on = [module.dynamodb_table]

}

JSON 文件

{
  "Item1": {
    "schema": {
      "S": "https://schema.org/government-documents#id-card"
    },
    "properties": {
      "S": "{\"documentName\":{\"type\":\"string\"},\"dateOfBirth\":{\"type\":\"string\"}}"
    }
  },
  "Item2": {
    "schema": {
      "S": "https://schema.org/government-documents#drivers-license"
    },
    "properties": {
      "S": "{\"documentName\":{\"type\":\"string\"},\"dateOfBirth\":{\"type\":\"string\"}}"
    }
  }
}

我收到以下错误

Error: Inconsistent conditional result types

  on dynamodb-table.tf line 173, in resource "aws_dynamodb_table_item" "dynamodb_table_item":
 173:   for_each   = var.ENABLE_TABLE ? local.items : {}
    ├────────────────
    │ local.items is object with 13 attributes
    │ var.ENABLE_TABLE is a bool, known only after apply

The true and false result expressions must have consistent types. The given expressions are object and object, respectively.

我尝试了很多选项来传递这个错误,甚至将变量类型从 bool 更改为 object。如果我删除 for_each 中的条件并只传递 local.items,则 aws_dynamodb_table_item 会尝试创建,而不管 depends_on 并且它当然无法创建,因为 table_name 是由于 dynamodb_table 模块

中的 count = module.dynamodb_label.enabled ? 1 : 0 返回空

如果 var.ENABLE_TABLE 设置为 false

,我希望跳过 aws_dynamodb_table_item

我在这里错过了什么?非常感谢任何提示。

编辑:到目前为止尝试了以下所有错误;

for_each = var.ENABLE_TABLE == true ? local.schemas : {}
for_each = var.ENABLE_TABLE ? local.items : {}

也许你可以试试这个:

resource "aws_dynamodb_table_item" "dynamodb_table_item" {
  for_each   = var.ENABLE_TABLE : local.items ? {}
  table_name = module.dynamodb_table.table_name
  hash_key   = "schema"
  item       = jsonencode(local.for_each)

  depends_on = [module.dynamodb_table]

}

编辑:在这种情况下,变量 var.ENABLE_TABLE 必须是布尔值。

The true and false result expressions must have consistent types. The given expressions are object and object, respectively.

我想我发现了问题所在

您应该使用 jsondecode,但改用 jsonencode。

locals {
    json_data             = file("./items.json")
    items                 = jsondecode(local.json_data)
}

其次我运行进入这个问题

╷
│ Error: Incorrect attribute value type
│ 
│   on main.tf line 14, in resource "aws_dynamodb_table_item" "dynamodb_table_item":
│   14:   item       = each.value
│     ├────────────────
│     │ each.value is object with 2 attributes
│ 
│ Inappropriate value for attribute "item": string required.
╵
╷
│ Error: Incorrect attribute value type
│ 
│   on main.tf line 14, in resource "aws_dynamodb_table_item" "dynamodb_table_item":
│   14:   item       = each.value
│     ├────────────────
│     │ each.value is object with 2 attributes
│ 
│ Inappropriate value for attribute "item": string required.

为此我使用了这个

resource "aws_dynamodb_table_item" "dynamodb_table_item" {
for_each   = var.ENABLE_TABLE ? local.items : {}
table_name = module.dynamodb_table.table_name
hash_key   = "schema"
item       = each.value.properties.S

depends_on = [module.dynamodb_table]

}

希望这对您调试有帮助。

在围绕不同类型的表达式试验了 2 天以解决此问题后,Reddit 上的好心先生 referred 提出了这个解决方案,它非常有效;

for_each = { for k,v in local.items : k => v if var.ENABLE_TABLE }

对于任何有类似需求的人来说,这似乎是我错过的 gem 并建议您使用它。