Terraform模块间输出传递异常:安全组ID无法传入EC2实例
Terraform模块间输出传递问题:安全组ID传入EC2实例
问题
需要将security-groups模块创建的安全组ID传入vm-deploy模块中EC2实例的vpc_security_group_ids参数,执行terraform plan时出现报错。
目录结构
├── main.tf ├── modules │ ├── security-groups │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ └── vm-deploy │ ├── main.tf │ ├── output.tf │ └── variables.tf └── variables.tf
代码片段
根目录main.tf
module "security-groups" { source = "./modules/security-groups" for_each = var.security-groups name = each.value.name description = each.value.description vpc_id = data.aws_vpc.vpc.id } module "vm-deploy" { source = "./modules/vm-deploy" for_each = var.instances ami = each.value.ami iam_instance_role = each.value.iam_instance_role instance_type = each.value.instance_type key_name = each.value.key_name private_ip = each.value.private_ip subnet_id = each.value.subnet_id user_data = each.value.user_data vpc_security_group_ids = [module.security-groups.id] kms_key_id = each.value.kms_key_id root_size = each.value.root_size }
modules/security-groups/main.tf
resource "aws_security_group" "security_group" { name = var.name description = var.description vpc_id = var.vpc_id tags = var.tags }
modules/security-groups/outputs.tf
output "id" { value = aws_security_group.security_group.id }
modules/vm-deploy/main.tf
resource "aws_instance" "ec2_instance" { ami = var.ami iam_instance_profile = var.iam_instance_role instance_type = var.instance_type key_name = var.key_name private_ip = var.private_ip subnet_id = var.subnet_id user_data = var.user_data vpc_security_group_ids = var.security_group_ids root_block_device { delete_on_termination = false encrypted = true kms_key_id = var.kms_key_id volume_size = var.root_size volume_type = "gp2" } }
报错信息
│ on main.tf line 45, in module "vm-deploy": │ 45: vpc_security_group_ids= [module.security-groups.id] │ ├──────────────── │ │ module.security-groups 是包含1个属性"sg-default"的对象 │ │ 该对象没有名为"id"的属性。
解决方案
1. 处理for_each生成的模块实例集合
security-groups模块使用了for_each,因此module.security-groups不是单个模块实例,而是一个映射对象,键为var.security-groups中的每个键(比如报错中的sg-default),值为对应的模块实例。要获取安全组ID,需要指定具体的键:
# 如果只有一个安全组,直接指定键 vpc_security_group_ids = [module.security-groups["sg-default"].id]
2. 关联VM与对应安全组(推荐)
如果需要每个VM对应不同的安全组,建议在var.instances中添加安全组标识字段(比如sg_key),然后动态获取:
# 根目录main.tf中修改vm-deploy模块参数 vpc_security_group_ids = [module.security-groups[each.value.sg_key].id]
同时确保var.instances的定义包含sg_key字段,指向var.security-groups中的对应键。
3. 修正变量名匹配问题
注意vm-deploy模块中使用的变量是var.security_group_ids,但根目录main.tf中传递的参数名是vpc_security_group_ids,需要保持一致:
- 要么修改
vm-deploy的variables.tf,将变量名改为vpc_security_group_ids; - 要么修改根目录main.tf中的参数名,改为
security_group_ids = [module.security-groups["sg-default"].id]。
内容的提问来源于stack exchange,提问作者virtualramblings
相关产品推荐
相关产品推荐

