SageMakerノートブックインスタンスにおけるカスタムVPCでの起動について

このブログシリーズ 「クラウドセキュリティ 実践集」 では、一般的なセキュリティ課題を取り上げ、「なぜ危険なのか?」 というリスクの解説から、「どうやって直すのか?」 という具体的な修復手順(コンソール、AWS CLI、Terraformなど)まで、分かりやすく解説します。
今回は、Amazon SageMakerノートブックインスタンスがカスタムVPCで起動されていない状態について、そのリスクと対策を解説します。

リスク
Amazon SageMakerは、機械学習モデルを構築、トレーニング、デプロイするためのフルマネージドサービスです。SageMakerノートブックインスタンスは、Jupyterノートブック環境を提供し、データ分析やモデル開発に利用されます。ノートブックインスタンスは、デフォルトでSageMakerが管理するサービスVPC内で起動されます。このデフォルト設定のまま運用している場合、以下のようなセキュリティおよび運用上のリスクが発生します。
- データ流出のリスク: ノートブックインスタンスからインターネットへのアクセスが制限されていない場合、悪意のあるユーザーや設定ミスにより、機密データが外部に流出するリスクがあります。これには、企業秘密、顧客データ、モデルの重みなどが含まれます。
- 不正アクセスと攻撃の拡大: インターネットから直接アクセス可能な環境にある場合、外部からの不正アクセスや攻撃の対象となる可能性が高まります。もしノートブックインスタンスが侵害された場合、そこから他のAWSリソースへの攻撃の足がかりとなるリスクがあります。
- 内部リソースへのセキュアなアクセス不足: 企業内のデータベース(RDS、Redshiftなど)、S3バケット、プライベートAPIなど、同じVPC内にある他のAWSリソースへのセキュアなアクセスが困難になります。VPCピアリングやDirect Connectなどを用いて接続することは可能ですが、ルーティングが複雑になる可能性があります。
- 監査とロギングの制限: SageMaker管理VPCでは、ユーザーがVPCフローログを設定してネットワークトラフィックを監視することができません。これにより、セキュリティインシデント発生時の調査や監査証跡の収集が困難になります。
対策
Amazon SageMakerノートブックインスタンスをカスタムVPC内で起動することは、上記のすべてのリスクを軽減し、セキュリティ体制と運用上の柔軟性を大幅に強化するための重要なベストプラクティスです。
- ネットワーク分離とアクセス制御: ノートブックインスタンスをカスタムVPC内のプライベートサブネットに配置することで、インターネットからの直接アクセスを防ぎ、VPCのセキュリティグループやネットワークACLによって厳格なアクセス制御を実装できます。これにより、意図しないデータ流出や不正アクセスのリスクを大幅に低減します。
- プライベート接続の確立: 同じVPC内の他のAWSリソース(S3、RDS、Redshiftなど)へは、VPCエンドポイントやプライベートIPアドレスを介して直接、セキュアに接続できます。これにより、データ転送がインターネットを経由せず、レイテンシーの低減とセキュリティの向上が図れます。
- 監査と可視性の向上: カスタムVPCで起動することで、VPCフローログを有効にしてノートブックインスタンスのネットワークトラフィックを監視できます。これにより、異常な通信パターンを検出し、セキュリティインシデントの調査を効率的に行えます。
- 柔軟なルーティングと接続: VPCピアリングやTransit Gatewayを利用して、他のVPCやオンプレミスネットワークと接続し、セキュアな環境で広範囲なデータソースにアクセスできるようになります。
修復方法
Amazon SageMakerノートブックインスタンスをカスタムVPCで起動する方法は、AWSコンソールまたはTerraformで行えます。
AWSコンソールでの修復手順
AWSコンソールを使用して、Amazon SageMakerノートブックインスタンスの作成時にカスタムVPC、サブネット、およびセキュリティグループを指定します。
前提:
- ノートブックインスタンスを起動する既存のカスタムVPCがあること。
- そのVPC内に、ノートブックインスタンスが使用するプライベートサブネットがあること。
- ノートブックインスタンスが通信するために必要なポートを許可するセキュリティグループがあること(例: SSH 22番ポート、Sagemakerの内部通信ポートなど)。
- S3へのアクセスが必要な場合は、S3 VPCエンドポイントの作成を推奨します。
- Amazon SageMakerサービスへ移動: AWSコンソールにログインし、Amazon SageMaker サービスを開きます。
- ノートブックインスタンスの作成: 左側のナビゲーションペインで「ノートブック」の下にある「ノートブックインスタンス」を選択します。 「ノートブックインスタンスの作成」をクリックします。
- ノートブックインスタンス設定の構成:
- 「ノートブックインスタンス名」、「ノートブックインスタンスタイプ」などを設定します。
- 「プラットフォーム識別子」などの設定も必要に応じて行います。
- ネットワーク設定: 「ネットワーク設定」セクションまでスクロールします。
- 「VPC」のドロップダウンメニューから、ノートブックインスタンスを起動したいカスタムVPCを選択します。
- 「サブネット」のドロップダウンメニューから、そのVPC内のプライベートサブネットを選択します。
- 「セキュリティグループ」のドロップダウンメニューから、関連付けるセキュリティグループを選択します。
- 重要: セキュリティグループは、ノートブックインスタンスが必要とするサービスへのアウトバウンドアクセス(S3、SageMaker APIなど)と、SSHポート(通常22番)へのインバウンドアクセス(SageMakerサービスが管理用)を許可する必要があります。

- 追加設定の構成(IAMロールなど): 必要に応じて、IAMロール、ライフサイクル設定、ストレージ設定などを構成します。
- ノートブックインスタンスの作成: 設定内容を確認し、「ノートブックインスタンスの作成」をクリックしてインスタンスをプロビジョニングします。
これで、Amazon SageMakerノートブックインスタンスは指定したカスタムVPC内で起動され、よりセキュアなネットワーク環境で運用されるようになります。
Terraformでの修復手順
TerraformでAmazon SageMakerノートブックインスタンスをカスタムVPCで起動するには、aws_sagemaker_notebook_instance
リソースの subnet_id
と security_group_ids
パラメータを設定します。
# (前提) カスタムVPC, プライベートサブネット, セキュリティグループを定義します
resource "aws_vpc" "sagemaker_vpc" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "sagemaker-vpc"
}
}
resource "aws_subnet" "sagemaker_private_subnet" {
vpc_id = aws_vpc.sagemaker_vpc.id
cidr_block = "10.0.1.0/24"
availability_zone = "${data.aws_region.current.name}a"
tags = {
Name = "sagemaker-private-subnet"
}
}
resource "aws_security_group" "sagemaker_notebook_sg" {
name = "sagemaker-notebook-sg"
description = "Security group for SageMaker Notebook Instances"
vpc_id = aws_vpc.sagemaker_vpc.id
# インバウンドルール: SageMakerサービスからのSSHアクセス (ポート22)
# これにより、AWSがノートブックインスタンスの管理を行うことができます。
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
# SageMakerサービスが使用するCIDR範囲に制限することを推奨
# AWSドキュメントで最新のIP範囲を確認し、環境に合わせて調整してください
# または、VPCエンドポイント (EC2, Sagemaker API) 経由でのアクセスを検討
cidr_blocks = ["0.0.0.0/0"] # 例として広範囲にしていますが、実際の環境では制限してください
}
# アウトバウンドルール: S3 (VPCエンドポイント経由), SageMaker API, ECRなどへのアクセス
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"] # VPCエンドポイントを適切に設定し、ここを制限することを推奨
}
tags = {
Name = "sagemaker-notebook-sg"
}
}
# (オプション) S3 VPC Endpoint for private S3 access
resource "aws_vpc_endpoint" "s3_endpoint" {
vpc_id = aws_vpc.sagemaker_vpc.id
service_name = "com.amazonaws.${data.aws_region.current.name}.s3"
vpc_endpoint_type = "Gateway"
route_table_ids = [aws_vpc.sagemaker_vpc.main_route_table_id] # または特定のルートテーブル
policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Allow",
Principal = "*",
Action = "s3:*",
Resource = [
"arn:aws:s3:::*", # 特定のS3バケットに制限を推奨
]
}
]
})
tags = {
Name = "sagemaker-s3-endpoint"
}
}
# SageMakerノートブックインスタンスにアタッチするIAMロール
resource "aws_iam_role" "sagemaker_notebook_role" {
name = "sagemaker-notebook-role"
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Allow",
Principal = {
Service = "sagemaker.amazonaws.com"
},
Action = "sts:AssumeRole"
}
]
})
}
# IAMロールにアタッチするポリシー (例: S3へのアクセス許可)
resource "aws_iam_role_policy" "sagemaker_s3_access_policy" {
name = "sagemaker-s3-access-policy"
role = aws_iam_role.sagemaker_notebook_role.id
policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Allow",
Action = [
"s3:GetObject",
"s3:PutObject",
"s3:ListBucket"
],
Resource = [
"arn:aws:s3:::your-ml-data-bucket/*", # あなたのS3バケット名に置き換え
"arn:aws:s3:::your-ml-data-bucket"
]
},
{
Effect = "Allow",
Action = [
"sagemaker:CreatePresignedNotebookInstanceUrl",
"sagemaker:DescribeNotebookInstance"
],
Resource = "*" # ノートブックインスタンスへのアクセス
},
{
Effect = "Allow",
Action = [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage"
],
Resource = "*"
},
{
Effect = "Allow",
Action = [
"cloudwatch:PutMetricData"
],
Resource = "*"
},
{
Effect = "Allow",
Action = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogStreams"
],
Resource = "arn:aws:logs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:log-group:/aws/sagemaker/NotebookInstances:*"
}
]
})
}
# Amazon SageMaker ノートブックインスタンス
resource "aws_sagemaker_notebook_instance" "my_notebook" {
name = "my-secure-notebook-instance"
role_arn = aws_iam_role.sagemaker_notebook_role.arn
instance_type = "ml.t3.medium"
platform_identifier = "notebook-al2-v1" # Amazon Linux 2 platform identifier
# カスタムVPCの設定
subnet_id = aws_subnet.sagemaker_private_subnet.id
security_group_ids = [aws_security_group.sagemaker_notebook_sg.id]
# インターネットアクセスを無効化 (推奨)
direct_internet_access = "Disabled"
tags = {
Name = "MySecureSageMakerNotebook"
Environment = "Production"
}
}
# 現在のAWSアカウント情報とリージョンを取得
data "aws_caller_identity" "current" {}
data "aws_region" "current" {}
上記のTerraformコードでは、aws_sagemaker_notebook_instance
リソース内で subnet_id
と security_group_ids
を設定することで、SageMakerノートブックインスタンスをカスタムVPC内のプライベートサブネットで起動しています。
aws_vpc.sagemaker_vpc
,aws_subnet.sagemaker_private_subnet
,aws_security_group.sagemaker_notebook_sg
: ノートブックインスタンスが使用するVPC、サブネット、およびセキュリティグループを定義します。subnet_id
: ノートブックインスタンスを配置するサブネットのIDを指定します。プライベートサブネットを選択することを強く推奨します。security_group_ids
: ノートブックインスタンスに適用するセキュリティグループのIDを指定します。これらのセキュリティグループは、必要なインバウンド/アウトバウンドトラフィックを許可するように設定する必要があります。direct_internet_access = "Disabled"
: インターネットへの直接アクセスを無効にします。これにより、ノートブックインスタンスからのアウトバウンドトラフィックは、VPCのルーティングテーブル(NAT GatewayまたはVPCエンドポイント)を介してのみ許可されるようになります。セキュリティ強化のためにこの設定を強く推奨します。aws_sagemaker_notebook_role
とaws_iam_role_policy
: ノートブックインスタンスがS3バケットや他のAWSサービスにアクセスするために必要なIAMロールとポリシーを定義します。
your-ml-data-bucket
や 10.0.0.0/16
などのプレースホルダーは、実際の環境に合わせて修正してください。セキュリティグループのCIDRブロックやS3のポリシーは、最小特権の原則に従って、できる限り制限するようにしてください。
最後に
この記事では、Amazon SageMakerノートブックインスタンスをカスタムVPCで起動することの重要性について解説しました。この設定は、データ流出のリスクを低減し、不正アクセスから保護し、コンプライアンス要件を満たし、他のAWSリソースへのセキュアなアクセスを可能にする上で不可欠です。 貴社のSageMakerノートブックインスタンスは、カスタムVPCで起動されていますか?この機会にぜひ設定を確認・強化してみてください。 こちらの内容の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。運用が非常にラクに出来る製品になっていますのでぜひ興味がある方はお問い合わせお待ちしております。
最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです。