OSS として公開された ガバメント AI「源内」 について、源内 AI アプリ の方を閉域の AWS 環境へデプロイできるようにした記事を書きました。
源内 Web(AI インターフェース)の方を閉域ネットワークで動かすのは難しいのかなと思っていたのですが、Kubota さん(@infra365)から、源内の元となった GenU の 閉域モード についてヒントをもらったので、早速源内 Web を閉域ネットワークの AWS 環境にデプロイできないか検証してみました。
結論として、GenU の閉域モードの CDK のコードを一部移植して改変することで、似たような形で閉域ネットワークの AWS 環境へデプロイすることができました。
源内 Web の閉域デプロイ構成図
基本的には GenU の閉域モードと同じ構成になります。
源内 Web はフロントエンドが CloudFront + WAF でサーバーレスなアーキテクチャになっています。これらは閉域ネットワークでは動作しないため、フロントエンドは Application Load Balancer(ALB)と ECS に変更し、Lambda は VPC へ配置するようにします。
また、VPC と VPC エンドポイントを作成し、インターフェース型 VPC エンドポイント経由で必要な AWS のサービスへアクセスできるようにします。
CDK の変更方針について
基本的に GenU の閉域モードに関する部分 の CDK のコードを源内に再移植しました。具体的には、GenU のリポジトリの主に以下の部分です。
- packages/cdk/fargate-s3-server/*
- packages/cdk/lib/construct/closedNetwork/*
- packages/cdk/lib/closed-network-stack.ts
CDK コードの変更箇所が多いため、Github に源内からフォークして改変したものをアップしています。よかったら参考にしてください。
デプロイ手順
事前準備
源内の事前準備のドキュメント を参考に、Node.js, AWS CLI, AWS CDK CLI, jq をインストールし、依存関係のインストールと、必要に応じて CDK Bootstrap を実行します。
また、Docker イメージのビルドも必要になるため、Docker もインストール・起動する必要があります。
AWS Certificate Manager で ALB 用の TLS 証明書を作成
フロントエンドとなる ALB で HTTPS を終端する構成とするため、事前に AWS Certificate Manager(ACM)で ALB 用の TLS 証明書を作成しておきます。ACM は源内をデプロイするリージョンと同じリージョンのものを使用します。
パブリック証明書でも問題がないため、検証ではパブリック証明書を作成し、ARN を控えておくことにします。
ACM で ALB 用のパブリック証明書を発行する手順は過去に記事を書いていますので、よかったら参考にしてください。
設定ファイルの修正
ここからは基本的に 源内のデプロイ手順のドキュメント とほとんど同じです。
テンプレートファイルの作成
以下のとおり、テンプレートファイルからデプロイする環境用のファイルを作成します。ここでは self-hosting-dev.ts というファイルを作成することにしました。
$ cd packages/cdk/env-parameters
$ cp self-hosting-template.ts self-hosting-dev.ts
self-hosting-dev.ts ファイルの閉域ネットワークに関する設定を抜粋します。設定内容はコメントのとおりです。
ここで、closedNetworkCertificateArn の値は、事前に ACM で発行していた証明書の ARN を指定します。
export const selfHostingDevParams: Partial<StackInput> = {
// ============================================================================
// Closed Network 設定(必須)
// ============================================================================
/**
* 新規 VPC の CIDR
* オプション
* デフォルト: '10.1.0.0/16'
*/
closedNetworkVpcCidr: '10.129.0.0/16',
/**
* Private Hosted Zone のドメイン名
* 必須: Yes
* ALB + ACM + Route53 で HTTPS を提供するために使用します
* 例: 'genai.example.internal'
*/
closedNetworkDomainName: 'genai.intra.morori.jp',
/**
* ACM 証明書 ARN
* 必須: Yes
* 注意: アプリのリージョン(modelRegion と同じ)で発行された証明書を指定してください。
* us-east-1 ではありません(CloudFront を使わないため)。
*/
closedNetworkCertificateArn:
'arn:aws:acm:ap-northeast-1:xxxxxxxxxxxx:certificate/xxxxxxxx',
/**
* 既存の Private Hosted Zone ID(任意)
* オプション
* 指定した場合は既存の Hosted Zone を利用し、ALB の A レコードはユーザーが
* 別途作成してください。指定しなければスタックが新規 PrivateHostedZone を作成します。
*/
// closedNetworkPrivateHostedZoneId: 'Z1234567890ABC',
parameter.ts の修正
packages/cdk/parameter.ts の deploy_envs オブジェクトに、作成した設定ファイルをインポートして追加します。
ここではデプロイ先の環境を selfHostingDev としました。
import { selfHostingDevParams } from "./env-parameters/self-hosting-dev";
const deploy_envs: Record<string, Partial<StackInput>> = {
"-selfHostingDev": selfHostingDevParams,
// 他の環境も追加可能
};
デプロイ先リージョンの設定
packages/cdk/cdk.context.json の AWS アカウント ID の箇所を実際にデプロイするアカウントのものに修正します。
また、デプロイ先のリージョンとなっていることを確認してください。
{
"availability-zones:account=123456789012:region=ap-northeast-1": [
"ap-northeast-1a",
"ap-northeast-1c",
"ap-northeast-1d"
]
}
ローカルからデプロイ
事前に aws login コマンドなどでクレデンシャルを取得します。
$ aws login
CDK Deploy を実行します。env には先に設定した -selfHostingDev を指定します。
$ npm -w packages/cdk run cdk -- deploy --all --require-approval never -c env=-selfHostingDev
今回の検証ではデプロイ完了まで約 10 分かかりました。
源内 Web へサインインするためのユーザーの作成
デプロイが完了したら、Cognito のユーザープールに源内 Web へサインインするためのユーザーを追加します。
今回セルフサインアップ機能は検証せず、Cognito のユーザープールに直接マネジメントコンソールからユーザーを追加しました。
セルフサインアップ機能を使わない場合の Cognito でのユーザー追加手順は以下のとおりです。
- デプロイ完了後に作成された Cognito User Pool の管理画面にアクセスし、以下の設定でユーザーを手動で登録してください
- 招待メッセージ: E メールで招待を送信を選択
- E メールアドレスを検証済みとしてマーク: チェックを入れる
- 仮パスワード: パスワードの生成を選択
- ユーザーを登録後、UserGroup グループにユーザーを追加してください
- 初回ログイン用のパスワードが記載されたメールを確認しパスワードを控えてください
digital-go-jp/genai-web / docs / アカウント登録 から引用
以上で源内 Web を使用するための準備は全て完了です。
源内 Web の動作検証
デプロイに成功したら、源内 Web の動作検証をします。
今回は源内 Web がデプロイされているプライベートサブネットに Windows Server の EC2 インスタンスを立てて、Windows Server の Web ブラウザーから源内 Web へアクセスして動作検証しました。
packages/cdk/env-parameters/self-hosting-dev.ts の closedNetworkDomainName に設定していたドメイン名に HTTPS でアクセスしてみます。
サインイン画面が表示されました。メールアドレスとパスワードは、先ほど Cognito で作成したものを入力します。その後パスワードを再設定する画面などへ遷移し、設定が完了すると源内 Web のトップページが表示されます。
源内 Web は汎用アプリとして、チャット、文章作成、翻訳、文字起こしが使えるようです。別途 AI アプリを開発して連携させることで、行政実務用 AI アプリをどんどん追加していけるような構成になっています。
チャットを試してみます。
選択した LLM でチャットに応答してくれます。LLM のモデルとリージョンは packages/cdk/env-parameters/self-hosting-dev.ts で設定変更が可能です。
次に文章作成と翻訳を試します。
しっかり動作していることが確認できました。音声ファイルの文字起こしは試しませんでしたが、便利な汎用アプリが使えるのはいいですね。
源内 Web を閉域ネットワークで動かすときの制限事項など
以上のとおり、源内 Web も閉域ネットワークの AWS 環境で動作させることができました。
しかし、インターネット環境にデプロイする場合と異なり、一部の機能に制約があり、注意が必要です。
SAML による外部 IdP とのシングルサインオンは使用できない
GenU の閉域モードと同様に、SAML による外部 IdP とのシングルサインオンは使用できないため、源内 Web へのサインインは Cognito ユーザープール、ID プールを使うユーザー名とパスワードによる認証となります。
クライアントは VPC エンドポイントの名前解決が必要
源内 Web にアクセスするクライアントは、源内 Web が使用しているインターフェース型 VPC エンドポイントの名前解決をできる必要があります。クライアントのブラウザーから ALB だけでなく、execute-api や cognito-identity など一部のエンドポイントへ直接アクセスできる必要があるためです。
そのため、実際に地方自治体がガバメントクラウドの基幹業務システムの環境へ源内 Web をデプロイしてオンプレミス環境から使いたい場合、ネットワーク集約アカウントにインターフェース型 VPC エンドポイントを集約し、オンプレミス環境の DNS リゾルバーとネットワーク集約アカウントの Route 53 インバウンドエンドポイントを連携して、オンプレミス環境から VPC エンドポイントの名前解決をできるようにするとよいでしょう。
コストにも注意
直接の制限事項ではありませんが、閉域ネットワークへ源内 Web をデプロイする構成では、ALB と Fargate が必要になり、ALB はサービス時間外に停めるといった運用はできないため、固定的なコストがかかります。
また、インターフェース型 VPC エンドポイントの数がかなり多いので、これもコスト増となります。
上記のとおり、ネットワーク集約アカウントへの VPC エンドポイントの集約を検討した方がよいです。
閉域ネットワークで源内 Web を動かしてみた感想
制限事項はありつつ、地方自治体の基幹業務システムがあるガバメントクラウドのような閉域ネットワークの AWS 環境で源内のように拡張性の高い生成 AI サービスを使えるのは非常にメリットがありそうです。
源内 Web を閉域ネットワークの生成 AI サービスのハブとして用意し、外部 AI アプリを SaaS から調達する、といった使い方ができそうだと思いました。





