Terraform 如何忽略 JSON 编码属性中的特定更改

67次阅读
没有评论

问题描述

在使用 Terraform 配置 CloudWatch 日志记录和 DMS 配置时,遇到了在 replication_task_settings 上忽略特定属性更改的问题。目前,用户的 DMS 复制任务配置如下:

resource "aws_dms_replication_task" "main" {
  migration_type            = "full-load-and-cdc"
  replication_instance_arn  = var.replication_instance_arn
  replication_task_id       = "${var.environment}-${var.customer}-dms-replication-task-ongoing-main-${var.engine}"
  source_endpoint_arn       = var.source_endpoint_arn
  target_endpoint_arn       = var.target_endpoint_arn
  replication_task_settings = jsonencode(local.task_settings)
  table_mappings            = jsonencode(local.table_mappings)
  tags                      = merge({}, local.additional_labels)

  lifecycle {
    ignore_changes = [
      replication_task_settings
    ]
  }
}

这里用户通过 ignore_changes 属性忽略了对 replication_task_settings 的所有未来更改。用户希望能够只忽略 Logging.CloudWatchLogGroupLogging.CloudWatchLogStream 这两个属性的更改,因为 DMS 会为用户创建这些日志组和日志流,而且用户无法更改它们。然而,问题在于 replication_task_settings 是一个 JSON 编码的属性。

用户尝试使用以下方法来忽略特定属性的更改,但都遇到了问题:

  • 使用 ignore_changes = [replication_task_settings["Logging"]["CloudWatchLogStream"]] 报错。
  • 使用 ignore_changes = [jsondecode(replication_task_settings)["Logging"]["CloudWatchLogStream"]] 也报错。

用户想知道是否有方法可以忽略 JSON 编码属性的特定部分更改,或者是否有其他 DMS 任务的解决方法。

解决方案

请注意以下操作可能涉及版本差异,进行操作前建议备份数据。

Terraform 中的 ignore_changes 机制无法直接针对 JSON 编码属性的特定部分进行更改的忽略。因为 Terraform 将 replication_task_settings 视为不透明的字符串,所以要么检测该字符串是否发生了更改(默认行为),要么完全忽略对字符串的更改。

然而,您可以尝试以下方法来达到类似的效果:

方法1:将不需要更改的属性分离

将需要忽略的属性从 replication_task_settings 中分离出来,形成一个单独的属性,然后使用 ignore_changes 忽略整个属性。

  1. Logging.CloudWatchLogGroupLogging.CloudWatchLogStream 等属性从 local.task_settings 中分离出来,形成一个单独的对象,例如 local.logging_settings

  2. aws_dms_replication_task 资源中,将 replication_task_settings 设置为 jsonencode(local.logging_settings)

  3. 使用 ignore_changes 忽略整个 replication_task_settings

这样做的效果是,虽然整个 replication_task_settings 属性仍然会被忽略,但由于您将需要保持不变的属性单独分离出来,就能达到忽略特定属性更改的目的。

方法2:使用替代属性

如果您想要细粒度地控制属性的更改,可以考虑使用替代属性。在 Terraform 中,您可以创建一个与 replication_task_settings 对应的输出,其中只包含不需要更改的属性。

  1. 在您的 Terraform 配置中,创建一个输出变量,将需要保持不变的属性从 replication_task_settings 中分离出来,形成一个单独的对象。
output "replication_task_logging_settings" {
  value = {
    Logging = {
      CloudWatchLogGroup   = local.task_settings.Logging.CloudWatchLogGroup,
      CloudWatchLogStream  = local.task_settings.Logging.CloudWatchLogStream
    }
  }
}
  1. 在其他模块或配置文件中,引用该输出变量来获取需要保持不变的属性。

  2. 由于输出变量只包含特定属性,您可以在使用时更细粒度地控制更改。

尽管这两种方法都不是直接忽略 JSON 编码属性的特定部分更改,但可以根据您的需求,通过重新组织属性和输出变量来实现类似的效果。

结论

虽然 Terraform 的 ignore_changes 机制无法直接针对 JSON 编码属性的特定部分进行更改的忽略,但您可以通过将需要保持不变的属性分离出来,或者使用输出变量的方式,达到类似的效果。选择哪种方法取决于您的具体需求和配置结构。在实施时,请根据您的环境和版本考虑备份数据,以避免不必要的风险。

请确保在实施任何更改之前阅读 Terraform 官方文档以及相关版本更新,以确保您的操作是基于最新的信息和最佳实践。

正文完