Terraform创建AWS EC2报错IP不在子网范围问题排查
报错根因
这个报错和IP网段计算无关,核心是模块间参数传递、资源关联配置缺失,导致EC2实例根本没有被部署到你手动创建的192.168.1.0/24子网中,实际调度到了AWS账号下当前区域的默认VPC子网(默认VPC网段通常为172.31.0.0/16),硬编码的192.168.1.15当然不在默认子网的地址范围内。
具体配置问题点有3个:
- network模块没有通过output暴露创建的子网ID,Terraform的模块有命名空间隔离,跨模块无法直接访问模块内部的资源属性
- servers模块没有声明
subnet_id变量,也没有在aws_instance资源块中指定subnet_id参数,EC2启动时会自动选择默认VPC下的可用子网 - 根模块调用servers模块时的子网ID引用写法错误,就算network模块输出了子网ID,
module.network.aws_subnet也不是合法的模块输出引用
修复步骤
- 补全network模块的输出配置
在network/outputs.tf中添加子网ID输出,供其他模块调用:
output "subnet_id" { value = aws_subnet.subnet-1.id }
如果后续需要关联VPC其他属性,也可以一并输出,比如VPC ID、安全组ID等。
- 给servers模块添加变量声明并关联EC2资源
首先在servers/variables.tf中声明子网ID变量:
variable "subnet_id" { type = string description = "EC2实例部署的目标子网ID" }
然后修改servers/main.tf中的aws_instance资源块,添加subnet_id参数,指定实例部署到传入的目标子网:
resource "aws_instance" "bar" { ami = var.some_ami instance_type = "t3.medium" associate_public_ip_address = true subnet_id = var.subnet_id # 新增该行,关联目标子网 private_ip = "192.168.1.15" root_block_device { volume_size = "60" volume_type = "gp3" encrypted = true delete_on_termination = true } tags = { Name = "bar" } }
- 修正根模块的调用配置
修改根目录main.tf中模块调用的参数引用,关联network模块输出的子网ID,同时记得补充servers模块需要的AMI参数(当前配置中省略了该参数传值,实际部署也会报错):
module "network" { source = "./network" } module "servers" { source = "./servers" subnet_id = module.network.subnet_id # 修正为network模块的合法输出引用 some_ami = "ami-xxxxxx" # 替换为实际使用的AMI ID }
验证方式
修改完成后先执行terraform init加载模块配置更新,再执行terraform plan,查看计划结果中EC2实例的subnet_id属性是否和你手动创建的subnet-1 ID一致,确认无误后再执行部署即可。
内容的提问来源于stack exchange,提问作者Fresh
相关产品推荐
相关产品推荐

