使用Terraform模块创建多EC2实例,用户数据文件名做变量报错求助
如何通过Terraform变量传递用户数据文件名创建多EC2实例并解决报错
完全可以将用户数据文件名作为变量使用,你的报错是代码中的两处错误导致的,下面是问题分析和修正方案:
报错原因
报错信息里的代码是 filename = file("${each.value.user_data}"),但你提供的local_file配置代码却写的是filename = "${path.cwd}/${each.value.user_data}",这说明实际运行的代码存在两处问题:
local_file数据源的filename参数只需要文件路径字符串,不需要用file()函数包裹(file()是用来读取文件内容的函数,不能直接给filename参数)- 路径使用
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
相关产品推荐
相关产品推荐

