如何通过Terraform在单个AWS VPC中创建多台EC2实例?
问题描述
- 能否通过Terraform在单个AWS VPC中创建多台EC2实例?
- 此前每次创建实例都新建VPC,耗尽AWS区域5个VPC配额后无法创建第6台实例。
- 尝试导入现有VPC及关联资源后,出现SSH无法访问实例、user_data中的
setting_instance.py脚本不执行的问题。 - 需要最大化复用VPC、子网等基础资源的方案,以及现有Terraform代码的优化建议。
解决方案与代码优化
一、单个VPC中创建多台EC2实例的核心思路
复用VPC、子网、安全组、路由表等基础网络资源,仅对EC2实例、弹性IP(如需要)等实例级资源进行批量创建,使用Terraform的count或for_each实现批量部署。
二、解决SSH访问与user_data执行问题
SSH无法访问的排查点
- 确认安全组的22端口规则已正确关联到实例所在子网/实例,源地址配置符合需求(建议限制为你的公网IP,而非全开放)。
- 实例需具备公网IP:可通过子网开启
map_public_ip_on_launch自动分配,或绑定弹性IP。 - 确认密钥对
key_name与实例所在区域匹配,本地私钥文件权限设置为600。 - 导入现有资源时,需确保路由表已关联子网、互联网网关已绑定VPC,实例出站流量正常。
user_data脚本不执行的解决方法
- Ubuntu系统依赖
cloud-init处理user_data,确保脚本开头的#!/bin/bash格式正确。 - 若
setting_instance.py未预存在实例中,需先通过user_data下载脚本(例如从S3拉取),示例:#!/bin/bash apt update && apt install -y python3 aws s3 cp s3://your-bucket/setting_instance.py /home/ubuntu/ python3 /home/ubuntu/setting_instance.py - 查看cloud-init日志排查问题:
cat /var/log/cloud-init.log或cat /var/log/cloud-init-output.log。
三、Terraform代码优化建议
- 移除硬编码凭证:不要在provider中直接写
access_key和secret_key,改用环境变量AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY或AWS凭证文件~/.aws/credentials。 - 简化网络配置:无需手动创建网络接口,EC2实例可直接关联子网和安全组,自动分配私IP。
- 批量创建实例:使用
count参数批量生成多台实例,复用基础资源。 - 弹性IP关联优化:直接将弹性IP绑定到EC2实例,无需通过网卡中转。
- 移除冗余依赖:Terraform会自动处理资源依赖,无需手动添加
depends_on(除非特殊场景)。
优化后的示例代码
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 3.0" } } } # AWS Provider配置(使用环境变量或凭证文件,避免硬编码) provider "aws" { region = "us-east-2" } # 1. 创建VPC resource "aws_vpc" "prod-vpc" { cidr_block = "10.0.0.0/16" tags = { Name = "production" } } # 2. 创建互联网网关 resource "aws_internet_gateway" "gw" { vpc_id = aws_vpc.prod-vpc.id tags = { Name = "prod-igw" } } # 3. 创建路由表 resource "aws_route_table" "prod-route-table" { vpc_id = aws_vpc.prod-vpc.id route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.gw.id } tags = { Name = "Prod" } } # 4. 创建子网(开启自动分配公网IP) resource "aws_subnet" "prod-subnet" { vpc_id = aws_vpc.prod-vpc.id cidr_block = "10.0.1.0/24" availability_zone = "us-east-2a" map_public_ip_on_launch = true # 实例创建时自动分配公网IP tags = { Name = "prod-subnet" } } # 5. 子网关联路由表 resource "aws_route_table_association" "prod-subnet-assoc" { subnet_id = aws_subnet.prod-subnet.id route_table_id = aws_route_table.prod-route-table.id } # 6. 安全组配置 resource "aws_security_group" "allow_web" { name = "allow_web_traffic" description = "Allow Web inbound traffic" vpc_id = aws_vpc.prod-vpc.id ingress { description = "HTTPS" from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { description = "Custom Port" from_port = 8000 to_port = 8000 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { description = "HTTP" from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { description = "SSH" from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] # 建议改为你的公网IP,提升安全性 } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "allow_web" } } # 7. 批量创建EC2实例(示例创建3台) resource "aws_instance" "web-server" { count = 3 # 实例数量 ami = var.AMI_ID instance_type = "g4dn.xlarge" availability_zone = "us-east-2a" key_name = "us-east-2" subnet_id = aws_subnet.prod-subnet.id vpc_security_group_ids = [aws_security_group.allow_web.id] root_block_device { volume_size = "200" } iam_instance_profile = aws_iam_instance_profile.training_profile.name user_data = <<-EOF #!/bin/bash # 确保python3已安装 apt update && apt install -y python3 # 示例:若脚本在S3,先下载再执行 # aws s3 cp s3://your-bucket/setting_instance.py /home/ubuntu/ python3 /home/ubuntu/setting_instance.py EOF tags = { Name = "${var.INSTANCE_NAME}-${count.index + 1}" } } # 8. 批量创建弹性IP(可选) resource "aws_eip" "web-server-eip" { count = 3 instance = aws_instance.web-server[count.index].id vpc = true tags = { Name = "${var.INSTANCE_NAME}-eip-${count.index + 1}" } } # 输出所有实例的公网IP output "server_public_ips" { value = [for instance in aws_instance.web-server : instance.public_ip] } # 输出所有弹性IP(如果使用) output "eip_addresses" { value = [for eip in aws_eip.web-server-eip : eip.public_ip] }
内容的提问来源于stack exchange,提问作者kiran pradeep
相关产品推荐
相关产品推荐

