4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

閉域モード版源内のデプロイ手順とオンプレミスと接続する時の注意点

4
Posted at

ガバメント AI 源内(genai-web)を閉域ネットワークでも動作するように、源内のフロントエンドを CloudFront から ALB + ECS Fargate に変更し、Lambda を VPC 内へ配置するようにした上で AWS サービスにはインターフェース VPC エンドポイントで到達できるよう変更したフォーク(閉域モード版源内)を作りました。

このフォークは、VPC エンドポイントを含めて必要な AWS リソースを全て CDK で作成できるようになっています。

しかし、いざガバメントクラウドのような閉域ネットワークに閉域モード版源内をデプロイしようとした時に、いくつか注意点が分かりました。

閉域モード版源内を閉域ネットワークにデプロイする時の注意点とは

オンプレミスまでのルートの確保

閉域モード版源内でデプロイされるのは単独の VPC(以下「源内 VPC」)であるため、オンプレミスとのネットワーク接続を別途作る必要があります。

ガバメントクラウドの閉域ネットワークでは、Direct Connect でオンプレミスと AWS が接続されています。また、複数の VPC が接続されることから、Direct Connect Gateway (DXGW) と Transit Gateway (TGW) を使うことが多いです。そして、DXGW と TGW は、ネットワークアカウントという共有リソース用のアカウントに集約することが一般的です。

そのため、閉域モード版源内をデプロイした後、CDK Deploy とは別の手順で、源内 VPC に作成されたプライベートサブネットと TGW をアタッチメントで接続し、同様に源内 VPC に作成された VPC ルートテーブルへオンプレミスへのルートを登録することにします。

インターフェース VPC エンドポイントの名前解決

閉域モード版源内では、CDK で必要な VPC エンドポイントをデプロイするようになっています。

しかし、ガバメントクラウドの閉域ネットワークでは、ネットワークアカウントに VPC(以下「共有リソース VPC」)を作成し、Route 53 インバウンドエンドポイントやその他インターフェース型 VPC エンドポイントを集約させる構成が多く見られます。

また、共有リソース VPC の Route 53 インバウンドエンドポイントは、AWS 環境の名前解決に必要なオンプレミスの DNS リゾルバーからの条件付きフォワード先に設定されているケースが多いです。

そのため、閉域モード版源内で必要な VPC エンドポイントをオンプレミスからも名前解決させるには、主に以下のパターンが考えられます。

  1. 源内 VPC に作成したインターフェース型 VPC エンドポイントのうち、オンプレミスのクライアントから直接アクセスさせる必要があるもののみ、エンドポイントと同名の Route 53 Private Hosted Zone (PHZ) を作成し、共有リソース VPC へ関連付けを行う
  2. CDK でインターフェース型 VPC エンドポイントを作成するのをやめて、全て共有リソース VPC へ作成するようにし、エンドポイントと同名の Route 53 PHZ を作成し、源内 VPC へ関連付けを行う

コスト効率を考えると後者の方がよいですが、この場合 CDK を修正しなければならないので、今回は前者のパターンで閉域モード版源内をデプロイしてみます。

構成図は以下のとおりです。

genai-web.drawio.png

閉域モード版源内のデプロイ手順

事前準備

ランタイム等のインストール

Node.js, AWS CLI, jq, Docker をインストールします。手順は割愛します。

依存関係のインストール

閉域モード版源内のルートディレクトリで依存ライブラリをインストールします。

$ npm ci

CDK Bootstrap

初めて CDK を使う AWS アカウントやリージョンの場合、CDK Bootstrap を実行します。

$ npm -w packages/cdk run cdk -- bootstrap

Docker サービスの起動

ECS の Docker イメージをビルドするのに Docker が必要なので、Docker サービスを起動しておきます。

AWS Certificate Manager で Application Load Balancer 用の TLS 証明書を作成

事前に AWS Certificate Manager (ACM) で Application Load Balancer (ALB) 用の TLS 証明書を作成しておきます。手順は割愛します。

Elastic Container Registry のレジストリポリシーを修正

Elastic Container Registry (ECR) のプライベートレジストリにレジストリポリシーで制限をかけている場合、CDK からの操作を許可しておかないとデプロイできません。

具体的には以下の IAM ロールからの操作をレジストリポリシーの許可ルールへ追加する必要があります。

IAM ロール ロール名のパターン ECR を使う場面
CDK のイメージ発行ロール cdk-hnb659fds-image-publishing-role-* デプロイ元マシンからのフロントエンド配信コンテナの push
Fargate タスク実行ロール GenerativeAiUseCasesStack-* タスク起動時のイメージ pull

Bedrock から Claude を初めて使う場合はユースケースの送信

源内では Bedrock から Claude のモデルを使うことがあるので、デプロイする AWS アカウントで初めて Bedrock から Claude のモデルを使う場合は、事前に Bedrock のマネジメントコンソールから任意の Claude のモデルのプレイグラウンドを開き、画面の指示に従ってユースケースを送信してください。

CDK のパラメーター等設定

テンプレートファイルの作成

以下のとおり、テンプレートファイルからデプロイする環境用のファイルを作成します。ここでは self-hosting-prod.ts というファイルを作成することにしました。

$ cd packages/cdk/env-parameters
$ cp self-hosting-template.ts self-hosting-prod.ts

self-hosting-prod.ts ファイルの閉域ネットワークに関する設定を抜粋します。設定内容はコメントのとおりです。

ここで、closedNetworkCertificateArn の値は、事前に ACM で発行していた証明書の ARN を指定します。

packages/cdk/env-parameters/self-hosting-prod.ts
export const selfHostingProdParams: 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',

  /**
   * 利用者端末(オンプレミス)側の CIDR リスト
   * 必須: 専用線/VPN 越しのオンプレミス端末から利用する場合は Yes
   * VPC エンドポイント共通 SG と ALB の SG の許可対象に追加されます。
   * ブラウザは Cognito・API Gateway・Lambda・S3(署名付き URL)を VPC エンドポイント
   * 経由で直接呼び出すため、未設定だとオンプレミス端末からはサインインもできません。
   * 例: ['172.16.0.0/12', '192.168.10.0/24']
   */
  closedNetworkAllowedClientCidrs: ['10.1.0.0/16','10.128.0.0/16'],

parameter.ts の修正

packages/cdk/parameter.ts の deploy_envs オブジェクトに、作成した設定ファイルをインポートして追加します。

ここではデプロイ先の環境を selfHostingProd としました。

packages/cdk/parameter.ts
import { selfHostingProdParams } from "./env-parameters/self-hosting-prod";

const deploy_envs: Record<string, Partial<StackInput>> = {
  // 他の環境も追加可能
  "-selfHostingProd": selfHostingProdParams,
};

デプロイ先リージョンの設定

packages/cdk/cdk.context.json の AWS アカウント ID の箇所を実際にデプロイするアカウントのものに修正します。

また、デプロイ先のリージョンとなっていることを確認してください。

packages/cdk/cdk.context.json
{
  "availability-zones:account=123456789012:region=ap-northeast-1": [
    "ap-northeast-1a",
    "ap-northeast-1c"
  ]
}

ローカルから CDK をデプロイ

事前に aws login コマンドなどでクレデンシャルを取得します。

$ aws login

CDK Deploy を実行します。env には先に設定した -selfHostingProd を指定します。

$ npm -w packages/cdk run cdk -- deploy --all --require-approval never -c env=-selfHostingProd

デプロイに成功すると、コンソールに以下のような出力があります。

スクリーンショット 2026-07-05 11.09.27.png

源内 Web へサインインするためのユーザーの作成

デプロイが完了したら、Cognito のユーザープールに源内 Web へサインインするためのユーザーを追加します。

閉域モード版源内はセルフサインアップ機能を使用できないので、Cognito のユーザープールに直接マネジメントコンソールからユーザーを追加する必要があります。

セルフサインアップ機能を使わない場合の Cognito でのユーザー追加手順は以下のとおりです。

  1. デプロイ完了後に作成された Cognito User Pool の管理画面にアクセスし、以下の設定でユーザーを手動で登録してください
    • 招待メッセージ: E メールで招待を送信を選択
    • E メールアドレスを検証済みとしてマーク: チェックを入れる
    • 仮パスワード: パスワードの生成を選択
  2. ユーザーを登録後、UserGroup グループにユーザーを追加してください
  3. 初回ログイン用のパスワードが記載されたメールを確認しパスワードを控えてください

digital-go-jp/genai-web / docs / アカウント登録 から引用

TGW アタッチメントの作成及び VPC ルートテーブルの追加

閉域モード版源内では VPC に 2 つのプライベートサブネットを作成します。

ここからは手動で、閉域モード版源内からオンプレミスと接続できるよう、オンプレミスまでのルートがある TGW にアタッチメント接続を作ります。

その後、2 つのプライベートサブネットに関連付けられている 2 つの VPC ルートテーブルに、オンプレミスと共有リソース VPC へのルートとして、ネクストホップを TGW としたルートを追加します。

参考に、CDK Deploy で出力された源内 VPC のサブネット ID とルートテーブル ID などをセットして CloudFormation で上記の作業を行う時の参考スクリプトは以下のとおりです。

AWSTemplateFormatVersion: 2010-09-09
Description: This template deploys a TGW Attachments for genai-web VPC.

Parameters:
  VPC2Id:
    Description: Please select the genai VPC ID
    Type: AWS::EC2::VPC::Id

  PrivateSubnet1Id:
    Description: Please select the private subnet in the first Availability Zone
    Type: AWS::EC2::Subnet::Id

  PrivateSubnet2Id:
    Description: Please select the private subnet in the second Availability Zone
    Type: AWS::EC2::Subnet::Id

  PrivateSubnet1RouteTableId:
    Description: Please enter the genai route table 1 ID
    Type: String

  PrivateSubnet2RouteTableId:
    Description: Please enter the genai route table 2 ID
    Type: String
    
  OnpremisesCidr:
    Description: Please enter the Onpremises CIDR
    Type: String
    Default: 10.0.0.0/8

  TGWId:
    Description: Please enter the TGW ID
    Type: String

  VPC1Cidr:
    Description: Please enter the Shared Resource VPC CIDR
    Type: String
    Default: 10.128.0.0/16

Resources:
  # オンプレミス宛てのルートテーブルはネクストホップを TGW とする
  PrivateSubnet1RouteTableRoute1:
    Type: AWS::EC2::Route
    DependsOn: TGWAttachment2
    Properties:
      DestinationCidrBlock: !Ref OnpremisesCidr
      RouteTableId: !Ref PrivateSubnet1RouteTableId
      TransitGatewayId: !Ref TGWId

  # VPC1(共有リソース VPC)宛てのルートテーブルはネクストホップを TGW とする
  PrivateSubnet1RouteTableRoute2:
    Type: AWS::EC2::Route
    DependsOn: TGWAttachment2
    Properties:
      DestinationCidrBlock: !Ref VPC1Cidr
      RouteTableId: !Ref PrivateSubnet1RouteTableId
      TransitGatewayId: !Ref TGWId

  # オンプレミス宛てのルートテーブルはネクストホップを TGW とする
  PrivateSubnet2RouteTableRoute1:
    Type: AWS::EC2::Route
    DependsOn: TGWAttachment2
    Properties:
      DestinationCidrBlock: !Ref OnpremisesCidr
      RouteTableId: !Ref PrivateSubnet2RouteTableId
      TransitGatewayId: !Ref TGWId

  # VPC1(共有リソース VPC)宛てのルートテーブルはネクストホップを TGW とする
  PrivateSubnet2RouteTableRoute2:
    Type: AWS::EC2::Route
    DependsOn: TGWAttachment2
    Properties:
      DestinationCidrBlock: !Ref VPC1Cidr
      RouteTableId: !Ref PrivateSubnet2RouteTableId
      TransitGatewayId: !Ref TGWId

  #
  # TGW アタッチメントを作成
  #
  TGWAttachment2:
    Type: AWS::EC2::TransitGatewayAttachment
    Properties:
      Options:
        DnsSupport: enable
        SecurityGroupReferencingSupport: enable
      SubnetIds:
        - !Ref PrivateSubnet1Id
        - !Ref PrivateSubnet2Id
      Tags:
        - Key: Name
          Value: genai-tgw-attach-vpc-tokyo
      TransitGatewayId: !Ref TGWId
      VpcId: !Ref VPC2Id

Outputs:

  TGWAttachment2:
    Value: !Ref TGWAttachment2
    Export:
      Name: TGWAttachment2Id

源内 VPC 側のルートテーブル等が変更できたら、共有リソース VPC 側や TGW のルートテーブルに源内 VPC 向けのルートを追加してください。手順は割愛します。

なお、これらの変更は CDK でデプロイされたものへの変更になるため、CDK Destroy で削除する時は必ず先に上記のルートテーブル等を元に戻してから削除するようにしてください。

オンプレミスのクライアントから必要なエンドポイントを名前解決させる

閉域モード版源内へのクライアントからの接続について、フロントの ALB だけではなく、いくつかのインターフェース型 VPC エンドポイントへ直接アクセスする必要があります。

# 解決すべき DNS 名 解決先 用途
1 cognito-idp.<リージョン>.amazonaws.com Cognito IDP エンドポイント サインイン・トークン取得
2 cognito-identity.<リージョン>.amazonaws.com Cognito Identity エンドポイント 一時クレデンシャル取得
3 *.execute-api.<リージョン>.amazonaws.com API Gateway エンドポイント REST API(メイン + チーム管理)
4 lambda.<リージョン>.amazonaws.com Lambda エンドポイント チャットストリーミング応答の直接 Invoke
5 s3.<リージョン>.amazonaws.com*.s3.<リージョン>.amazonaws.com S3 Interface エンドポイント 署名付き URL でのファイル送受信(バケット名付きの仮想ホスト形式で解決されるためワイルドカードが必要)
6 closedNetworkDomainName に設定したドメイン 内部 ALB アプリ本体の画面

そこで、以下の手順でこれらのエンドポイントと同名の Route 53 PHZ を作成し、Route 53 インバウンドエンドポイントのある共有リソース VPC に関連付けることで、オンプレミスのクライアントからも上記エンドポイントを名前解決できるようになります。

  1. CDK デプロイ後、源内 VPC の VPC エンドポイントの DNS エントリを確認
  2. サービス名と同名の Route 53 PHZ を、共有リソース VPC に関連付けて作成
  3. 作成した Route 53 PHZ へ VPC エンドポイントへの Alias レコードを追加

ただし、既に共有リソース VPC に上記のインターフェース型 VPC エンドポイントがある場合はこの作業をしないでください。この作業をしてしまうと、既存の共有リソース VPC と連携しているオンプレミスや他の VPC の名前解決に影響があります。

Route 53 PHZ の作成が必要なものは以下のとおりです。

ゾーン名 作成するレコード名
cognito-idp.ap-northeast-1.amazonaws.com ゾーン頂点(ゾーン名と同じ)
cognito-identity.ap-northeast-1.amazonaws.com ゾーン頂点
execute-api.ap-northeast-1.amazonaws.com *.execute-api.ap-northeast-1.amazonaws.com(ワイルドカード)
lambda.ap-northeast-1.amazonaws.com ゾーン頂点
s3.ap-northeast-1.amazonaws.com ゾーン頂点 と *.s3.ap-northeast-1.amazonaws.com の 2 レコード

VPC エンドポイントの DNS エントリを確認

作成した VPC エンドポイントの DNS 名を確認します。

スクリーンショット 2026-07-05 13.15.10.png

サービス名と同名の Route 53 PHZ を作成

サービス名と同名の Route 53 PHZ を、共有リソース VPC に関連付けて作成します。

スクリーンショット 2026-07-05 13.17.42.png

作成した Route 53 PHZ へ VPC エンドポイントへの Alias レコードを追加

作成した Route 53 PHZ へ、先ほど確認した VPC エンドポイントの DNS 名への Alias レコードを追加します。

スクリーンショット 2026-07-05 13.28.07.png

以下同様の手順となります。一部アスタリスクで設定するものがあることに注意してください。

以上の作業が終わったら、オンプレミスから閉域モード版源内へ接続できるはずです。

オンプレミスから閉域モード版源内への接続確認

以下のように源内のログイン画面が表示されればネットワーク接続は成功です。

スクリーンショット 2026-07-05 150535.png

Cognito でユーザープールに追加したユーザーでログインできれば、無事閉域モード版源内を使うことができます。

まとめ

閉域モード版源内をガバメントクラウドのような閉域ネットワークにデプロイする際は、主にネットワーク関係で追加の作業が生じます。

特に名前解決については、環境によりベストな方法が異なると思うので、事前にしっかり設計してからデプロイするようにしましょう。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?