You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Terraform遍历含Map的列表按需创建资源报错求助

问题分析与修复建议

原始配置与代码

JSON配置

{"serviceConfig": {"city_shared": {"schedules": [{"EcsServiceRestartOrder": ["redis","redis2","redisblahblah"],"Description": "daily","CityRestartCronExpression": "cron(0 4 * * ? *)","CityRestartEnabled": true},{"EcsServiceRestartOrder": ["redis-stg"],"Description": "weekly","CityRestartCronExpression" : "cron(0 4 * * 1 *)","CityRestartEnabled": true}],"MonitoringStartUTC": "0500","MonitoringEndUTC": "2000"}}}

原始Terraform代码

resource "aws_cloudwatch_event_rule" "scheduled_restart" {
  for_each = { for i in var.serviceConfig.city_shared.schedules : i.Description => i
  if i.CityRestartEnabled == true }

  name                = "${local.awsResourceName}-${each.value.Description}-scheduled_restart"
  schedule_expression = each.value.CityRestartCronExpression

  is_enabled = each.value.CityRestartEnabled
}

resource "aws_iam_role" "cloudwatch_event_scheduled_restart" {
  for_each = { for i in var.serviceConfig.city_shared.schedules : i.Description => i
  if var.serviceConfig.city_shared.schedules.CityRestartEnabled == true }

  name = "${join("", [local.multiRegionCityPrefix, local.awsResourceName])}-cloudwatch_event_scheduled_restart"

  assume_role_policy = jsonencode({
    "Version" : "2012-10-17",
    "Statement" : [
      {
        "Effect" : "Allow",
        "Principal" : {
          "Service" : "events.amazonaws.com"
        },
        "Action" : "sts:AssumeRole"
      }
    ]
    }
  )

  tags = {
    tag-key = "${join("", [local.multiRegionCityPrefix, local.awsResourceName])}-cloudwatch_event_scheduled_restart"
  }
}

错误原因解析

第一个错误(aws_iam_role部分)

Error: Unsupported attribute

on cloudwatch_events.tf line 3, in resource "aws_iam_role" "cloudwatch_event_scheduled_restart":
3: if var.serviceConfig.city_shared.schedules.CityRestartEnabled == true }
|----------------
| var.serviceConfig.city_shared.schedules is list of object with 2 elements

This value does not have any attributes.

原因:var.serviceConfig.city_shared.schedules是对象列表,直接访问列表的CityRestartEnabled属性逻辑错误,应该引用遍历的单个对象i.CityRestartEnabled,而非整个列表。

第二个错误(aws_cloudwatch_event_rule部分)

Error: Unsupported attribute

on cloudwatch_events.tf line 52, in resource "aws_cloudwatch_event_rule" "scheduled_restart":
52: for_each = { for i in var.serviceConfig.city_shared.schedules : i.Description => i

This object does not have an attribute named "Description".

原因:var.serviceConfig变量未明确类型定义,Terraform松散类型推断无法识别schedules列表中对象的Description属性。

修复方案

1. 明确变量类型定义

在variables.tf中添加变量类型约束,确保Terraform能识别对象属性:

variable "serviceConfig" {
  type = object({
    city_shared = object({
      schedules = list(object({
        EcsServiceRestartOrder     = list(string)
        Description                = string
        CityRestartCronExpression  = string
        CityRestartEnabled         = bool
      }))
      MonitoringStartUTC = string
      MonitoringEndUTC   = string
    })
  })
  description = "Service configuration"
}

2. 修正aws_iam_role的for_each逻辑

  • 如果只需要单个IAM角色给所有规则使用,直接移除for_each:
resource "aws_iam_role" "cloudwatch_event_scheduled_restart" {
  name = "${join("", [local.multiRegionCityPrefix, local.awsResourceName])}-cloudwatch_event_scheduled_restart"

  assume_role_policy = jsonencode({
    "Version" : "2012-10-17",
    "Statement" : [
      {
        "Effect" : "Allow",
        "Principal" : {
          "Service" : "events.amazonaws.com"
        },
        "Action" : "sts:AssumeRole"
      }
    ]
  })

  tags = {
    tag-key = "${join("", [local.multiRegionCityPrefix, local.awsResourceName])}-cloudwatch_event_scheduled_restart"
  }
}
  • 如果需要每个启用的schedule对应一个角色,修正for_each的条件判断:
resource "aws_iam_role" "cloudwatch_event_scheduled_restart" {
  for_each = { for i in var.serviceConfig.city_shared.schedules : i.Description => i
  if i.CityRestartEnabled == true }

  name = "${join("", [local.multiRegionCityPrefix, local.awsResourceName])}-${each.value.Description}-cloudwatch_event_scheduled_restart"

  assume_role_policy = jsonencode({
    "Version" : "2012-10-17",
    "Statement" : [
      {
        "Effect" : "Allow",
        "Principal" : {
          "Service" : "events.amazonaws.com"
        },
        "Action" : "sts:AssumeRole"
      }
    ]
  })

  tags = {
    tag-key = "${join("", [local.multiRegionCityPrefix, local.awsResourceName])}-${each.value.Description}-cloudwatch_event_scheduled_restart"
  }
}

3. 验证aws_cloudwatch_event_rule逻辑

第一个资源的for_each逻辑本身正确,只要变量类型定义完成,i.Description就能被正常识别。

最终验证

执行terraform plan,确认能正常遍历启用的schedule,创建对应的CloudWatch Event规则及正确的IAM角色。

内容的提问来源于stack exchange,提问作者fraserc182

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 03:35:42