Terraform:AWS VPC+EC2+EBS
Terraform AWS VPC+EC2+EBS数据卷完整Demo详解
这是VPC+EC2架构的存储扩展版,在原有网络和计算资源基础上,新增了独立的EBS数据卷并挂载到EC2实例,实现了计算与存储分离——这是AWS上持久化存储数据的标准方式。
一、核心功能总结
✅ 保留了之前完整的VPC网络架构(公网/私网子网、IGW、NAT网关)
✅ 保留了可SSH登录的公网EC2实例
✅ 新增:创建一个20GB的独立EBS数据卷
✅ 新增:将EBS卷自动挂载到EC2实例的/dev/xvdh设备
✅ 提供了完整的格式化、挂载、开机自动挂载的手动操作流程
二、整体架构图
互联网
↓
Internet Gateway
↓
┌─────────────────────────────────────────────────┐
│ VPC (10.0.0.0/16) │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ 可用区eu-west-1a │ │ 可用区eu-west-1b │ │
│ │ ┌─────────┐ │ │ ┌─────────┐ │ │
│ │ │公网子网1│ │ │ │公网子网2│ │ │
│ │ │10.0.1.0/24│ │ │ │10.0.2.0/24│ │ │
│ │ └─────────┘ │ │ └─────────┘ │ │
│ │ ↓ │ │ │ │
│ │ ┌─────────┐ │ │ │ │
│ │ │EC2实例 │ │ │ │ │
│ │ │(根卷8GB)│ │ │ │ │
│ │ └─────────┘ │ │ │ │
│ │ ↓ │ │ │ │
│ │ ┌─────────┐ │ │ │ │
│ │ │EBS数据卷│ │ │ │ │
│ │ │(20GB) │ │ │ │ │
│ │ └─────────┘ │ │ │ │
│ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────┘
关键区别:EC2实例自带一个根卷(默认8GB,用于安装操作系统),而我们新增的是独立的数据卷,专门用于存储业务数据。
三、核心代码逐行解析(instance.tf)
1. 原有EC2实例代码(无变化)
resource "aws_instance" "example" {
ami = var.AMIS[var.AWS_REGION] # 从变量中获取对应区域的Ubuntu AMI
instance_type = "t2.micro" # 免费套餐可用
subnet_id = aws_subnet.main-public-1.id # 部署在eu-west-1a公网子网
vpc_security_group_ids = [aws_security_group.allow-ssh.id] # 关联SSH安全组
key_name = aws_key_pair.mykeypair.key_name # 关联SSH密钥对
}
2. 新增:创建独立EBS数据卷
resource "aws_ebs_volume" "ebs-volume-1" {
availability_zone = "eu-west-1a" # 🔥 必须和EC2实例在同一个可用区!
size = 20 # 卷大小,单位GB
type = "gp2" # 卷类型,通用型SSD
tags = {
Name = "extra volume data"
}
}
关键参数详解:
availability_zone:最重要的参数。EBS是可用区级别的资源,只能挂载到同一个可用区的EC2实例上。如果这里写eu-west-1b,而实例在eu-west-1a,挂载会直接失败。size:卷的大小,gp2类型最小1GB,最大16TB。type:卷类型,决定了性能和价格:gp2:旧版通用型SSD,已不推荐gp3:新版通用型SSD,价格比gp2低20%,性能更高,生产环境必须用这个io1/io2:高性能SSD,用于数据库等IO密集型应用st1/sc1:吞吐量优化型HDD,用于大数据仓库
3. 新增:将EBS卷挂载到EC2实例
resource "aws_volume_attachment" "ebs-volume-1-attachment" {
device_name = "/dev/xvdh" # 设备名,AWS推荐使用/dev/xvdh到/dev/xvdz
volume_id = aws_ebs_volume.ebs-volume-1.id # 要挂载的EBS卷ID
instance_id = aws_instance.example.id # 要挂载到的EC2实例ID
}
关键参数详解:
device_name:Linux系统中识别这个卷的设备路径。- 系统根卷通常是
/dev/xvda - AWS推荐从
/dev/xvdh开始使用,避免和系统保留的设备名冲突 - 注意:在某些Linux发行版中,实际显示的设备名可能是
/dev/nvme1n1(Nitro实例),但挂载时写/dev/xvdh仍然有效
- 系统根卷通常是
四、完整部署与验证流程
1. 部署所有资源
cd demo-9_EBS
terraform init # 初始化
terraform plan # 预览
terraform apply # 确认部署
Terraform会自动按顺序创建:VPC → 子网 → IGW → NAT → 安全组 → 密钥对 → EC2实例 → EBS卷 → 挂载卷。
2. SSH登录实例
# 获取实例公网IP
terraform output ec2_public_ip
# 登录
ssh -i mykey ubuntu@<实例公网IP>
3. 验证EBS卷已挂载到系统
lsblk
预期输出:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda 202:0 0 8G 0 disk
└─xvda1 202:1 0 8G 0 part /
xvdf 202:80 0 20G 0 disk # 这就是我们新增的EBS卷
注意:这里显示的是
xvdf而不是xvdh是正常现象,不同实例类型的设备名映射可能不同。
4. 格式化EBS卷(仅第一次需要)
新创建的EBS卷是空白的,没有文件系统,必须格式化后才能使用:
sudo mkfs -t ext4 /dev/xvdf
警告:格式化会删除卷上的所有数据,已经有数据的卷不要执行这个命令!
5. 创建挂载点并挂载
# 创建挂载目录
sudo mkdir /mnt/data
# 将卷挂载到/mnt/data目录
sudo mount /dev/xvdf /mnt/data
6. 验证挂载成功
df -h
预期输出:
Filesystem Size Used Avail Use% Mounted on
/dev/xvda1 7.7G 1.3G 6.5G 17% /
/dev/xvdf 20G 45M 19G 1% /mnt/data # 挂载成功
7. 测试写入数据
echo "Hello EBS!" | sudo tee /mnt/data/test.txt
cat /mnt/data/test.txt
如果能正常输出"Hello EBS!",说明卷可以正常读写。
8. 配置开机自动挂载(可选但强烈推荐)
如果不配置,重启实例后挂载会消失,需要重新手动挂载。
# 将挂载信息写入/etc/fstab文件
echo '/dev/xvdf /mnt/data ext4 defaults,nofail 0 2' | sudo tee -a /etc/fstab
# 验证fstab配置是否正确(非常重要!)
sudo mount -a
关键参数说明:
nofail:最重要的参数。如果没有这个参数,当EBS卷挂载失败时,实例会无法启动!0 2:dump和fsck选项,数据卷一般设置为0 2。
五、EBS核心概念与原理
1. 根卷 vs 数据卷
| 特性 | 根卷 | 数据卷 |
|---|---|---|
| 用途 | 安装操作系统 | 存储业务数据 |
| 创建方式 | 随EC2实例自动创建 | 手动独立创建 |
| 生命周期 | 默认随实例终止而删除 | 默认独立于实例,实例终止后卷仍然存在 |
| 大小 | 默认8GB,可调整 | 自定义,1GB-16TB |
2. EBS的持久性
EBS卷的数据会自动在同一个可用区内复制三份,可用性高达99.999%。即使EC2实例故障或被终止,EBS卷上的数据仍然安全,可以挂载到其他实例上。
3. 为什么需要独立的数据卷?
- 数据安全:实例终止时,根卷会被删除,但数据卷会保留
- 灵活扩展:可以随时扩容数据卷,不需要重建实例
- 性能隔离:数据卷的IO性能不会和根卷竞争
- 备份方便:可以单独对数据卷创建快照备份
六、生产环境最佳实践
-
使用gp3代替gp2:gp3价格更低,性能更高,是当前的默认推荐类型
type = "gp3" -
明确设置卷的删除策略:默认情况下,数据卷在实例终止时会保留。如果希望实例终止时自动删除数据卷,可以添加:
resource "aws_volume_attachment" "ebs-volume-1-attachment" { # ... 其他参数 delete_on_termination = true } -
不要硬编码可用区:将可用区抽成变量,避免和实例的可用区不一致:
resource "aws_ebs_volume" "ebs-volume-1" { availability_zone = aws_instance.example.availability_zone # ... 其他参数 }这样无论实例部署在哪个可用区,EBS卷都会自动跟随。
-
定期创建快照备份:EBS快照是增量备份,成本很低,可以有效防止数据丢失。
-
对于数据库等IO密集型应用:使用io2卷,并配置适当的IOPS。
七、常见坑点与排错
- 挂载失败:VolumeInUse:EBS卷已经挂载到其他实例上,或者之前的挂载没有正常卸载。
- 挂载失败:InvalidVolume.ZoneMismatch:EBS卷和EC2实例不在同一个可用区。
- 重启实例后挂载消失:没有配置/etc/fstab自动挂载。
- 实例无法启动:fstab配置错误,特别是没有加
nofail参数。 - 无法写入数据:没有格式化卷,或者挂载目录权限不正确。
八、进阶改进
- 添加outputs.tf输出EBS卷ID和挂载点信息
- 使用user_data自动完成格式化和挂载操作,不需要手动执行命令
- 配置EBS卷的自动快照策略
- 实现EBS卷的在线扩容(不需要停机)
更多推荐
所有评论(0)