Mountpoint for Amazon S3を使ってみる
Posted On 2025-01-23
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の中の人が運営しているサークル「じゅ~しぃ~すくりぷと」の本のご案内
技術書コーナー
北海道の駅巡りコーナー