Amazon SageMaker上でセキュアなセルフホスト型AIコーディングアシスタントを構築し、エンタープライズ開発者の生産性を引き上げる
はじめに
AIによるコーディング支援は、定型作業の自動化や精度向上を通じてソフトウェア開発を大きく変えつつあり、開発者がより複雑な課題解決に集中できる環境を生み出しています。近年は、機密性の高い知的財産や独自コードの保護、データ規制への準拠、自社固有のニーズに合わせたカスタマイズといった理由から、LLMをプライベート環境でホストする企業が増えています。
概要
本記事では、Amazon SageMaker環境にマーケットプレイス提供のLLMをホストする方法を紹介します。モデルにはAmazon SageMaker Jumpstartのものを使用します。Roo Code、Cline、Continue.devをはじめとする主要なAI自律コーディングエージェントの多くはOpenAIなどのオープンプロトコルに対応しており、SageMaker推論をつなぐOpenAIプロキシとしてLiteLLMが最適です。
なぜセルフホスト型LLMなのか
セルフホスト型LLMが企業にもたらす主なメリットは次のとおりです。
- データプライバシーとセキュリティ:社内でホストすることで、機密データ・ソースコード・独自アルゴリズムを安全に保てます。
- カスタマイズ性:自社のコーディングスタイル、ビジネスロジック、規制要件に合わせてAIモデルを調整できます。
- コスト最適化:リソースを効率的に管理・最適化することで、サードパーティのAIサービスよりもコストを抑えられます。
生産性向上とユースケース
AIによるコーディング支援は、ソフトウェア開発の各工程で生産性と効率を高めます。代表的な活用例は次のとおりです。
- ボイラープレートコード生成の自動化
- デバッグやパフォーマンスのボトルネック特定の支援
- コードレビュープロセスの強化
- 新規参画メンバーのオンボーディングや教育の加速
検討すべきポイント
- セキュリティとコンプライアンス:IAMロール、暗号化、アクセス制御を適切に構成すること。
- コスト管理:インフラ利用状況を継続的にモニタリングし、最適化を続けること。
- パフォーマンス最適化:workloadsの要件に合わせて、適切なSageMakerインスタンスタイプを選ぶこと。
セルフホスティングにおけるAmazon SageMakerの役割
Amazon SageMakerは、次のような特長によりセルフホスティングを容易にします。
- SageMaker Jumpstartを通じて、幅広い事前学習済みLLMにアクセスできる。
- スケーラブルかつセキュアで、高いパフォーマンスを発揮するインフラ管理を提供する。
- AWSサービスとスムーズに統合でき、運用の複雑さを抑えられる。
Fargateを使うメリット
LiteLLMプロキシのデプロイにAWS Fargateを使うことで、運用負荷を大幅に減らせます。
- インフラの手動管理やサーバーのメンテナンスが不要になります。
- スケーリングと可用性が自動で扱われ、安定したパフォーマンスが保たれます。
- 分離されたAWSマネージド環境により、セキュリティ管理の複雑さを抑えられます。
アーキテクチャ

- リアルタイム推論用のAmazon SageMakerエンドポイントにモデルをデプロイします。
- VSCodiumなどのローカルIDEでAIコーディング支援を使うEngineersが、セキュアなチャネル経由でLiteLLM OpenAIプロキシに接続し、LiteLLM OpenAI Proxyを呼び出します。
全体の流れ
まず、事前学習済みモデルをAmazon SageMakerエンドポイントとしてデプロイします。続いて、LiteLLMによるOpenAIプロキシをECSサービスとして稼働させます。
これで開発者はOpenAIプロキシに接続できるようになります。本チュートリアルでは簡略化のため、ECSタスクのパブリックIP経由で接続する想定としています。
ステップ1:事前学習済みモデルをAmazon SageMakerにデプロイする
前提条件:Amazon SageMakerエンドポイントをプロビジョニングする前に、エンドポイントで使用するインスタンスのクォータがアカウントで1以上あることを確認してください。クォータは https://console.aws.amazon.com/servicequotas/home/services/sagemaker/quotas から確認できます。本記事では ml.g5.12xlarge を使用するため、最低でも1つ必要です。不足している場合は 「Request increase at account level」 から引き上げをリクエストできます。

- 既存のAmazon SageMaker実行ロール(https://docs.aws.amazon.com/sagemaker/latest/dg/sagemaker-roles.html)がない場合は、SageMaker実行用のIAMロールを作成します。ここでは
AmazonSageMaker-Endpoints-ExecutionRoleという名前で、マネージドポリシーarn:aws:iam::aws:policy/AmazonSageMakerFullAccessをアタッチし、sagemaker.amazonaws.com向けの信頼ポリシーを設定します。
{
"Version": "2012-10-17",
"Statement": [\
{\
"Effect": "Allow",\
"Principal": {\
"Service": "sagemaker.amazonaws.com"\
},\
"Action": "sts:AssumeRole"\
}\
]
}
2. デプロイ先のVPC、プライベートサブネット、Amazon SageMakerエンドポイントを特定します。
3. Amazon SageMakerエンドポイントがS3バケットから事前学習済みモデルをダウンロードできるよう、S3 VPCエンドポイントを作成します。
aws ec2 create-vpc-endpoint \
--private-dns-enabled \
--vpc-id <vpc-id> \
--service-name com.amazonaws.<region>.s3 \
--route-table-ids <route-table-id>
コマンドが正常に実行されると、ルートテーブルにNATとあわせてVPCエンドポイントが追加されます。
% aws ec2 describe-route-tables --route-table-ids <route-table-id> --query 'RouteTables[*].Routes'
[\
[\
{\
"DestinationCidrBlock": "10.0.0.0/23",\
"GatewayId": "local",\
"Origin": "CreateRouteTable",\
"State": "active"\
},\
{\
"DestinationCidrBlock": "0.0.0.0/0",\
"NatGatewayId": "nat-<NAT GW ID>",\
"Origin": "CreateRoute",\
"State": "active"\
},\
{\
"DestinationPrefixListId": "pl-63a5400a",\
"GatewayId": "vpce-<VPCE ID>",\
"Origin": "CreateRoute",\
"State": "active"\
}\
]\
]
3. 次の設定でセキュリティグループ ecs-sagemaker-endpoint を作成します。
インバウンドルール:
- プロトコル:HTTPS(443)
- ソース:このセキュリティグループ自身(自己参照)
アウトバウンドルール:
- プロトコル:HTTPS(443)
- 宛先:S3 VPCエンドポイント
注:サイバーセキュリティのベストプラクティスとして、デフォルトのセキュリティグループにはインバウンド・アウトバウンドのいずれのルールも設定しないことが推奨されます。詳細は https://docs.aws.amazon.com/securityhub/latest/userguide/ec2-controls.html#ec2-2 を参照してください。
- Amazon SageMaker Jumpstartから利用するモデル(例:Qwen2、Mistral、Llama 3.2)を選びます。事前学習済みモデルの一覧は https://sagemaker.readthedocs.io/en/stable/doc_utils/pretrainedmodels.html で確認できます。

2. モデルIDとバージョンを控え、Amazon SageMakerモデルを作成します。
from sagemaker.jumpstart.model import JumpStartModel
jump_start_model = JumpStartModel(
model_id="huggingface-llm-qwen2-7b-instruct",
model_version="1.2.0",
role="AmazonSageMaker-Endpoints-ExecutionRole",# または該当するAmazon SageMaker実行ロール
vpc_config={
"Subnets": [ "Private Subnets" ],
"SecurityGroupIds": [ "ecs-sagemaker-endpoint" ]
},
)
jump_start_model.deploy(
initial_instance_count=1,
instance_type="ml.g5.12xlarge",
accept_eula=True,
endpoint_name="jumpstart-model"
)
AWS CLIでエンドポイントの状態を確認します。
% aws sagemaker list-endpoints
{
"Endpoints": [\
{\
"EndpointName": "jumpstart-model",\
"EndpointArn": "arn:aws:sagemaker:<AWS REGION>:<AWS ACCOUNT ID>:endpoint/jumpstart-model",\
"CreationTime": "<CreationTime>",\
"LastModifiedTime": "<LastModifiedTime>",\
"EndpointStatus": "InService"\
}\
]
}
ステップ2:Amazon Elastic Container Service(ECS)でOpenAIプロキシをデプロイする
LiteLLMプロキシの設定方法の詳細は https://docs.litellm.ai/docs/proxy/configs を参照してください。
- SageMakerエンドポイントをマッピングする設定YAMLファイル(
config.yaml)を作成します。
model_list:
- model_name: jumpstart-model
litellm_params:
model: sagemaker/jumpstart-model # sagemakerネームスペースを使い、Amazon SageMakerエンドポイント名を指定
2. config.yaml をS3バケットにアップロードします。
3. ECSコンテナを定義します(container-definition.json)。
[\
{\
"name": "litellm",\
"image": "ghcr.io/berriai/litellm:main-latest",\
"cpu": 0,\
"portMappings": [\
{\
"containerPort": 4000,\
"hostPort": 4000,\
"protocol": "tcp"\
}\
],\
"essential": true,\
"environment": [\
{\
"name": "LITELLM_CONFIG_BUCKET_OBJECT_KEY",\
"value": "config.yaml"\
},\
{\
"name": "LITELLM_CONFIG_BUCKET_NAME",\
"value": "<S3 bucket>"\
},\
{\
"name": "LITELLM_MASTER_KEY",\
"value": "<プロキシ呼び出し用APIキー(例:sk-123123)>"\
}\
],\
"mountPoints": [],\
"volumesFrom": [],\
"logConfiguration": {\
"logDriver": "awslogs",\
"options": {\
"awslogs-group": "/ecs/litellm",\
"awslogs-create-group": "true",\
"awslogs-region": "us-east-1",\
"awslogs-stream-prefix": "ecs"\
}\
},\
"systemControls": []\
}\
]
3. 最小権限の原則に基づき、ECSタスクロール用のIAMロールを次のように作成します。
{
"Version": "2012-10-17",
"Statement": [\
{\
"Sid": "Statement1",\
"Effect": "Allow",\
"Action": [\
"sagemaker:InvokeEndpoint"\
],\
"Resource": [\
"arn:aws:sagemaker:<AWS REGION>:<AWS ACCOUNT ID>:endpoint/jumpstart-model"\
]\
}\
]
}
4. ECSタスク定義を登録します。
aws ecs register-task-definition \
--family litellm-task \
--requires-compatibilities FARGATE \
--cpu 1024 \
--memory 2048 \
--network-mode awsvpc \
--runtime-platform cpuArchitecture=ARM64 \
--task-role-arn "<ECS Task Role ARN>" \
--container-definitions file://./container-definition.json \
--region $REGION
ECSサービスを作成する前に、次の情報を準備しておきます。
- ECSタスクが稼働するサブネットID。
- ECSタスクからAmazon SageMakerエンドポイントへの接続を許可するセキュリティグループ。本記事では
ecs-sagemaker-endpointとして作成済みです。
さらに、ECSタスクがLiteLLMコンテナイメージをダウンロードできるよう、別のセキュリティグループも作成します。
アウトバウンドルール:
- プロトコル:HTTPS(443)
- 宛先:0.0.0.0/0
- 説明:ECSタスクのイメージダウンロード用
もう1つ、プロキシからECSタスクへの接続用のセキュリティグループも用意します。
インバウンドルール:
- プロトコル:LiteLLMポート(4000)
- ソース:このセキュリティグループ自身(自己参照)
アウトバウンドルール:
- プロトコル:LiteLLMポート(4000)
- 宛先:このセキュリティグループ自身(自己参照)
- 説明:プロキシとECSタスク間
サブネットIDを指定し、タスク定義からECSサービスを作成します。
aws ecs create-service \
--cluster litellm-cluster \
--service-name litellm-service \
--task-definition litellm-task:1 \
--desired-count 1 \
--launch-type FARGATE \
--platform-version LATEST \
--network-configuration "awsvpcConfiguration={subnets=[<SUBNET ID>],assignPublicIp=DISABLED},securityGroups=[<sg-xxx for ecs-sagemaker-endpoint>,<sg-xxx for ecs-443-outbound>,<sg-xxx for proxy-ecs-4000>]" \
--region $REGION
注:サイバーセキュリティのベストプラクティスとして、ECSサービスにパブリックIPアドレスを割り当てないことが推奨されます。詳細は https://docs.aws.amazon.com/securityhub/latest/userguide/ecs-controls.html#ecs- 2 を参照してください。
ECSタスクのプライベートIPを取得します。
CLUSTER="litellm-cluster"
# ステップ1: ECSタスクIDを取得
TASK=$(aws ecs list-tasks --cluster ${CLUSTER} --query "taskArns[0]" --output text)
# ステップ2: ECSタスクからENIを取得
ENI=$(aws ecs describe-tasks --cluster $CLUSTER --tasks $TASK --query "tasks[0].attachments[0].details[?name=='networkInterfaceId'].value | [0]" --output text)
# ステップ3: ENIのプライベートIPアドレスを取得
aws ec2 describe-network-interfaces --network-interface-ids $ENI --query 'NetworkInterfaces[0].PrivateIpAddress' --output text
取得したタスクのプライベートIPは、後のプロキシ設定で使うため控えておきます。
ステップ3:プロキシをセットアップする
本例では、LiteLLMプロキシへSSMポートフォワーディング経由で接続するため、同じプライベートサブネット内にAmazon Systems Managerで管理するEC2を立てます。
- アウトバウンドの443接続を許可する新しいセキュリティグループ
ssm-outbound-sgを作成します。
アウトバウンドルール:
- プロトコル:HTTPS(443)
- 宛先:0.0.0.0/0
- 説明:SSMエンドポイントへの接続
- プライベートサブネット内のEC2がSSMエンドポイントへ接続できるよう、3つのVPCエンドポイントを作成します。
# Systems Managerエンドポイント
aws ec2 create-vpc-endpoint \
--vpc-id <vpc-id> \
--vpc-endpoint-type Interface \
--service-name com.amazonaws.<region>.ssm \
--subnet-ids <EC2をプロビジョニングするプライベートサブネットID> \
--security-group-ids <EC2が接続するセキュリティグループID(例:ec2-ssm)>
# SSM Messagesエンドポイント
aws ec2 create-vpc-endpoint \
--vpc-id <vpc-id> \
--vpc-endpoint-type Interface \
--service-name com.amazonaws.<region>.ssmmessages \
--subnet-ids <EC2をプロビジョニングするプライベートサブネットID> \
--security-group-ids <EC2が接続するセキュリティグループID(例:ec2-ssm)>
# EC2 Messagesエンドポイント
aws ec2 create-vpc-endpoint \
--vpc-id <vpc-id> \
--vpc-endpoint-type Interface \
--service-name com.amazonaws.<region>.ec2messages \
--subnet-ids <EC2をプロビジョニングするプライベートサブネットID> \
--security-group-ids <EC2が接続するセキュリティグループID(例:ec2-ssm)>
- プライベートサブネット内に、Amazon Linuxを使ったGraviton EC2(例:t4g.small)を作成します。
- このEC2に次のセキュリティグループをアタッチします。
- 同一セキュリティグループに対してアウトバウンドポート4000を許可するLitellm-proxy。これにより、このプロキシEC2からECSタスクに接続できます。
- EC2からSSMエンドポイントへの接続を許可する
ssm-outbound-sg。
3. EC2の準備ができたら、SSMエージェントを使ってポートフォワーディング付きで接続します。
aws ssm start-session \
--target <EC2インスタンスID(例:i-012345)> \
--document-name AWS-StartPortForwardingSessionToRemoteHost \
--parameters host="<ECSタスクのプライベートIP>",portNumber="4000",localPortNumber="4000"
ステップ4:AIコーディング支援環境を構成する
マーケットプレイス(例:https://open-vsx.org/extension/Continue/continue)からContinue.devをインストールし、ローカルの設定ファイルを開きます。

作成したECSタスクをモデルプロバイダーとして設定します。

"models": [\
{\
"title": "litellm",\
"provider": "openai",\
"model": "jumpstart-model",\
"apiBase": "http://localhost:4000/",\
}\
],
設定を更新したら、ファイルを添付してAIによる支援を受けられます。



注:エンジニアの端末からLiteLLMプロキシエンドポイントへの接続には、AWS Client VPNなどを利用したセキュアな経路の確保を強く推奨します。
まとめとお問い合わせ
Amazon SageMaker上でLLMをホストすれば、企業は強力なコントロールと堅牢なデータプライバシーを手にし、ソフトウェア開発の生産性を大きく引き上げられます。DoiT International は、お客様の要件に最適化されたセルフホスト型かつセキュアでコスト効率の高いAIソリューションの設計から実装まで、専門家として伴走します。
セキュアにコーディング能力を強化しませんか?エンタープライズAI戦略のご相談、データプライバシーやコンプライアンス対応については、今すぐ DoiT International までお問い合わせください。