こしあん
2025-01-23

Mountpoint for Amazon S3を使ってみる


17{icon} {views}


Mountpoint for Amazon S3を使えば、S3バケットをEC2に直接マウントし、Linuxコマンド感覚でファイルを操作できる。TerraformのコードでIAMロールやユーザーデータを設定するだけで、大容量データを簡単に扱える環境が整う。

はじめに

  • Mountpoint for Amazon S3というEC2にS3をマウントする機能(OSS)を試してみた
  • ちゃんと設計するならEFSを使うべきだと思うけど、とりあえずS3のファイルをLinuxコマンド感覚で読みたいときに便利そうだと思う
  • Mountpoint for Amazon S3自体はOSS

できるもの

こんな感じにS3にファイルをアップロードしたとき

Amazon LinuxにマウントするとこのようにLinuxコマンドでファイルが見れる

Terraformのコード

  • Mountpoint for Amazon S3のインストールとS3のマウントは、EC2のユーザーデータで行っている
  • Mountpoint for Amazon S3のURLはx86_64用なので、t4gのようなARMのときは以下のURLに変換する

https://s3.amazonaws.com/mountpoint-s3-release/latest/arm64/mount-s3.rpm

# マウントするバケットの作成
resource "aws_s3_bucket" "example" {
  bucket = var.s3_bucket_name
  force_destroy = true
}

# EC2 が利用する IAM ロールに必要なポリシーを付与
data "aws_iam_policy_document" "ec2_trust" {
  statement {
    actions = ["sts:AssumeRole"]
    principals {
      type        = "Service"
      identifiers = ["ec2.amazonaws.com"]
    }
  }
}

resource "aws_iam_role" "ec2_role" {
  name               = "ec2-role-s3-mount"
  assume_role_policy = data.aws_iam_policy_document.ec2_trust.json
}

# Session Manager用のポリシーをIAMロールにアタッチ
resource "aws_iam_role_policy_attachment" "ssm_attach" {
  role       = aws_iam_role.ec2_role.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}

# Amazon S3 へのフルアクセスを例としてアタッチ(必要に応じてポリシーを制限してください)
resource "aws_iam_role_policy_attachment" "ec2_attach_s3_policy" {
  role       = aws_iam_role.ec2_role.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonS3FullAccess"
}

# EC2 インスタンスで使用する IAM インスタンスプロファイル
resource "aws_iam_instance_profile" "ec2_profile" {
  name = "ec2-profile-s3-mount"
  role = aws_iam_role.ec2_role.name
}

# AMI の指定 (Amazon Linux 2023 を例としています)
data "aws_ami" "amazon_linux" {
  most_recent = true
  owners      = ["137112412989"] # AmazonのAMI所有者ID

  filter {
    name   = "name"
    # Amazon Linux 2023 AMIの名前パターン。minimumを除外する
    values = ["al2023-ami-2023*-kernel-*-x86_64"]
  }

  filter {
    name   = "architecture"
    values = ["x86_64"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
}

# セキュリティグループの作成
resource "aws_security_group" "ec2_sg" {
  name        = "ec2-s3-mount-sg"
  description = "Allow SSH"
  vpc_id      = var.vpc_id

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
    ipv6_cidr_blocks = ["::/0"]
  }
}

# EC2 インスタンスを作成し、User Data で mountpoint for Amazon S3 をインストールしてマウント
resource "aws_instance" "ec2_s3_mount" {
  ami                    = data.aws_ami.amazon_linux.id
  instance_type          = "t3.small"
  subnet_id              = var.private_subnet_id
  vpc_security_group_ids = [aws_security_group.ec2_sg.id]

  iam_instance_profile = aws_iam_instance_profile.ec2_profile.name

  user_data = <<-EOF
    #!/bin/bash
    set -eux

    # システムのアップデートと必要なパッケージのインストール
    dnf update -y
    dnf install -y wget

    # 最新リリースへのパス
    MOUNT_S3_URL="https://s3.amazonaws.com/mountpoint-s3-release/latest/x86_64/mount-s3.rpm"

    # mount-s3 のダウンロードとインストール
    wget $MOUNT_S3_URL
    dnf install -y ./mount-s3.rpm

    # マウント先ディレクトリ作成
    mkdir -p /mnt/my-s3-bucket

    # S3 バケットをマウント (my-example-bucket をご利用のバケット名に変更)
    mount-s3 ${var.s3_bucket_name} /mnt/my-s3-bucket

    # 例: 永続的にマウントするには、systemd ユニットを作成する方法等があります。 
    #     下記はシンプルな例なので再起動するとマウントは外れます。
  EOF

  tags = {
    Name = "EC2-S3-Mount"
  }
}

所感

  • S3にまあまあ大きめのデータがあって、「EC2から使う必要あるんだけど、EBS拡張すっか~めんどいし課金やだな~」みたいなとき普通に便利そう
  • 初手からこれ前提に設計するのはあんま良くないと思う


Shikoan's ML Blogの中の人が運営しているサークル「じゅ~しぃ~すくりぷと」の本のご案内

技術書コーナー

北海道の駅巡りコーナー


Add a Comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です