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 = "" }
问题分析与修复
核心问题点
- 动态块引用错误:动态块中错误引用全局的
var.ec2_instances.ebs_volume,应引用当前实例的each.value.ebs_volume - 变量字段不匹配:
variables.tf中ebs_volume定义的字段是volume_location,但terraform.tfvars中使用的是volume_name,字段名不一致 - for表达式语法错误:原动态块中的for表达式格式混乱,无需额外构造映射,直接遍历实例的EBS卷列表即可
- 标签变量名错误:
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
相关产品推荐
相关产品推荐

