ChatGPTでAWS CloudFormationテンプレートを作成してみた

2023年9月29日掲載

キービジュアル

こんにちは。ソリューションエンジニアの谷口です。

AWS CloudFormation のテンプレートをChatGPTに書かせてみました。プロンプトに工夫を加えているので、プロンプトエンジニアリングの参考にしていただけると幸いです。

また本記事は、IaC(Infrastructure as Code)に挑戦してみたい方向けの記事です。今後、構築するリソースを拡張した記事をドンドン上げる予定です。お楽しみに!

目次

※ChatGPTの回答は確率的に生成されており、本記事で紹介したプロンプトを入力しても同様の返答が得られるとは限らないこと、あらかじめご了承ください。

とりあえずChatGPTにCloudFormationのテンプレートを作成してもらった

AWSでシステムを構築する際にまず作成するのは、VPCとサブネットではないでしょうか。特に、1つのVPCの中で、2つのアベイラビリティーゾーンに跨ったパブリックサブネットとプライベートサブネットを配置する以下のような構成はいわゆる「あるある構成」の筆頭かと思います。

AWS構成図

ではまずは、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を少しかじったことがある人は違和感をもったのではないでしょうか。

Resource map Lv1 プロンプトLv1で作成されたテンプレートを用いたデプロイ状況

 

サブネットを4つ作成してくれているので、一見上手くいっているように見えますが、パブリックサブネットの定義は「インターネットに接続されるサブネット」です。インターネットゲートウェイ(以下、IGW)が作成されておらずインターネットへの出入口はありませんし、もちろんサブネットからIGWへ通信がルーティングされるようなルートテーブルもありません。

他にも、命名規則がバラバラであることや、CIDRブロックが標準のもので確定されていることなど、気になるところはいくつもあります。

SEとしてリソースを作成する際に気をつける要件を整理し、適切に自動構築してくれるテンプレートを作成できるプロンプトを作成していきましょう。

リソースを作成するときの要件とは

求めている構成を満たすために必要な要件をピックアップしていきました。
今回は作成リソース要件7件とオプション要件4件をターゲットにし、前章のプロンプトで達成できた要件については〇、できなかった要件については✖を記載しています。

要件表とプロンプトLv1の結果 要件表とプロンプト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個ずつ作成できるようになっています。

Resource map Lv2 プロンプトLv2で作成されたテンプレートを用いたデプロイ状況

 

しかし依然として、IGWの作成、アタッチや、パブリックサブネットからIGWへのルート追加は、GPT-3.5もGPT-4も反映してくれませんでした。

要件表とプロンプトLv2の結果 要件表とプロンプト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]]

 

見事、想定構成を作成できるテンプレートを作成してくれ、すべての要件を満たすことができました!

 

Resource map Lv3 プロンプトLv3で作成されたテンプレートを用いたデプロイ状況
要件表とプロンプトLv3の結果 要件表とプロンプトLv3の結果

作成したプロンプトの将来の展望

ここまで想定したテンプレートを作成してもらうために、「###コード作成条件」を編集する形で実現してきました。実は、「###作成リソース」に「インターネットゲートウェイ」と「パブリックサブネット用ルートテーブル」を追記することでも、想定したテンプレートを作成できることは確認していました。

ではなぜ「###コード作成条件」を編集することに終始したかというと、「###作成リソース」が不十分だったとしても、質問者が作成したい環境を察して補完できることを実証するためでした。

CloudFormation のテンプレート作成用の事前プロンプトに「###コード作成条件」を組み込み、初心者の方などがAWSの知識を網羅的に把握していなくても、イメージした構成図を反映できるような補完機能を搭載した環境の構築ができることを確信しました。

今後AWS環境開発用のプラグインを開発する際は、今回のようなナレッジを反映させることで、精度を大幅に向上させることができるでしょう。

まとめ

ここまでの説明で、ChatGPTでCloudFormationのテンプレートが作成できることは証明できたかと思います。ただし、「###コード作成条件」のプロンプトを作りこまなければ、想定通りの構成とならないことがあるので注意は必要です。GPT-4であったとしても、察する力には限界があるため、GPTのレベルアップを待つ前に、プロンプトエンジニアリング力の向上にも力を入れていきましょう!

是非今回紹介したプロンプトを参考にしてみてください!

今回考慮した要件はほんの一部であるので、他にも以下のような要件に合わせてプロンプトを作成してみましょう!

  • DNSオプションの設定
  • NATゲートウェイの作成
  • JSON/YAMLの指定
  • EC2などの他リソースの作成

次回は、EC2などの他のリソース作成も伴う、より複雑なテンプレートをChatGPTに作成させたものを記事にしたいと思います!

最後までお読みいただき、ありがとうございました!
皆さまも、ChatGPTを上手く活用して楽にタスクを処理していきましょう!

関連サービス

Amazon Web Services (AWS)

ソフトバンクはAWS アドバンストティアサービスパートナーです。「はじめてのAWS導入」から大規模なサービス基盤や基幹システムの構築まで、お客さまのご要望にあわせて最適なAWS環境の導入を支援します。

おすすめの記事

条件に該当するページがございません