★★ 中級

14. EBS / EFS

EC2 や ECS にディスクをアタッチする方法。EBS は 1 台専用EFS は複数台で共有。用途別に使い分けます。

EBS / EFS / S3 の使い分け

EBSEFSS3
形式ブロックストレージファイルシステム (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。