Terraform For_Each结合Azure Pipeline单环境部署报错求助
问题:Terraform单环境部署Azure监控告警时触发索引错误
使用Terraform的alerts.tf配置在Sandbox、Dev、Test三个环境部署Azure监控告警和动作组,通过for_each循环在main.tf中调用创建资源。全环境部署正常,但仅部署DEV环境时触发如下错误:
Error: Invalid index local.monitor_alerts is object with one attribute "SANDBOX" environment is "DEV" The given key does not identify an element in this collection value.
相关配置文件
alerts.tf
locals { alerts_resource_group = "rg-resources" } locals { monitor_alert_webhook_service_name = "apply" monitor_alerts = { SANDBOX = { apply_sys_failure = { alert_type = "metric" name = "service-alert-failure" resource_group_name = var.rg-monitor-alerts location = var.location description = "Sandbox - One or more API calls to the backend service have failed" scopes = [data.azurerm_application_insights.service_app_insights.id] auto_mitigation_enabled = false enabled = true evaluation_frequency = "PT1M" window_duration = "PT5M" severity = 1 target_resource_type = "Microsoft.Insights/components" skip_query_validation = "false" criteria = [ { metric_namespace = "Azure.ApplicationInsights" metric_name = "SubmitOrder Failures" aggregation = "Count" operator = "GreaterThan" threshold = 0 skip_metric_validation = false } ] action = [ { action_group_id = try(module.azurerm_monitor_action_group["rg_engineers"].action_group.id, "") webhook_properties = { service = local.monitor_alert_webhook_service_name } } ] } } DEV = { apply_sys_failure = { alert_type = "metric" name = "service-alert-failure" resource_group_name = var.rg-monitor-alerts location = var.location description = "Dev - One or more API calls to the backend service have failed" scopes = [data.azurerm_application_insights.service_app_insights.id] auto_mitigation_enabled = false enabled = true evaluation_frequency = "PT1M" window_duration = "PT5M" severity = 1 target_resource_type = "Microsoft.Insights/components" skip_query_validation = "false" criteria = [ { metric_namespace = "Azure.ApplicationInsights" metric_name = "SubmitOrder Failures" aggregation = "Count" operator = "GreaterThan" threshold = 0 skip_metric_validation = false } ] action = [ { action_group_id = try(module.azurerm_monitor_action_group["rg_engineers"].action_group.id, "") webhook_properties = { service = local.monitor_alert_webhook_service_name } } ] } } TEST = { apply_sys_failure = { alert_type = "metric" name = "service-alert-failure" resource_group_name = var.rg-monitor-alerts location = var.location description = "TEST - One or more API calls to the backend service have failed" scopes = [data.azurerm_application_insights.service_app_insights.id] auto_mitigation_enabled = false enabled = true evaluation_frequency = "PT1M" window_duration = "PT5M" severity = 1 target_resource_type = "Microsoft.Insights/components" skip_query_validation = "false" criteria = [ { metric_namespace = "Azure.ApplicationInsights" metric_name = "SubmitOrder Failures" aggregation = "Count" operator = "GreaterThan" threshold = 0 skip_metric_validation = false } ] action = [ { action_group_id = try(module.azurerm_monitor_action_group["rg_engineers"].action_group.id, "") webhook_properties = { service = local.monitor_alert_webhook_service_name } } ] } } } monitor_action_groups = { SANDBOX = { rg_engineers = { name = "acg-rg-engineers" resource_group_name = local.alerts_resource_group short_name = "RgEng" enabled = true email_receiver = [ { name = "Incidents Mailbox" email_address = "rgincidents@rg.com" } ] } } DEV = { rg_engineers = { name = "acg-rg-engineers" resource_group_name = local.alerts_resource_group short_name = "RgEng" enabled = true email_receiver = [ { name = "Incidents Mailbox" email_address = "rgincidents@rg.com" } ] } } TEST = { rg_engineers = { name = "acg-rg-engineers" resource_group_name = local.alerts_resource_group short_name = "RgEng" enabled = true email_receiver = [ { name = "Incidents Mailbox" email_address = "rgincidents@rg.com" } ] } } } }
main.tf
# Create Alerts module "azurerm_monitor_alert" { source = "git::https://[ADO-URL]/_git/module-tf-azurerm-monitor-alert" for_each = local.monitor_alerts alert = each.value resource_group_name = each.value.resource_group_name tags = var.tags depends_on = [ local.alerts_resource_group ] } # Create Action Groups module "azurerm_monitor_action_group" { source = "git::https://[ADO-URL]/_git/module-tf-azurerm-monitor-alert" for_each = local.monitor_alerts action_group = each.value resource_group_name = each.value.resource_group_name tags = var.tags depends_on = [ local.alerts_resource_group ] }
解决方案
核心问题分析
错误根源有两点:
main.tf中动作组模块的for_each错误绑定了local.monitor_alerts,应该使用动作组专属的local.monitor_action_groups;- 告警配置中引用动作组ID时,没有按环境维度索引模块实例,导致跨环境查找资源失败。
具体修复步骤
修正动作组模块的
for_each数据源
在main.tf中,将动作组模块的for_each改为指向local.monitor_action_groups:# Create Action Groups module "azurerm_monitor_action_group" { source = "git::https://[ADO-URL]/_git/module-tf-azurerm-monitor-alert" for_each = local.monitor_action_groups action_group = each.value resource_group_name = each.value.resource_group_name tags = var.tags depends_on = [ local.alerts_resource_group ] }按环境维度引用动作组实例
在alerts.tf的告警配置中,添加环境索引,确保只调用当前环境的动作组资源(假设存在environment变量传入部署环境名):action = [ { action_group_id = try(module.azurerm_monitor_action_group[upper(var.environment)].rg_engineers.action_group.id, "") webhook_properties = { service = local.monitor_alert_webhook_service_name } } ]用
upper()统一转为大写,匹配local配置中的键名格式。添加环境过滤逻辑(可选但推荐)
如果Pipeline通过变量指定部署环境,在alerts.tf中添加过滤逻辑,只保留当前环境的配置:locals { filtered_monitor_alerts = { for env, alerts in local.monitor_alerts : env => alerts if env == upper(var.environment) } filtered_monitor_action_groups = { for env, groups in local.monitor_action_groups : env => groups if env == upper(var.environment) } }然后在
main.tf中,模块的for_each改为使用过滤后的变量:module "azurerm_monitor_alert" { source = "git::https://[ADO-URL]/_git/module-tf-azurerm-monitor-alert" for_each = local.filtered_monitor_alerts alert = each.value resource_group_name = each.value.resource_group_name tags = var.tags depends_on = [ local.alerts_resource_group ] } module "azurerm_monitor_action_group" { source = "git::https://[ADO-URL]/_git/module-tf-azurerm-monitor-alert" for_each = local.filtered_monitor_action_groups action_group = each.value resource_group_name = each.value.resource_group_name tags = var.tags depends_on = [ local.alerts_resource_group ] }
验证修复
部署单个环境时,Terraform只会处理当前环境的配置,告警引用的动作组也会指向对应环境的实例,避免索引错误。
内容的提问来源于stack exchange,提问作者hitman126
相关产品推荐
相关产品推荐

