如果 Null 值位于 Terraform 的嵌套地图中,是否有任何方法可以限制数组中的存在?

Is there any way to condition presence in array if null values are in nested maps in Terraform?

我想向 dynamodb table 插入一些将在使用模块期间定义的项目。在模块中指定参数时,用户不需要传递所有变量,因为某些字段不是必需的,例如“timezone”。

传递给模块的输入值

locals {
 schedules = {
    "reyjkavik-time" = {
      "timezone"    = "Atlantic/Reykjavik"
      "description" = "office hours in Reykjavik"
      "periods"     = ["office-hours"]
    }
  }
}

locals.tf

  schedules = toset(flatten([
  for schedule_name, schedule in var.schedules : {
    description = schedule.description
    timezone = try(schedule.timezone,"")
    periods = schedule.periods
  }
  ]))
resource "aws_dynamodb_table_item" "schedules" {
  for_each = {
  for schedule in local.schedules : schedule.name => schedule
  }
  table_name = aws_dynamodb_table.config_table.name
  hash_key   = aws_dynamodb_table.config_table.hash_key

  item = jsonencode({
    "description" = {
      "S" = each.value.description
    },
    "timezone" = {
      "S" = each.value.timezone
    },
    "periods" = {
      "SS" = each.value.periods
    },
  })
}

但是如果用户不传递像“时区”这样的变量怎么办? 项目将以以下格式添加到 dynamodb

{
  "timezone": {
    "S": ""
  },
  "description": {
    "S": "office hours in reyka"
  },
  "periods": {
    "SS": [
      "office-hours"
    ]
  }
}

问题是我使用 AWS lambda 的 lambda https://aws.amazon.com/solutions/implementations/instance-scheduler/ 和数据库项目的格式无效,因为 dynamodb 显示时区值为空,这是错误的。 理想情况下,如果在这种情况下我只能插入两个字段(没有时区)

{
  "description": {
    "S": "office hours in reyka"
  },
  "periods": {
    "SS": [
      "office-hours"
    ]
  }
}

您可以检查 timezone 的空字符串,如果需要则跳过它:

resource "aws_dynamodb_table_item" "schedules" {
  for_each = {
  for schedule in local.schedules : schedule.name => schedule
  }
  table_name = aws_dynamodb_table.config_table.name
  hash_key   = aws_dynamodb_table.config_table.hash_key

  item = jsonencode(merge({
    "description" = {
      "S" = each.value.description
    }},
    each.value.timezone != "" ? {"timezone" = {
                                    "S" = each.value.timezone
                                }} : null,
    {"periods" = {
      "SS" = each.value.periods
    },
  }))
}

看起来不太漂亮,但应该可以。