如何在Terraform资源中实现可选的warning块?
解决方案
错误原因
你之前的写法错在在count表达式里引用了count.index——count是用来计算资源实例数量的,此时count.index还未生成,自然会触发报错。
最优实现:用动态块(Dynamic Block)
没必要拆成两个资源,Terraform的动态块能帮你根据warning_enabled的值决定要不要生成warning块,用单个资源就能搞定需求。
修改后的完整代码:
resource "newrelic_nrql_alert_condition" "additional_alerts_condition" { count = length(var.additional_alerts) account_id = var.newrelic_account_id policy_id = newrelic_alert_policy.policy.id name = format("%s-%s", local.container_name, var.additional_alerts[count.index].name_suffix) type = "static" runbook_url = var.runbook_url enabled = var.additional_alerts[count.index].enabled # 动态生成warning块:只有warning_enabled为true时才创建 dynamic "warning" { for_each = var.additional_alerts[count.index].warning_enabled ? [1] : [] content { operator = var.additional_alerts[count.index].operator threshold = var.additional_alerts[count.index].warning_threshold threshold_duration = var.additional_alerts[count.index].duration threshold_occurrences = var.additional_alerts[count.index].occurrences # 注意:原代码里拼错了,是occurrences不是occurences } } critical { operator = var.additional_alerts[count.index].operator threshold = var.additional_alerts[count.index].critical_threshold threshold_duration = var.additional_alerts[count.index].duration threshold_occurrences = var.additional_alerts[count.index].occurrences } nrql { query = var.additional_alerts[count.index].query } aggregation_window = 60 aggregation_method = "event_flow" aggregation_delay = 120 slide_by = 30 violation_time_limit_seconds = 3600 }
代码说明
dynamic "warning"用for_each控制生成逻辑:当warning_enabled为true时,传一个单元素列表[1],就生成一个warning块;为false时传空列表,直接跳过该块。- 顺便修正了原代码里的拼写错误:
occurences改成occurrences,免得后续出现配置问题。
替代方案:拆分列表(不推荐)
如果非要拆成两个资源,得先把原列表过滤成两个子列表,再用子列表长度作为count值:
# 先把原列表分成带warning和不带warning的两组 locals { alerts_with_warning = [for alert in var.additional_alerts : alert if alert.warning_enabled] alerts_without_warning = [for alert in var.additional_alerts : alert if !alert.warning_enabled] } # 生成带warning的告警资源 resource "newrelic_nrql_alert_condition" "with_warning" { count = length(local.alerts_with_warning) account_id = var.newrelic_account_id policy_id = newrelic_alert_policy.policy.id name = format("%s-%s", local.container_name, local.alerts_with_warning[count.index].name_suffix) type = "static" runbook_url = var.runbook_url enabled = local.alerts_with_warning[count.index].enabled warning { operator = local.alerts_with_warning[count.index].operator threshold = local.alerts_with_warning[count.index].warning_threshold threshold_duration = local.alerts_with_warning[count.index].duration threshold_occurrences = local.alerts_with_warning[count.index].occurrences } critical { operator = local.alerts_with_warning[count.index].operator threshold = local.alerts_with_warning[count.index].critical_threshold threshold_duration = local.alerts_with_warning[count.index].duration threshold_occurrences = local.alerts_with_warning[count.index].occurrences } nrql { query = local.alerts_with_warning[count.index].query } aggregation_window = 60 aggregation_method = "event_flow" aggregation_delay = 120 slide_by = 30 violation_time_limit_seconds = 3600 } # 生成不带warning的告警资源 resource "newrelic_nrql_alert_condition" "without_warning" { count = length(local.alerts_without_warning) account_id = var.newrelic_account_id policy_id = newrelic_alert_policy.policy.id name = format("%s-%s", local.container_name, local.alerts_without_warning[count.index].name_suffix) type = "static" runbook_url = var.runbook_url enabled = local.alerts_without_warning[count.index].enabled critical { operator = local.alerts_without_warning[count.index].operator threshold = local.alerts_without_warning[count.index].critical_threshold threshold_duration = local.alerts_without_warning[count.index].duration threshold_occurrences = local.alerts_without_warning[count.index].occurrences } nrql { query = local.alerts_without_warning[count.index].query } aggregation_window = 60 aggregation_method = "event_flow" aggregation_delay = 120 slide_by = 30 violation_time_limit_seconds = 3600 }
但这种写法会导致大量代码重复,维护成本高,所以优先推荐动态块的实现方案。
内容的提问来源于stack exchange,提问作者Aleksey Kurkov
相关产品推荐
相关产品推荐

