AWS ParallelClusterをPermissions Boundary環境で使ってみる
はじめに
皆様こんにちは、あかいけです。
最近ParallelClusterを触る機会があり、IAMの権限昇格対策でPermissions Boundaryを使う環境だと、クラスタ作成用のCloudFormationがPermission Denyで失敗する場面に遭遇しました。
というわけで今回はpclusterの「PermissionsBoundaryモード」を実際に使ってみて、ハマったところも含めてまとめてみました。
前提条件
- AWS ParallelCluster v3(検証時は3.15.1)
- スケジューラはSlurm
- pcluster実行用のIAMプリンシパルにPermissions Boundaryが付与されている想定
- 本記事では、権限昇格対策として「Permissions Boundary未設定でのIAMロール作成を禁止する」ポリシーを境界として付けたロールで検証します
- HeadNode/Computeを配置する既存VPC・サブネットが用意済みであること
ParallelClusterでPermissions boundaryを使う方法
ParallelClusterはクラスタ作成時に、HeadNodeやComputeノード用のIAMロールをiam:CreateRoleで自動作成します。
一方でPermissions Boundaryを使う環境では、「Boundaryを付けずにIAMロールを作ることを禁止する」という制御を入れることが一般的です。
そのためクラスタ作成時にPermissions Boundaryを考慮しないと、pclusterが作るIAMロールがBoundaryのDenyに引っかかり、クラスタ作成が失敗します。
ParallelClusterはこれを回避するための「PermissionsBoundaryモード」を公式に用意しているので、今回はそれを使って解消するまでを見ていきます。
ParallelClusterのIAM管理方式とPermissionsBoundaryモード
ParallelCluster v3には、pcluster実行者のIAM権限の扱い方として3つのモードがあります。
| モード | 内容 |
|---|---|
| Privileged IAM access | ParallelClusterが全IAMリソースを自動作成する。実質的にIAM管理者権限が必要 |
| Restricted IAM access | 管理者が事前にロールを作成し、設定で渡す。自由度は下がる |
| PermissionsBoundary | ParallelClusterがBoundary付きでロールを自動作成する |
権限昇格対策でPermissions Boundaryを使っている環境に一番きれいに合うのが、3つ目のPermissionsBoundaryモードです。
このモードでは、クラスター設定ファイルのIam.PermissionsBoundaryにポリシーのARNを指定すると、ParallelClusterが自動作成するparallelcluster/*パス配下のIAMロールすべてに、そのポリシーをBoundaryとして付けてくれます。
今回使うPermissions Boundary
検証では、pcluster実行用のロールに以下のようなPermissions Boundaryを付けています。
具体的には「iam:CreateRoleのリクエストに、iam:PermissionsBoundaryとしてpcluster-dev-boundaryが指定されていない場合はDenyする」、という条件になっています。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAll",
"Effect": "Allow",
"Action": "*",
"Resource": "*"
},
{
"Sid": "DenyRoleCreationWithoutBoundary",
"Effect": "Deny",
"Action": "iam:CreateRole",
"Resource": "*",
"Condition": {
"ArnNotLike": {
"iam:PermissionsBoundary": "arn:aws:iam::*:policy/pcluster-dev-boundary"
}
}
}
]
}
クラスターを作成してみる
①:Permissions boundaryを指定せずに作成してみる
まずはPermissions boundaryを指定せずに作成して、エラーが出ることを確認します。
クラスター設定ファイルにIam.PermissionsBoundaryを書かずにクラスタを作成すると、pclusterはBoundaryなしでロールを作ろうとするため、Boundaryのdenyに引っかかります。
以下がIamセクションを書いていないクラスター設定ファイルです。
Region: ap-northeast-1
Image:
Os: alinux2023
HeadNode:
InstanceType: t3.medium
Networking:
SubnetId: subnet-xxxxxxxx
Iam:
AdditionalIamPolicies:
- Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
Scheduling:
Scheduler: slurm
SlurmQueues:
- Name: compute
ComputeResources:
- Name: cr-compute
InstanceType: t3.micro
MinCount: 0
MaxCount: 1
Networking:
SubnetIds:
- subnet-xxxxxxxx
# Iam.PermissionsBoundary を意図的に書いていない
この設定で作成します。
pcluster create-cluster \
--cluster-name pc-ng \
--cluster-configuration cluster-config.yaml
作成自体はCREATE_IN_PROGRESSで始まりますが、しばらくするとCREATE_FAILEDになります。
CloudFormationのイベントを見ると、iam:CreateRoleがBoundaryのDenyで弾かれているのがはっきり分かります。
User: arn:aws:sts::123456789012:assumed-role/.../pcluster-test-user
is not authorized to perform: iam:CreateRole
on resource: arn:aws:iam::123456789012:role/parallelcluster/pc-deny-repro/pc-deny-repro-RoleHeadNode-xxxx
with an explicit deny in a permissions boundary:
arn:aws:iam::123456789012:policy/pcluster-dev-boundary
with an explicit deny in a permissions boundaryとあるので、Boundaryが原因だと切り分けできます。
②:Permissions boundaryを指定して作成する
①のエラーは、クラスター設定ファイルのIam.PermissionsBoundaryにBoundaryのARNを書くだけで解消できます。
こうするとpclusterは、自動作成するロールにこのBoundaryを付けた状態でiam:CreateRoleを呼ぶため、denyの条件を満たして通過します。
Region: ap-northeast-1
Image:
Os: alinux2023
HeadNode:
InstanceType: t3.medium
Networking:
SubnetId: subnet-xxxxxxxx
Iam:
AdditionalIamPolicies:
- Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
Scheduling:
Scheduler: slurm
SlurmQueues:
- Name: compute
ComputeResources:
- Name: cr-compute
InstanceType: t3.micro
MinCount: 0
MaxCount: 2
Networking:
SubnetIds:
- subnet-xxxxxxxx
# ここが今回の肝
Iam:
PermissionsBoundary: arn:aws:iam::123456789012:policy/pcluster-dev-boundary
この設定で作成します。
pcluster create-cluster \
--cluster-name pc-ok \
--cluster-configuration cluster-config.yaml
Iam.PermissionsBoundaryを書いたことでiam:CreateRoleが通り、無事CREATE_COMPLETEになりました。
ハマったところ
実際にやってみて詰まったところを共有します。
Permissions Boundaryとは直接関係ない環境要因も多いですが、同じところで止まる方は多そうなのでまとめておきます。
Pythonが新しすぎてpclusterが動かない
最初、create-clusterが設定バリデーションの時点で以下のエラーになりました。
{
"message": "Invalid cluster configuration: There is no current event loop in thread 'MainThread'."
}
これはPythonのバージョンが新しすぎることが原因でした。
Python 3.12でイベントループの扱いが変わった影響で、3.13/3.14ではpcluster内部の処理がこけるようです。
私の環境はPython 3.14でしたが、3.12に下げたら解消しました。
ParallelCluster 3.14.x/3.15.xはPython 3.12をサポートしているので、3.12を使うのが無難そうです。
botocore[crt]が必要と言われる
aws loginの認証情報でpclusterを実行したところ、以下のように依存パッケージの追加を求められました。
{
"message": "Missing Dependency: Using the login credential provider requires an additional dependency. You will need to pip install \"botocore[crt]\" before proceeding."
}
メッセージのとおり、pclusterのvenv内で追加インストールすれば解消します。
pip install "botocore[crt]"
動作確認
私はParallelClusterを触るのが初めてだったので、ちゃんと使えるかも確認してみます。
共有ストレージ(/home)の確認
HeadNodeで書いたファイルを、Computeノードから読めるかを確認します。
ParallelClusterはデフォルトでHeadNodeの/homeをComputeにNFSで共有します。
$ echo "written on headnode at $(date)" > /home/ec2-user/shared_test.txt
$ srun -N1 bash -c 'hostname; cat /home/ec2-user/shared_test.txt'
compute-dy-cr-compute-1
written on headnode at Fri Aug 14 17:54:37 UTC 2026
Computeノード側でHeadNodeが書いた内容が読めているので、共有ストレージは問題なく動いています。
マルチノードのMPIジョブ
次に、2ノードにまたがるMPIジョブを投げて、ノード間通信ができるかを確認します。
簡単なMPIプログラムを用意してビルドし、--nodes=2のジョブスクリプトを作ります。
module load openmpi
cat > ~/hello.c <<'EOF'
#include <mpi.h>
#include <stdio.h>
int main(int argc,char**argv){
MPI_Init(&argc,&argv);
int rank,size,len; char name[MPI_MAX_PROCESSOR_NAME];
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Get_processor_name(name,&len);
printf("rank %d / %d on %s\n",rank,size,name);
MPI_Finalize(); return 0;
}
EOF
mpicc ~/hello.c -o ~/hello
cat > ~/mpi.sbatch <<'EOF'
#!/bin/bash
#SBATCH --job-name=mpihello
#SBATCH --nodes=2
#SBATCH --ntasks-per-node=1
#SBATCH --output=/home/ec2-user/mpi-%j.out
module load openmpi
srun --mpi=pmix /home/ec2-user/hello
EOF
このジョブを投入すると、Computeが2台確保されます。
$ sbatch ~/mpi.sbatch
Submitted batch job 3
$ squeue
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
3 compute mpihello ec2-user CF 0:01 2 compute-dy-cr-compute-[1-2]
NODESが2、NODELISTがcompute-dy-cr-compute-[1-2]となっており、2ノードにまたがってジョブがスケジュールされたことが確認できます。
オートスケール(スケールアップ/ダウン)
複数のジョブを一気に投げて、MaxCountまでスケールアップし、ジョブが終わるとスケールダウンする様子も確認しました。
$ for i in $(seq 1 4); do sbatch --wrap="sleep 120" -N1; done
$ sinfo
PARTITION AVAIL TIMELIMIT NODES STATE NODELIST
compute* up infinite 2 alloc~ compute-dy-cr-compute-[1-2] # 起動中
...
$ sinfo
PARTITION AVAIL TIMELIMIT NODES STATE NODELIST
compute* up infinite 2 alloc compute-dy-cr-compute-[1-2] # ジョブ実行中
...
$ sinfo
PARTITION AVAIL TIMELIMIT NODES STATE NODELIST
compute* up infinite 2 idle compute-dy-cr-compute-[1-2] # ジョブ完了
alloc~(起動中)からalloc(実行中)、そしてジョブ完了後にidleへと遷移しています。
このあとScaledownIdletime(既定10分)のアイドルが続くと、Computeノードは自動で終了します。
クラスタ更新は問題なくできるか
update-clusterによる更新でもIAMロールの作成・変更が走り得るため、「作成だけでなく更新でもBoundaryが問題なく通るか」を見ておきます。
MaxCountを1から2に変更する更新を、コンピュートフリートを止めてから実行しました。
# MaxCount変更はフリート停止が前提
pcluster update-compute-fleet --cluster-name pc-ok --status STOP_REQUESTED
# cluster-config.yaml の MaxCount を 1 -> 2 に変更してから
pcluster update-cluster \
--cluster-name pc-ok \
--cluster-configuration cluster-config.yaml
# 更新完了(UPDATE_COMPLETE)を待ってからフリート再開
pcluster update-compute-fleet --cluster-name pc-ok --status START_REQUESTED
更新はchangeSetにMaxCountの変更が反映され、Boundaryに弾かれることなく完了しました。
つまり、クラスター設定ファイルにBoundaryを明示しておけば、作成だけでなくクラスターの更新も問題なく動くことが確認できました。
なお、更新がUPDATE_IN_PROGRESSの間はフリートを開始できません。
私は待たずにSTART_REQUESTEDを叩いてしまい、以下のエラーが出ました。
これはエラーというより順番の問題なので、UPDATE_COMPLETEになってから再実行すればOKです。
{
"message": "Bad Request: Failed when starting compute fleet with error: Cannot start/enable compute fleet while stack is in UPDATE_IN_PROGRESS status."
}
さいごに
以上、AWS ParallelClusterでPermissions Boundaryを使ってみる、でした。
Permission Denyの対処はIam.PermissionsBoundaryを1行書くだけとシンプルで、権限昇格対策のBoundary環境でもpclusterを問題なく使えました。
同じような環境でpclusterを使おうとしている方の参考になれば幸いです。







