以下の内容はhttps://msyksphinz.hatenablog.com/entry/2025/11/25/040000より取得しました。


TerraformでAWS Devサーバを構築する手順をしらべる (3. AWS Slurmクラスターの構築)

作業の目的

AWS上にSlurmクラスターを構築する必要があったので、Terraformを使って完全自動化で構築できるようにした。

構築した環境

  • フロントエンドサーバ: Slurmコントローラー(slurmctld)を実行
  • ジョブサーバ: Slurmワーカー(slurmd)を実行
  • 固定IPアドレス: Elastic IPでIPアドレスを固定
  • 共有ストレージ: EFSとEBSボリューム(1TB)をNFSで共有
  • 完全自動化: インスタンス起動時にすべての設定が自動実行

アーキテクチャ

作業の流れ

最初にterraform planを実行したところ、以下のエラーが発生した:

Error: Self-referential block
on main.tf line 53, in resource "aws_security_group" "frontend_job_sg":
53:     security_groups = [aws_security_group.frontend_job_sg.id]

Configuration for aws_security_group.frontend_job_sg may not refer to itself.

セキュリティグループが自分自身を参照していた。同じセキュリティグループ内のリソース間で通信を許可するには、self = trueを使う必要があった。修正した:

ingress {
  description = "NFS for EFS"
  from_port   = 2049
  to_port     = 2049
  protocol    = "tcp"
  self        = true  # これで解決
}

セキュリティグループを設定した。SSHとNFSの通信を許可する必要があった:

resource "aws_security_group" "frontend_job_sg" {
  name        = "frontend-job-sg"
  description = "Allow SSH from internet and NFS inside SG"
  vpc_id      = var.vpc_id

  # SSH access
  ingress {
    description = "SSH"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = var.ssh_allowed_cidrs
  }

  # NFS for EFS and shared storage
  ingress {
    description = "NFS for EFS"
    from_port   = 2049
    to_port     = 2049
    protocol    = "tcp"
    self        = true
  }
}

ストレージの設定

EFSの追加

最初はEFSだけを設定した。Slurmの設定ファイルやMunge keyを共有するために必要だった:

resource "aws_efs_file_system" "work" {
  creation_token = "work-efs"

  lifecycle_policy {
    transition_to_ia = "AFTER_30_DAYS"
  }

  tags = {
    Name = "work-efs"
  }
}

1TBのEBSボリュームを追加

後から、作業用の1TBディスクが必要になった。フロントエンドサーバにアタッチして、NFSでジョブサーバと共有することにした:

resource "aws_ebs_volume" "shared_storage" {
  availability_zone = aws_instance.frontend.availability_zone
  size              = 1024 # 1TB
  type              = "gp3"
  encrypted         = true

  tags = {
    Name = "shared-storage-1tb"
  }
}

resource "aws_volume_attachment" "shared_storage_attach" {
  device_name = "/dev/sdf"
  volume_id   = aws_ebs_volume.shared_storage.id
  instance_id = aws_instance.frontend.id
}

固定IPアドレスの設定

インスタンスを再起動しても同じIPアドレスを使いたかったので、Elastic IPを設定した:

resource "aws_eip" "frontend_eip" {
  domain = "vpc"
  tags = {
    Name = "frontend-server-eip"
  }
}

resource "aws_eip_association" "frontend_eip_assoc" {
  instance_id   = aws_instance.frontend.id
  allocation_id = aws_eip.frontend_eip.id
}

インスタンスの自動設定

フロントエンドサーバのuser_data

インスタンス起動時に自動で設定されるように、user_dataスクリプトを書いた。以下の処理を自動化した:

  1. ホスト名の設定
  2. パッケージのインストール(Emacs、Docker、Makeなど)
  3. EFSのマウント
  4. Slurmコントローラーのインストールと設定
  5. Munge keyの生成とEFSへの共有
  6. EBSボリュームのフォーマットとマウント
  7. NFSサーバの設定

EBSボリュームの自動マウントで苦労した

最初は、EBSボリュームがマウントされない問題に遭遇した。df -hを実行しても/mnt/sharedが表示されなかった。

原因を調べたところ: - user_dataスクリプトがEBSボリュームのアタッチを待たずに実行されていた - デバイス名の検出が不十分だった(nvme1n1を固定で指定していた)

確認方法

lsblk
ls -la /dev/nvme*

解決方法:以下のように設定した:

# Setup 1TB shared storage (EBS volume)
# Wait for EBS volume to be attached (max 5 minutes)
MAX_WAIT_EBS=300
ELAPSED_EBS=0
DEVICE=""

while [ -z "$DEVICE" ] && [ $ELAPSED_EBS -lt $MAX_WAIT_EBS ]; do
    # Check for NVMe devices (modern instances)
    for nvme_dev in /dev/nvme[1-9]n1; do
        if [ -e "$nvme_dev" ]; then
            # Check if it's not the root device
            if ! mountpoint -q "$nvme_dev" 2>/dev/null; then
                DEVICE="$nvme_dev"
                break
            fi
        fi
    done
    
    if [ -z "$DEVICE" ]; then
        sleep 5
        ELAPSED_EBS=$((ELAPSED_EBS + 5))
        echo "Waiting for EBS volume... ($ELAPSED_EBS/$MAX_WAIT_EBS seconds)"
    fi
done

# Format and mount
if ! blkid $DEVICE > /dev/null 2>&1; then
    mkfs.ext4 -F $DEVICE
fi

mkdir -p /mnt/shared
echo "$DEVICE /mnt/shared ext4 defaults,nofail 0 2" >> /etc/fstab
mount $DEVICE /mnt/shared

# Install and configure NFS server
apt-get install -y nfs-kernel-server
chmod 777 /mnt/shared
echo "/mnt/shared *(rw,sync,no_subtree_check,no_root_squash)" >> /etc/exports
exportfs -ra
systemctl enable nfs-kernel-server
systemctl restart nfs-kernel-server

この改善により、NVMeデバイスを動的に検出し、最大5分間待機するようになった。




以上の内容はhttps://msyksphinz.hatenablog.com/entry/2025/11/25/040000より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14