GitHub Copilotを用いてCloudFormationテンプレートを作成をした際の使い心地

# 1. 概要
ローカル環境で開発したRailsアプリのインフラ部分をAWSで構築しているが、コスト削減のために、使わないときはリソースを簡単に削除できるように可能な限りCloudFormationでIaC化したいと考えている。
今回はシステム規模が小さいため、以下のAWSの公式ドキュメントを参照しながら各AWSリソースのプロパティを確認し、手動でテンプレートを作成してもそこまで時間はかからないと思われるが、それでもAIに任せた方が効率は良いと思うので、GitHub Copilotの使用感の確認も兼ねて、GitHub Copilotにテンプレートを作成してもらう。

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html

# 2. 利用方針

せっかくなのでGitHub Copilotにテンプレートファイルを全て作成してもらって、コードに問題があればGitHub Copilotにその都度修正してもらうことで、テンプレートファイルを作成する。
ついでに、何ラリーで想定したテンプレートファイルが作成されるかをカウントしてみる。

GitHub Copilotへのプロンプトを記述する際の注意点やコツは以下のドキュメントに整理されていたので、できるだけこれに沿ってプロンプトを作成する。

https://docs.github.com/ja/enterprise-cloud@latest/copilot/using-github-copilot/prompt-engineering-for-github-copilot

# 3. いきなり結果
GitHub Copilotに任せてCloudFormationテンプレートを作成した結果、たった3ラリーでほとんど完成済みのテンプレートを出力してくれた！！
また、自分のプロンプト不備に起因するテンプレートの間違いも割とあったので、プロンプトの間違いをなくせば、1〜2ラリーでテンプレート完成させることもできそう。
パラメータの細かいミス等を自分で行い、短時間でテンプレートを完成させることができた。

# 4. プロンプト内容
今回3ラリーでテンプレートをほぼ完成の状態に持っていくことができたが、各ラリーでどのようなプロンプトをGitHub Copilotに与えたのか以下に記載する
#### 1ラリー目
```
ローカル環境で自作したRailsアプリを本番公開するための環境をAWSで構築しており、
AWSリソースを可能な限りCloudFormationテンプレートで定義したいと考えています。
以下にシステムの仕様を記載するため、これをもとにテンプレートをYaml形式で作成してください。

■システム概要
・RailsアプリのWebコンテナはECS Fargateを利用してホストする。
・データベースとしてはRDS PostgreSQLを使用する。
・利用者がアプリケーションにアクセスするまでの流れとしては以下の通り。
　CloudFrontディストリビューションにHTTPSアクセス→ALBにHTTPSアクセス→ECSクラスター内で定義されているタスクにHTTPアクセス
・ALB、ECSは同じパブリックサブネットに配置し、RDSのみプライベートサブネットに配置する。
・VPCはデフォルトのVPCを使用する


■利用するAWSサービス一覧
・VPC
・RDS
・ALB
・CloudFront


■テンプレートで作成するAWSサービスごとのリソース一覧
○VPC
・サブネット
→サブネットはアカウント内に最初から存在するデフォルトのVPC内に作成してください
→パブリックサブネット2つ、プライベートサブネット二つをそれぞれap-northeast-1a、ap-northeast-1cに作成してください
→パブリックサブネットの名前はalcohol-pub-subnet-01とalcohol-pub-subnet-02で、CIDRは172.31.0.0/27、172.31.0.32/27
→プライベートサブネットの名前はalcohol-prv-subnet-01とalcohol-prv-subnet-02で、CIDRは172.31.0.64/27、172.31.0.96/27
・ルートテーブル
→パブリックサブネットにアタッチするルートテーブルの名前はalcohol-routetbl-pub、プライベートサブネットにアタッチするルートテーブルの名前はalcohol-routetbl-prv
→alcohol-routetbl-pubに紐づけるIGWはVPC内にデフォルトで存在するものを使用してください
・セキュリティグループ
→ALB用の「alcohol-sg-alb」、ECS用の「alcohol-sg-ecs」、RDS用の「alcohol-sg-rds」をそれぞれ作成してください
→一般のユーザがECS内で起動したRailsアプリにアクセスでき、ECSからRDSへのアクセスも可能なようにセキュリティグループを設定設定してください

○RDS
・サブネットグループ
→サブネットグループの名前はalcoho-subnet-groupにしてください
→alcohol-prv-subnet-01とalcohol-prv-subnet-02を含めてください。
・RDSインスタンス
→エンジンタイプは「PostgreSQL」を使用してください
→テンプレートは「無料利用枠」を使用してください
→DB クラスター識別子はalcohol-rdsにしてください
→マスターユーザー名は「postgresql」にしてください
→パスワード名は「password」にしてください
→DBインスタンスクラスはdb.t3.microにしてください
→パブリックアクセスはなしでお願いします
→アベイラビリティゾーンはap-northeast-1aにしてください
→Alcohol_productionという名前の初期データベースを作成してください

○ALB
・ターゲットグループ
→alcohol-target-groupという名前のターゲットグループを作ってください
・ALB
→「alcohol-alb」という名前にしてください
→HTTPリスナーとHTTPSリスナーをそれぞれ作成してください

○CloudFront
・ディストリビューション
→オリジンはALBを指定してください。
→許可されたHTTPメソッドとしては「GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE」にしてください
→WAFは無効でお願いします

```
→この時点で9割完成したテンプレートを出力

#### 2ラリー目
※リソースID等はマスクしています。
```
以下の通りにコードを修正願います。

・現状、各VPCリソースでデフォルトVPCのIDを参照するとき、「VpcId: !Ref DefaultVPC」と言う形で参照していると思いますが、
デフォルトVPCのIDである「vpc-XXXXXXXXXXXXXXXX」という値を「VpcId: !FindInMap [DefaultVPCID]」と言う形で取り出せるように
Mappingsセクションを用いて変数化していただくようお願いします。

・上記に関連して、各VPCリソースでデフォルトVPC内のIGWのIDを参照するとき、「GatewayId: !Ref DefaultIGW」と言う形で参照していると思いますが、
IGWのIDである「igw-XXXXXXXXXXXXXXXX」という値を「GatewayId: !FindInMap [DefaultIGWID]」と言う形で取り出せるように
Mappingsセクションを用いて変数化していただくようお願いします。

・alcohol-sg-albからalcohol-sg-ecsへのHTTPアクセスが可能なようにアウトバウンドルールを追加願います。

・alcohol-sg-ecsからalcohol-sg-rdsへのPostgreSQLアクセスが可能なようにアウトバウンドルールを追加願います。

・サブネットグループの名前はalcohol-subnet-groupにしてください

・CloudFrontディストリビューションには以下のarnの証明書を紐づけていただくようお願いします。
「arn:aws:acm:us-east-1:XXXXXXXXXXXX:certificate/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX」

・ALBには以下のarnの証明書を紐づけていただくようお願いします。
「arn:aws:acm:ap-northeast-1:XXXXXXXXXXXX:certificate/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX」

・ARN等で12桁のアカウントIDが指定されているところは「${AWS::AccountId}」と言う形で変数を埋め込む形にしてもらうようお願いします。
（!Subで指定することで埋め込み可能になると思います）

```

#### 3ラリー目
```
・AlcoholSGALB、AlcoholSGECS、AlcoholSGRDSが循環依存の状態になっていると言うエラーが発生しました。
そのため、Type: AWS::EC2::SecurityGroup内でインバウンドルール、アウトバウンドルールを定義するのではなく、
「AWS::EC2::SecurityGroupEgress」「AWS::EC2::SecurityGroupIngress」という形でType: AWS::EC2::SecurityGroup内
内から分離して記載する形に変更してください。
```
→この時点で完成したテンプレートからCloudFormationスタックを起動したところ、エラー等発生せず正常に動作したので、あとは細かいパラメータ等を修正して、完成！！

# 5. 結果
テンプレート作成をGitHub Copilotにお願いすることで、テンプレート作成の時間を大幅に短縮できた。
ただ、テンプレート作成時間はプロンプトの質によって変わってくると思うので、より具体的に記載することを意識することで、時間をより短縮できると思われる。
ただ、テンプレートの細かい部分は自分で修正したほうが早いと思うので、テンプレートの基礎的な文法は押さえておく必要がある。