Amazon SageMakerをそれなりの人数で使うときの設定

AWSのマネージドJupyterサービスである「Amazon SageMaker」を数十名規模で使う機会があったのでインフラ的に設定した内容などを書いておく。
SageMakerで何をしたかなどはいずれちゃんとした情報が出ると思う。

Amazon SageMakerとは?

AWSのWebUIでぽちぽちクリックしていくとJupyterが起動する、そういうやつです。
SageMakerのオフィシャルサイトはこちら。 aws.amazon.com

Amazon SageMakerの起動方法

まずアクセスすべきはこちら。 https://console.aws.amazon.com/sagemaker/home#/notebook-instances

「Create notebook instance」ボタンをクリックするとこのような画面になるので項目を埋めていく。 f:id:mazgi:20180305225954p:plain

ある程度の人数で使う場合には以下のような項目を取り決めておくと良さそう。

  • Notebook instance name
    • 文字通りNotebookインスタンスの名前になるほか、Jupyter NotebookのURLの一部としても使われる
    • 誰が作ったかとか何の目的なのかとか命名ルールを決めておくと良さそう
  • Notebook instance type
    • いくつか選べる
    • Notebookインスタンスは純粋にNotebookであって、このインスタンスでjobが動くわけではないのでそんなに強力なインスタンスでなくてもよい
    • なお実際にjobを実行するインスタンスでは p2/p3 などのGPUインスタンスも選べる
  • IAM role(後述)
    • Notebookインスタンスに与えるRole、この権限でjobなどのインスタンスを作ろうとする
    • Roleを作成するか既存のRoleから選択するかなどが選べる
    • チームやグループで使うのであればあらかじめRoleを作っておいてARNを入力してもらう方が管理上よいと思う
  • Custom IAM role ARN
    • 前述の「IAM role」で既存のRoleを選ぶことにすると表示される
    • 私はあらかじめ作っておいたRoleを入力してもらうことにした
  • VPC
    • とりあえず使うだけなら No VPC でよい
    • ここで指定したVPCにSageMakerがアクセスできるようになるらしい(未検証)
    • "Notebook instances will have internet access independent of your VPC setting."とある通り、ここでVPCを指定したからといってSageMakerやNotebookを特定のVPCに閉じ込めることはできないので注意

以上のような項目を埋めて、ページ下部の「Create notebook instance」ボタンをクリックするとNotebookインスタンスが準備されるので「InService」になるまで数分〜10数分程度待つ。
案外時間がかかるが裏側でプロビジョニングなどを行なっているのでしょう。

「InService」になったNotebookインスタンスの詳細をみると右上に「Open」ボタンがあるのでクリックする。 f:id:mazgi:20180305230017p:plain

そうすると別タブで見慣れたJupyter Notebookの画面が開くので好きなように使う。 f:id:mazgi:20180305230045p:plain

こんなに楽だと自分でJupyter Notebook立てるモチベーションがなくなって良いですね。

IAM Role/Group作成

以下を用意した

  • IAM Role
    • 前述の、Notebookインスタンスに与えるRole
    • 最小限 AmazonSageMakerFullAccess をアタッチしておけば良い
  • IAM Group
    • 今回は1つのAWSアカウントで数十名が同時にSageMakerを使うため、グループを作ってユーザーを紐づけることにした
    • 以下をアタッチした(もう少し絞り込めそうではある)
      • AmazonSageMakerFullAccess
      • AmazonEC2FullAccess
      • IAMReadOnlyAccess
      • IAMUserChangePassword (これは運用上必要だっただけ)
  • IAM User(s)
    • SageMakerを使う人全員分のユーザーを払い出し、前述のグループに紐付けた
    • 今回は初期パスワードを私の手元でコンソール出力し、各自初回ログイン時に変更してもらった

以上の設定をTerraformで行う .tf ファイルの例は次の通り。
内容はほぼそのまま、個々のユーザー名は別途変数から読んでいる。

# --------------------------------
# IAM Role for SageMaker

resource "aws_iam_role" "sagemaker-role" {
  name = "sagemaker-role"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "sagemaker.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF
}

resource "aws_iam_role_policy_attachment" "sagemaker-role-attachment" {
  role       = "${aws_iam_role.sagemaker-role.name}"
  policy_arn = "arn:aws:iam::aws:policy/AmazonSageMakerFullAccess"
}

# --------------------------------
# IAM Group for SageMaker

resource "aws_iam_group" "sagemaker-group" {
  name = "sagemaker-group"
}

resource "aws_iam_group_policy_attachment" "sagemaker-group-attachment-AmazonSageMakerFullAccess" {
  group      = "${aws_iam_group.sagemaker-group.name}"
  policy_arn = "arn:aws:iam::aws:policy/AmazonSageMakerFullAccess"
}

resource "aws_iam_group_policy_attachment" "sagemaker-group-attachment-AmazonEC2FullAccess" {
  group      = "${aws_iam_group.sagemaker-group.name}"
  policy_arn = "arn:aws:iam::aws:policy/AmazonEC2FullAccess"
}

resource "aws_iam_group_policy_attachment" "sagemaker-group-attachment-IAMReadOnlyAccess" {
  group      = "${aws_iam_group.sagemaker-group.name}"
  policy_arn = "arn:aws:iam::aws:policy/IAMReadOnlyAccess"
}

resource "aws_iam_group_policy_attachment" "sagemaker-group-attachment-IAMUserChangePassword" {
  group      = "${aws_iam_group.sagemaker-group.name}"
  policy_arn = "arn:aws:iam::aws:policy/IAMUserChangePassword"
}

resource "aws_iam_group_membership" "sagemaker-group-membership" {
  name  = "sagemaker-group-membership"
  group = "${aws_iam_group.sagemaker-group.name}"

  users = "${var.sagemaker_users}"
}

# --------------------------------
# IAM Users for SageMaker

resource "aws_iam_user" "sagemaker-users" {
  name          = "${var.sagemaker_users[count.index]}"
  force_destroy = true
  count         = "${length(var.sagemaker_users)}"
}

resource "aws_iam_user_login_profile" "sagemaker-users" {
  user    = "${var.sagemaker_users[count.index]}"
  pgp_key = "${file("foo.gpg.base64")}"
  count   = "${length(var.sagemaker_users)}"
}

output "sagemaker-user-passwords" {
  value = ["${aws_iam_user_login_profile.sagemaker-users.*.encrypted_password}"]
}
view raw terraform.tf.md hosted with ❤ by GitHub
gist.github.com

AWSリソース上限緩和申請

AWS SAの方にご相談の上、SageMakerを利用する IAM User数 * n で事前にリソース上限の緩和申請を行なった。
デフォルト値はこちら。
AWS サービス制限 - アマゾン ウェブ サービス

内容はざっと次の通り。

  • SageMaker のホスト
    • インスタンス数: IAM User数 * 3
  • SageMaker のトレーニング
    • インスタンス数: IAM User数 * 3
  • SageMaker のホスト
    • (学習に使用するインスタンスタイプ): IAM User数 * 3
  • SageMaker ノートブック
    • (使用するインスタンスタイプ): IAM User数 * 1.5
  • SageMaker のトレーニング
    • (学習に使用するインスタンスタイプ): IAM User数 * 3
  • SageMaker のホスト
    • エンドポイントのインスタンス数: IAM User数 * 3
    • これは不要だったようだ
  • SageMaker のトレーニング
    • トレーニングジョブのインスタンス数: IAM User数 * 3
  • SageMaker ノートブック
    • 実行中のノートブックインスタンスの数: IAM User数 * 1.5

一部CloudTrailの上限に引っかかり同時実行できなかったりもしたが、概ねこれでユーザー全員が目的の操作を行えた。
AWSのリソース上限はなかなか難しいのでAWS SAの方に相談するに限る🙏

感想

プロビジョニングしてルールを決めておけば使いたい人にサクッと使ってもらえて大変便利。
各種セキュリティ担保の方法や込み入った使い方については今後使ってもらいながら工夫していきたい。