本記事は 夏休みクラウド自由研究 8/1付の記事です。 |
こんにちは、広野です。
以前、以下の記事で Amazon Bedrock や Agents for Amazon Bedrock を使用した最小構成 RAG 環境構築を紹介しておりました。当時はAmazon Bedrock 関連のリソースを一部 AWS CloudFormation ではデプロイできなかったのですが、今はサポートされたためにできるようになりました。
当時の構成を現在は変更しており、Knowledge Base に使用するデータベースを Amazon OpenSearch Serverless から Aurora Serverless v2 Postgresql に変更しています。
本シリーズ記事では、環境構築用の AWS CloudFormation のサンプルテンプレートを 3 記事に分けて紹介します。説明を分割するため、テンプレートを3つに分けていますのでご了承ください。
初回は VPC 編です。
本記事で取り扱う構成
RAG 環境全体の構成
以下のアーキテクチャで、RAG アプリケーションを構築しています。このうち、赤枠の部分が本シリーズ記事で取り扱う箇所です。series 1 VPC 編では、Amazon Aurora Serverless v2 Postgresql を構築する際に必要な VPC について説明します。
VPC の構成
Amazon Aurora Serverless v2 をデプロイするためには VPC が必要になります。サーバーレスなんですが、VPC リソースからアクセス可能にするためにそのような仕様にしているのだと思います。以下の VPC を用意します。
- Aurora Serverless はプライベートサブネットに配置します。リーダーインスタンスやレプリカは設定していません。
- Aurora Serverless を配置するときに、RDS サブネットグループが必要になります。任意の 2 つ以上のサブネットをグループに登録します。これが Aurora Serverless の設定で必要になるため、マルチ AZ 構成が必須になります。
- データベースなので、プライベートサブネットに配置します。選択したサブネットに、VPC 内からアクセスするためのエンドポイントが作成されます。ただし Agents for Amazon Bedrock からは Data API 経由で接続するため、VPC は通りません。
- エンドポイントにはセキュリティグループを関連付けます。ここでは、サブネットの CIDR から Postgresql に接続するためのデフォルトポート番号を開けておきます。
- Agents for Amazon Bedrock が Aurora Serverless に接続するときのクレデンシャルは、Secrets Manager から取得します。これについては次回の記事で紹介します。
- NAT ゲートウェイは本記事では省略しました。
AWS CloudFormation テンプレート
図に掲載している、Amazon Aurora Serverless、Agents for Amazon Bedrock、Secrets Manager は次回記事のテンプレートに含まれます。
Aurora Serverless で使用する RDS サブネットグループとセキュリティグループはここで作成し、次回のテンプレートで使用するためリソース情報をエクスポートしておきます。
AZ は仕様上、使用可能な 2 つの AZ をアルファベット順に前から選定します。東京リージョンだと b が使用できないため a と c が選定されますが、多くのリージョンでは a と b が選定されます。ここでは、東京リージョンでの使用を想定して a と c がリソースの名前に使用されています。ご注意ください。
AWSTemplateFormatVersion: 2010-09-09 Description: The CloudFormation template that creates A VPC, Subnets, an Internet Gateway and Routings. Additionally, a RDS subnet group and a security group for Aurora serverless. # ------------------------------------------------------------# # Input Parameters # ------------------------------------------------------------# Parameters: SubName: Type: String Description: System sub name of sample. (e.g. test) Default: test MaxLength: 10 MinLength: 1 VPCCIDR: Type: String Description: IP Address range for your VPC (16 bit mask) Default: 192.168.0.0/16 MaxLength: 14 MinLength: 10 AllowedPattern: ^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){2}0\.0/16$ PublicSubnetACIDR: Type: String Description: IP Address range for your public subnet A (24 bit mask) Default: 192.168.1.0/24 MaxLength: 16 MinLength: 10 AllowedPattern: ^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}0/24$ PublicSubnetCCIDR: Type: String Description: IP Address range for your public subnet C (24 bit mask) Default: 192.168.2.0/24 MaxLength: 16 MinLength: 10 AllowedPattern: ^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}0/24$ PrivateSubnetACIDR: Type: String Description: IP Address range for your private subnet A (24 bit mask) Default: 192.168.101.0/24 MaxLength: 16 MinLength: 10 AllowedPattern: ^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}0/24$ PrivateSubnetCCIDR: Type: String Description: IP Address range for your private subnet C (24 bit mask) Default: 192.168.102.0/24 MaxLength: 16 MinLength: 10 AllowedPattern: ^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}0/24$ Resources: # ------------------------------------------------------------# # VPC # ------------------------------------------------------------# VPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VPCCIDR EnableDnsSupport: true EnableDnsHostnames: true InstanceTenancy: default Tags: - Key: Name Value: !Sub sample-VPC-${SubName} - Key: Cost Value: !Sub sample-${SubName} InternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: !Sub sample-IGW-${SubName} - Key: Cost Value: !Sub sample-${SubName} InternetGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: InternetGatewayId: !Ref InternetGateway VpcId: !Ref VPC # ------------------------------------------------------------# # Subnet # ------------------------------------------------------------# PublicSubnetA: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select - 0 - Fn::GetAZs: !Ref AWS::Region CidrBlock: !Ref PublicSubnetACIDR MapPublicIpOnLaunch: true VpcId: !Ref VPC Tags: - Key: Name Value: !Sub sample-Public-a-${SubName} - Key: Cost Value: !Sub sample-${SubName} PublicSubnetC: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select - 1 - Fn::GetAZs: !Ref AWS::Region CidrBlock: !Ref PublicSubnetCCIDR MapPublicIpOnLaunch: true VpcId: !Ref VPC Tags: - Key: Name Value: !Sub sample-Public-c-${SubName} - Key: Cost Value: !Sub sample-${SubName} PrivateSubnetA: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select - 0 - Fn::GetAZs: !Ref AWS::Region CidrBlock: !Ref PrivateSubnetACIDR VpcId: !Ref VPC Tags: - Key: Name Value: !Sub sample-Private-a-${SubName} - Key: Cost Value: !Sub sample-${SubName} PrivateSubnetC: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select - 1 - Fn::GetAZs: !Ref AWS::Region CidrBlock: !Ref PrivateSubnetCCIDR VpcId: !Ref VPC Tags: - Key: Name Value: !Sub sample-Private-c-${SubName} - Key: Cost Value: !Sub sample-${SubName} # ------------------------------------------------------------# # Subnet Group for RDS # ------------------------------------------------------------# PrivateSubnetGroup: Type: AWS::RDS::DBSubnetGroup Properties: DBSubnetGroupName: !Sub sample-${SubName} DBSubnetGroupDescription: !Sub Subnet Group for KB database for sample-${SubName} SubnetIds: - !Ref PrivateSubnetA - !Ref PrivateSubnetC Tags: - Key: Cost Value: !Sub sample-${SubName} # ------------------------------------------------------------# # Security Group for RDS # ------------------------------------------------------------# AuroraSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupName: !Sub bedrock-rag-kb-sample-${SubName} GroupDescription: !Sub Allow Aurora PostgreSQL for sample-${SubName} VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 5432 ToPort: 5432 CidrIp: !Ref PrivateSubnetACIDR - IpProtocol: tcp FromPort: 5432 ToPort: 5432 CidrIp: !Ref PrivateSubnetCCIDR Tags: - Key: Cost Value: !Sub sample-${SubName} - Key: Name Value: !Sub sg-bedrock-rag-kb-sample-${SubName} # ------------------------------------------------------------# # RouteTable # ------------------------------------------------------------# PublicRouteTableA: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC PublicRouteTableC: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC PrivateRouteTableA: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC PrivateRouteTableC: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC # ------------------------------------------------------------# # Routing to Internet # ------------------------------------------------------------# PublicRouteA: Type: AWS::EC2::Route Properties: RouteTableId: !Ref PublicRouteTableA DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway PublicRouteC: Type: AWS::EC2::Route Properties: RouteTableId: !Ref PublicRouteTableC DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway # ------------------------------------------------------------# # RouteTable Associate # ------------------------------------------------------------# PublicSubnetARouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PublicSubnetA RouteTableId: !Ref PublicRouteTableA PublicSubnetCRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PublicSubnetC RouteTableId: !Ref PublicRouteTableC PrivateSubnetARouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateSubnetA RouteTableId: !Ref PrivateRouteTableA PrivateSubnetCRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateSubnetC RouteTableId: !Ref PrivateRouteTableC # ------------------------------------------------------------# # Output Parameters # ------------------------------------------------------------# Outputs: # Subnet PrivateSubnetGroupName: Value: !Ref PrivateSubnetGroup Export: Name: !Sub sample-${SubName}-PrivateSubnetGroupName # Security Group AuroraSecurityGroupId: Value: !Ref AuroraSecurityGroup Export: Name: !Sub sample-${SubName}-AuroraSecurityGroupId
まとめ
いかがでしたでしょうか?
VPC 作成テンプレートはどこにでもある情報だと思いますし、マネジメントコンソールでも以前より簡単に作れるようになっているので必要性は低いかもしれませんが、私は普段からこのテンプレートを活用して VPC をデプロイしています。
次回は Knowledge Base 用 Aurora Serverless のデプロイがテーマです。
本記事が皆様のお役に立てれば幸いです。