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

使用Terraform模块创建多EC2实例,用户数据文件名做变量报错求助

如何通过Terraform变量传递用户数据文件名创建多EC2实例并解决报错

完全可以将用户数据文件名作为变量使用,你的报错是代码中的两处错误导致的,下面是问题分析和修正方案:

报错原因

报错信息里的代码是 filename = file("${each.value.user_data}"),但你提供的local_file配置代码却写的是filename = "${path.cwd}/${each.value.user_data}",这说明实际运行的代码存在两处问题:

  1. local_file数据源的filename参数只需要文件路径字符串,不需要用file()函数包裹(file()是用来读取文件内容的函数,不能直接给filename参数)
  2. 路径使用path.cwd存在风险,path.cwd是执行Terraform命令的目录,而模块内的文件路径建议用path.module(当前模块所在目录)更可靠

修正后的完整代码

1. 模块内的local_file数据源配置

data "local_file" "user_data" {
  for_each = { for ec2 in var.ec2_instances : ec2.name => ec2 }
  filename = "${path.module}/${each.value.user_data}" # 用path.module确保模块内路径正确
}

2. 模块内的EC2实例资源配置

resource "aws_instance" "instances" {
  for_each = { for instance in var.ec2_instances : instance.name => instance }

  ami                    = each.value.ami
  instance_type          = each.value.type
  cpu_core_count         = each.value.cpu_core
  user_data_base64       = base64encode(data.local_file.user_data[each.key].rendered) # 用each.key直接匹配for_each的key,更简洁
}

3. tfvars变量配置(补充引号和必填字段)

ec2_instances= [
  {
    name = "test1"
    user_data = "ec2_1.sh"
    ami = "ami-xxxxxx" # 替换为实际可用的AMI ID
    type = "t2.micro" # 替换为实际需要的实例类型
    cpu_core = 1
  },
  {
    name = "test2"
    user_data = "ec2_2.sh"
    ami = "ami-xxxxxx"
    type = "t2.micro"
    cpu_core = 1
  }
]

注意:tfvars中的字符串值必须用双引号包裹,否则Terraform会将其识别为标识符而非字符串。

4. 模块调用配置(保持不变)

module "ec2_app_demo" {
  source = "./aws-ec2-application/"

  ec2_instances     = var.ec2_instances
}

文件夹结构建议

确保用户数据文件和模块代码放在同一目录下,示例结构:

.
├── module.tf
├── terraform.tfvars
└── aws-ec2-application/
    ├── main.tf
    ├── variables.tf
    ├── ec2_1.sh
    └── ec2_2.sh

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 01:25:24