フォーム読み込み中
こんにちは。ソリューションエンジニアの谷口です。
AWS CloudFormation のテンプレートをChatGPTに書かせてみました。プロンプトに工夫を加えているので、プロンプトエンジニアリングの参考にしていただけると幸いです。
また本記事は、IaC(Infrastructure as Code)に挑戦してみたい方向けの記事です。今後、構築するリソースを拡張した記事をドンドン上げる予定です。お楽しみに!
※ChatGPTの回答は確率的に生成されており、本記事で紹介したプロンプトを入力しても同様の返答が得られるとは限らないこと、あらかじめご了承ください。
AWSでシステムを構築する際にまず作成するのは、VPCとサブネットではないでしょうか。特に、1つのVPCの中で、2つのアベイラビリティーゾーンに跨ったパブリックサブネットとプライベートサブネットを配置する以下のような構成はいわゆる「あるある構成」の筆頭かと思います。
ではまずは、ChatGPTにVPCを1つ、パブリックサブネットを2つ、プライベートサブネットを2つ作成するテンプレートを作成するようにお願いしてみました。
(なぜこの構成にしたかというと、実はすべてのリソースが無料で壁打ちしやすかったからだったりします。皆さまもAWS利用料に怯えず、気楽に色々試してみましょう!)
【プロンプト】
| AWS上で以下の作成リソースを作成するCloudFormationのテンプレートを作成してください。 ###作成リソース ・VPC 1個 ・パブリックサブネット 2個 ・プライベートサブネット 2個 |
【GPT-3.5の回答】
AWSTemplateFormatVersion: '2010-09-09'
Description: Create VPC with Public and Private Subnets
Resources:
MyVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsSupport: true
EnableDnsHostnames: true
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
CidrBlock: 10.0.0.0/24
MapPublicIpOnLaunch: true
PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
CidrBlock: 10.0.1.0/24
MapPublicIpOnLaunch: true
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
CidrBlock: 10.0.2.0/24
PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
CidrBlock: 10.0.3.0/24
Outputs:
VPCId:
Description: VPC ID
Value: !Ref MyVPC
PublicSubnetIds:
Description: Comma-separated list of Public Subnet IDs
Value: !Join [',', [!Ref PublicSubnet1, !Ref PublicSubnet2]]
PrivateSubnetIds:
Description: Comma-separated list of Private Subnet IDs
Value: !Join [',', [!Ref PrivateSubnet1, !Ref PrivateSubnet2]]
結果はどうでしょうか。確かに依頼した作成リソースは作ってくれましたが、AWSを少しかじったことがある人は違和感をもったのではないでしょうか。
プロンプトLv1で作成されたテンプレートを用いたデプロイ状況
サブネットを4つ作成してくれているので、一見上手くいっているように見えますが、パブリックサブネットの定義は「インターネットに接続されるサブネット」です。インターネットゲートウェイ(以下、IGW)が作成されておらずインターネットへの出入口はありませんし、もちろんサブネットからIGWへ通信がルーティングされるようなルートテーブルもありません。
他にも、命名規則がバラバラであることや、CIDRブロックが標準のもので確定されていることなど、気になるところはいくつもあります。
SEとしてリソースを作成する際に気をつける要件を整理し、適切に自動構築してくれるテンプレートを作成できるプロンプトを作成していきましょう。
求めている構成を満たすために必要な要件をピックアップしていきました。
今回は作成リソース要件7件とオプション要件4件をターゲットにし、前章のプロンプトで達成できた要件については〇、できなかった要件については✖を記載しています。
要件表とプロンプトLv1の結果
求めていた構成を作成するためには、#1~7のAWSリソースを作成する必要がありました。
今回のプロンプトでは、#1~3のリソースしか作成できていなかったため、#4~7の作成リソース要件を満たせるようにプロンプトを工夫していきます。
また、オプション要件として#8~11を要件として設定し、管理のしやすさなどを考慮したオプション選択ができるように工夫していきます。
では今回のゴールも定まったところで、ChatGPTと壁打ちをすることで、どのようなプロンプトであれば想定したテンプレートを作成してくれるか、実験をしていきましょう。
先ほどのプロンプトに、5つのコード作成条件を追加してみました。
【プロンプト】
| AWS上で以下の作成リソースを作成するCloudFormationのテンプレートを作成してください。 ###作成リソース ・VPC 1個 ・パブリックサブネット 2個 ・プライベートサブネット 2個 ###コード作成条件 ・要件を満たすために必要なリソースがあれば追加で作成すること ・Parametersを用いて、リソース名を「{UserName}-{ResourceName}」とすること ・Parametersを用いて、CIDRブロックを編集できるようにすること ・東京リージョンに作成すること ・複数のアベイラビリティーゾーンに対して、パブリック/プライベートサブネットを各1個ずつ作成すること |
ポイントは、「要件を満たすために必要なリソースがあれば追加で作成すること」という指示を基に、パブリックサブネットを作成するということは、合わせてIGWの作成、アタッチや、パブリックサブネットからIGWへのルート追加が必要であることを察して作成してくれることを促す部分です。また、Parametersを用いてオプション設定値を編集する要件や、配置するアベイラビリティーゾーンを詳細に設定する要件も追加しました。
ChatGPTに聞いてみると、以下のテンプレートを作成してくれました。
【GPT-3.5の回答】
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
UserName:
Type: String
Description: User name for resource naming
VpcCIDR:
Type: String
Default: 10.0.0.0/16
Description: CIDR block for the VPC
PublicSubnetCIDR1:
Type: String
Default: 10.0.0.0/24
Description: CIDR block for the first public subnet
PublicSubnetCIDR2:
Type: String
Default: 10.0.1.0/24
Description: CIDR block for the second public subnet
PrivateSubnetCIDR1:
Type: String
Default: 10.0.2.0/24
Description: CIDR block for the first private subnet
PrivateSubnetCIDR2:
Type: String
Default: 10.0.3.0/24
Description: CIDR block for the second private subnet
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VpcCIDR
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Sub "${UserName}-VPC"
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PublicSubnetCIDR1
AvailabilityZone: ap-northeast-1a
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub "${UserName}-PublicSubnet1"
PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PublicSubnetCIDR2
AvailabilityZone: ap-northeast-1c
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub "${UserName}-PublicSubnet2"
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PrivateSubnetCIDR1
AvailabilityZone: ap-northeast-1a
Tags:
- Key: Name
Value: !Sub "${UserName}-PrivateSubnet1"
PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PrivateSubnetCIDR2
AvailabilityZone: ap-northeast-1c
Tags:
- Key: Name
Value: !Sub "${UserName}-PrivateSubnet2"
Parametersが駆使されており、リソース作成時にユーザ名やCIDRブロックを入力できるようになっています。また、複数のアベイラビリティーゾーンに対して、パブリック/プライベートサブネットを各1個ずつ作成できるようになっています。
プロンプトLv2で作成されたテンプレートを用いたデプロイ状況
しかし依然として、IGWの作成、アタッチや、パブリックサブネットからIGWへのルート追加は、GPT-3.5もGPT-4も反映してくれませんでした。
要件表とプロンプトLv2の結果
ChatGPTに察してくれというのは、なかなか難問だったのかもしれません。(GPT-4は察してくれると信じていたのですが...)
逆に言えば、察し過ぎて想定外のリソースを作成してしまう方が不安であったため、この程度のtemperatureの方が安心とも言えるかもしれません。(temperatureとは、確率分布の鋭さや平坦さを調整するパラメータであり、小さいほど一貫性のある生成をし、大きいほど創造性のある生成をします。temperatureが大きいと、察してくれたのかはまた別の機会に検証してみたいと思います。)
ではChatGPTに「パブリックサブネットを作成する」とは何たるかを教えてみましょう。
【プロンプト】
| AWS上で以下の作成リソースを作成するCloudFormationのテンプレートを作成してください。 ###作成リソース ・VPC 1個 ・パブリックサブネット 2個 ・プライベートサブネット 2個 ###コード作成条件 ・要件を満たすために必要なリソースがあれば追加で作成すること ・Parametersを用いて、リソース名を「{UserName}-{ResourceName}」とすること ・Parametersを用いて、CIDRブロックを編集できるようにすること ・東京リージョンに作成すること ・複数のアベイラビリティーゾーンに対して、パブリック/プライベートサブネットを各1個ずつ作成すること ・パブリックサブネットを作成する際は、次の手順も実施すること。 ・インターネットゲートウェイの作成 ・インターネットゲートウェイをVPCへアタッチ ・インターネットゲートウェイへの経路を記載したパブリックサブネット用ルートテーブルの作成 ・パブリックサブネット用ルートテーブルをパブリックサブネットへ関連付け |
【GPT-3.5の回答】
AWSTemplateFormatVersion: '2010-09-09'
Description: CloudFormation template for creating VPC, public and private subnets
Parameters:
UserName:
Type: String
Description: Enter your username
Default: "UserName"
VpcCidrBlock:
Type: String
Description: CIDR block for the VPC
Default: "10.0.0.0/16"
PublicSubnetCidrBlock1:
Type: String
Description: CIDR block for the first public subnet
Default: "10.0.1.0/24"
PublicSubnetCidrBlock2:
Type: String
Description: CIDR block for the second public subnet
Default: "10.0.2.0/24"
PrivateSubnetCidrBlock1:
Type: String
Description: CIDR block for the first private subnet
Default: "10.0.3.0/24"
PrivateSubnetCidrBlock2:
Type: String
Description: CIDR block for the second private subnet
Default: "10.0.4.0/24"
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VpcCidrBlock
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Sub "${UserName}-VPC"
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub "${UserName}-InternetGateway"
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PublicSubnetCidrBlock1
AvailabilityZone: "ap-northeast-1a"
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub "${UserName}-PublicSubnet1"
PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PublicSubnetCidrBlock2
AvailabilityZone: "ap-northeast-1c"
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub "${UserName}-PublicSubnet2"
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PrivateSubnetCidrBlock1
AvailabilityZone: "ap-northeast-1a"
Tags:
- Key: Name
Value: !Sub "${UserName}-PrivateSubnet1"
PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PrivateSubnetCidrBlock2
AvailabilityZone: "ap-northeast-1c"
Tags:
- Key: Name
Value: !Sub "${UserName}-PrivateSubnet2"
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${UserName}-PublicRouteTable"
PublicRoute:
Type: AWS::EC2::Route
DependsOn: AttachGateway
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: "0.0.0.0/0"
GatewayId: !Ref InternetGateway
AssociatePublicSubnet1:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet1
RouteTableId: !Ref PublicRouteTable
AssociatePublicSubnet2:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet2
RouteTableId: !Ref PublicRouteTable
Outputs:
VpcId:
Description: VPC ID
Value: !Ref VPC
PublicSubnetIds:
Description: Public Subnet IDs
Value: !Join [",", [!Ref PublicSubnet1, !Ref PublicSubnet2]]
PrivateSubnetIds:
Description: Private Subnet IDs
Value: !Join [",", [!Ref PrivateSubnet1, !Ref PrivateSubnet2]]
見事、想定構成を作成できるテンプレートを作成してくれ、すべての要件を満たすことができました!
プロンプトLv3で作成されたテンプレートを用いたデプロイ状況
要件表とプロンプトLv3の結果
ここまで想定したテンプレートを作成してもらうために、「###コード作成条件」を編集する形で実現してきました。実は、「###作成リソース」に「インターネットゲートウェイ」と「パブリックサブネット用ルートテーブル」を追記することでも、想定したテンプレートを作成できることは確認していました。
ではなぜ「###コード作成条件」を編集することに終始したかというと、「###作成リソース」が不十分だったとしても、質問者が作成したい環境を察して補完できることを実証するためでした。
CloudFormation のテンプレート作成用の事前プロンプトに「###コード作成条件」を組み込み、初心者の方などがAWSの知識を網羅的に把握していなくても、イメージした構成図を反映できるような補完機能を搭載した環境の構築ができることを確信しました。
今後AWS環境開発用のプラグインを開発する際は、今回のようなナレッジを反映させることで、精度を大幅に向上させることができるでしょう。
ここまでの説明で、ChatGPTでCloudFormationのテンプレートが作成できることは証明できたかと思います。ただし、「###コード作成条件」のプロンプトを作りこまなければ、想定通りの構成とならないことがあるので注意は必要です。GPT-4であったとしても、察する力には限界があるため、GPTのレベルアップを待つ前に、プロンプトエンジニアリング力の向上にも力を入れていきましょう!
是非今回紹介したプロンプトを参考にしてみてください!
今回考慮した要件はほんの一部であるので、他にも以下のような要件に合わせてプロンプトを作成してみましょう!
次回は、EC2などの他のリソース作成も伴う、より複雑なテンプレートをChatGPTに作成させたものを記事にしたいと思います!
最後までお読みいただき、ありがとうございました!
皆さまも、ChatGPTを上手く活用して楽にタスクを処理していきましょう!
ソフトバンクはAWS アドバンストティアサービスパートナーです。「はじめてのAWS導入」から大規模なサービス基盤や基幹システムの構築まで、お客さまのご要望にあわせて最適なAWS環境の導入を支援します。
条件に該当するページがございません