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

Terraform嵌套循环问题:多EC2实例挂载多EBS卷失败

问题:嵌套循环创建带多EBS卷的EC2实例失败

尝试通过嵌套循环创建多个EC2实例,每个实例配置多个自定义挂载名称和大小的EBS卷,但动态块中的第二个for_each循环无法正常工作。

原配置文件

main.tf

# Create resources using for_each

resource "aws_instance" "ec2_instances" {
  for_each = { for inst in var.ec2_instances : inst.name => inst }
  # for_each = var.ec2_instances[].
  
  ami           = each.value.ami
  instance_type = each.value.instance_type
  key_name      = each.value.key_name
  
  
  tags = var.hp_standard_tags

  dynamic "ebs_block_device" {
    for_each = [for volume in var.ec2_instances.ebs_volume : volume.volume_name => volume {
      device_name = volume.volume_name,
      volume_size = volume.volume_size
    }]
    content {
      device_name           = ebs_block_device.value.device_name
      volume_type           = "gp3"
      volume_size           = ebs_block_device.value.volume_size
      delete_on_termination = true
    }
  }

#user_data = file("${path.module}/startup.sh")
}

variables.tf

variable "ec2_instances" {
  description = "List of EC2 instances"
  type = list(object({
    name               = string
    instance_type      = string
    ami                = string
    key_name           = string
    enable_autoscaling = bool
    ebs_volume = list(object({
      volume_size = string,
    volume_location = string }))
    })
  )
}

variable "standard_tags" {
  description = "Standard set of tags"
  type = object({
    last_review        = string,
    ticket             = string,
    app_name           = string,
    environment        = string,
    hpit_contact_email = string,
    hpit_cost_center   = string,
    hpit_criticality   = string,
    hpit_environment   = string,
    hpit_eprid         = string,
    hpit_mru           = string,
    hpit_role          = string,
    map_id             = string,
    map_prefix         = string
  })
  default = {
    last_review        = "07-12-2024",
    ticket             = "",
    app_name           = "",
    environment        = "dev",
    hpit_contact_email = "",
    hpit_cost_center   = "",
    hpit_criticality   = "",
    hpit_environment   = "",
    hpit_eprid         = "",
    hpit_mru           = "",
    hpit_role          = "",
    map_id             = "",
  map_prefix = "" }
}

variable "date" {
  description = "Run date for the tag"
  type        = string
  default     = "STRING" #"${formatdate("YYYY-MM-DD", timeadd(timestamp(), "24h"))}T00:00:00Z"
}

variable "role" {
  description = "dev aws account iam role to be assumed by core tf user"
  type        = string
  default     = ""
}

terraform.tfvars

# List of EC2 instances

ec2_instances = [
  {
    name               = "instance1"
    instance_type      = "t2.micro"
    ami                = "ami-00000000000" # Linux Golden Image Amazon Linux 2023
    key_name           = "your_key_pair_name1"
    enable_autoscaling = false
    ebs_volume = [
      {
        volume_size = "10",
        volume_name = "root"
      },
      {
        volume_size = "60",
        volume_name = "/dev/sg1"
      }
    ]
    #subnet
    #Tags

  },
  {
    name               = "instance2"
    instance_type      = "t2.small"
    ami                = "ami-00000000000" # Windows Golden Image Win 2022
    key_name           = "your_key_pair_name2"
    enable_autoscaling = true
    ebs_volume = [
      {
        volume_size = "10",
        volume_name = "root"
      },
      {
        volume_size = "60",
        volume_name = "/dev/sg1"
      }
    ]
  }
  # Add more instances as needed
]

standard_tags = {
  last_review        = "07-12-2024",
  ticket             = "SR0001",
  app_name           = "TEST",
  environment        = "dev",
  hpit_contact_email = "",
  hpit_cost_center   = "Number",
  hpit_criticality   = "low",
  hpit_environment   = "itg",
  hpit_eprid         = "38001",
  hpit_mru           = "",
  hpit_role          = "",
  map_id             = "",
  map_prefix         = ""
}

问题分析与修复

核心问题点

  1. 动态块引用错误:动态块中错误引用全局的var.ec2_instances.ebs_volume,应引用当前实例的each.value.ebs_volume
  2. 变量字段不匹配:variables.tf中ebs_volume定义的字段是volume_location,但terraform.tfvars中使用的是volume_name,字段名不一致
  3. for表达式语法错误:原动态块中的for表达式格式混乱,无需额外构造映射,直接遍历实例的EBS卷列表即可
  4. 标签变量名错误:tags = var.hp_standard_tags应为tags = var.standard_tags,与变量定义一致

修正后的代码

修正后的variables.tf(ebs_volume字段部分)

ebs_volume = list(object({
  volume_size = string,
  volume_name = string
}))

修正后的main.tf(动态块与标签部分)

resource "aws_instance" "ec2_instances" {
  for_each = { for inst in var.ec2_instances : inst.name => inst }
  
  ami           = each.value.ami
  instance_type = each.value.instance_type
  key_name      = each.value.key_name
  
  tags = var.standard_tags

  dynamic "ebs_block_device" {
    for_each = each.value.ebs_volume
    content {
      device_name           = ebs_block_device.value.volume_name
      volume_type           = "gp3"
      volume_size           = ebs_block_device.value.volume_size
      delete_on_termination = true
    }
  }
}

验证

执行terraform plan,会看到每个实例都会根据配置创建对应的EBS卷,动态块循环正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 13:04:51