14. EBS / EFS
EC2 や ECS にディスクをアタッチする方法。EBS は 1 台専用、EFS は複数台で共有。用途別に使い分けます。
この章の目次
EBS / EFS / S3 の使い分け
| EBS | EFS | S3 | |
|---|---|---|---|
| 形式 | ブロックストレージ | ファイルシステム (NFS) | オブジェクト |
| 同時接続 | 1 台(io2 のみ複数) | 複数 | 無制限 |
| レイテンシ | 最速 (μs) | 速 (ms) | 遅 (10ms-) |
| 料金 | 容量 + IOPS | 容量 + アクセス | 容量 + リクエスト |
| 用途 | DB / 起動ディスク | 共有ファイル / Web ルート | 静的アセット / バックアップ |
aws_ebs_volume
resource "aws_ebs_volume" "data" {
availability_zone = "ap-northeast-1a"
size = 100 # GB
type = "gp3"
iops = 3000 # gp3 は最低 3000、最大 16000
throughput = 125 # gp3 は最低 125 MiB/s、最大 1000
encrypted = true
kms_key_id = aws_kms_key.app.arn
tags = { Name = "data" }
lifecycle {
prevent_destroy = true # 本番データなら必須
}
}
EC2 にアタッチ
resource "aws_volume_attachment" "data" {
device_name = "/dev/sdf"
volume_id = aws_ebs_volume.data.id
instance_id = aws_instance.db.id
}
# EC2 内で
# sudo mkfs -t xfs /dev/nvme1n1 # 初回のみ
# sudo mkdir -p /mnt/data
# sudo mount /dev/nvme1n1 /mnt/data
# echo '/dev/nvme1n1 /mnt/data xfs defaults,nofail 0 2' | sudo tee -a /etc/fstab
EBS は 1 台の EC2 専有。デタッチして別 EC2 にアタッチは可能だが、同時接続は不可(io2 Multi-Attach を除く)。
EBS の種類
| type | 用途 | 性能 |
|---|---|---|
| gp3 | 汎用(デフォルト推奨) | 3000-16000 IOPS、125-1000 MiB/s。容量と独立に IOPS 設定可 |
| gp2(旧) | 使わない | 容量に IOPS が連動。gp3 より高い |
| io2 / io2 Block Express | 高 IOPS DB | 最大 256k IOPS、1ms 以下のレイテンシ |
| st1 / sc1 | 大容量シーケンシャル | HDD ベース、コールドストレージ用 |
2026 年現在は gp3 がほぼ常に正解。gp2 と比べて 20% 安く、性能も独立して上げられる。
EBS スナップショット
resource "aws_ebs_snapshot" "data" {
volume_id = aws_ebs_volume.data.id
description = "Manual snapshot of data volume"
tags = { Name = "data-snapshot" }
}
# 既存スナップショットからボリューム復元
data "aws_ebs_snapshot" "latest" {
most_recent = true
owners = ["self"]
filter {
name = "tag:Name"
values = ["data-snapshot"]
}
}
resource "aws_ebs_volume" "restored" {
availability_zone = "ap-northeast-1a"
snapshot_id = data.aws_ebs_snapshot.latest.id
type = "gp3"
}
定期スナップショットは AWS Backup または DLM (Data Lifecycle Manager) で自動化が標準。
aws_efs_file_system
EFS は 複数の EC2 / ECS タスクから同時マウント できる NFS。Web サーバ群の共有ストレージ、ML 訓練データ、コンテンツ配信に。
resource "aws_efs_file_system" "shared" {
performance_mode = "generalPurpose" # max IO もある
throughput_mode = "elastic" # 自動。bursting / provisioned もある
encrypted = true
kms_key_id = aws_kms_key.app.arn
lifecycle_policy {
transition_to_ia = "AFTER_30_DAYS" # 30 日アクセスなしで IA に
}
tags = { Name = "shared" }
}
EFS のマウント
VPC 内の各 AZ に マウントターゲット を作って、そこに EC2 / ECS から接続します。
resource "aws_security_group" "efs" {
name_prefix = "efs-"
vpc_id = aws_vpc.main.id
}
resource "aws_vpc_security_group_ingress_rule" "efs_from_app" {
security_group_id = aws_security_group.efs.id
referenced_security_group_id = aws_security_group.app.id
from_port = 2049 # NFS
to_port = 2049
ip_protocol = "tcp"
}
resource "aws_efs_mount_target" "main" {
for_each = aws_subnet.private
file_system_id = aws_efs_file_system.shared.id
subnet_id = each.value.id
security_groups = [aws_security_group.efs.id]
}
# ECS のタスク定義に volume を追加
resource "aws_ecs_task_definition" "app" {
# ...
volume {
name = "shared"
efs_volume_configuration {
file_system_id = aws_efs_file_system.shared.id
transit_encryption = "ENABLED"
}
}
}
EBS vs EFS 即決
1 台しか触らない / 高 IOPS 必要 → EBS。複数台で同じファイルを共有 / 複数 AZ → EFS。そもそもファイルシステム不要 → S3。