问题描述
在使用 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.CloudWatchLogGroup
和 Logging.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
忽略整个属性。
-
将
Logging.CloudWatchLogGroup
和Logging.CloudWatchLogStream
等属性从local.task_settings
中分离出来,形成一个单独的对象,例如local.logging_settings
。 -
在
aws_dms_replication_task
资源中,将replication_task_settings
设置为jsonencode(local.logging_settings)
。 -
使用
ignore_changes
忽略整个replication_task_settings
。
这样做的效果是,虽然整个 replication_task_settings
属性仍然会被忽略,但由于您将需要保持不变的属性单独分离出来,就能达到忽略特定属性更改的目的。
方法2:使用替代属性
如果您想要细粒度地控制属性的更改,可以考虑使用替代属性。在 Terraform 中,您可以创建一个与 replication_task_settings
对应的输出,其中只包含不需要更改的属性。
- 在您的 Terraform 配置中,创建一个输出变量,将需要保持不变的属性从
replication_task_settings
中分离出来,形成一个单独的对象。
output "replication_task_logging_settings" {
value = {
Logging = {
CloudWatchLogGroup = local.task_settings.Logging.CloudWatchLogGroup,
CloudWatchLogStream = local.task_settings.Logging.CloudWatchLogStream
}
}
}
-
在其他模块或配置文件中,引用该输出变量来获取需要保持不变的属性。
-
由于输出变量只包含特定属性,您可以在使用时更细粒度地控制更改。
尽管这两种方法都不是直接忽略 JSON 编码属性的特定部分更改,但可以根据您的需求,通过重新组织属性和输出变量来实现类似的效果。
结论
虽然 Terraform 的 ignore_changes
机制无法直接针对 JSON 编码属性的特定部分进行更改的忽略,但您可以通过将需要保持不变的属性分离出来,或者使用输出变量的方式,达到类似的效果。选择哪种方法取决于您的具体需求和配置结构。在实施时,请根据您的环境和版本考虑备份数据,以避免不必要的风险。
请确保在实施任何更改之前阅读 Terraform 官方文档以及相关版本更新,以确保您的操作是基于最新的信息和最佳实践。