目次
ご挨拶
お疲れ様です、寺井です。
「ChatGPT」盛り上がってますね~~
SNSなどで話題になっているので、私も存在は知っていたのですが、触ったことは無い状態でした。
今回はChatGPT先生がどれほどの方なのか、CloudFormationのテンプレートを作ってもらうことで試してみたいと思います。
ChatGPTってなに?
Wikiでは以下のように記載されています。
ChatGPT(チャットジーピーティー、Generative Pre-trained Transformer)[1]は、OpenAIが2022年11月に公開した人工知能チャットボット。OpenAIのGPT-3ファミリーの言語モデルを基に構築されており、教師あり学習と強化学習の両方の手法で転移学習されている。
参考:ウィキペディア(ChatGPT)
なるほど、分からん。
とにかくすごそうなので「百聞は一見にしかず」ということで、使ってみましょう。
必要なもの
ChatGPTアカウント
「ChatGPT」を使用するにはアカウント登録が必要です。
アカウントがまだ無いという方は以下のページよりアカウント登録を行ってください。
ChatGPT登録ページ
AWSアカウント
今回はCloudFormationテンプレートを流してリソースを作ろうと思いますので、CloudFormationが使用できる環境を用意します。
CloudFormationでスタックを作成するので、CloudFormationが使用できるIAMロールも作成しておきます。
やってみる
ChatGPT生成
チャット欄に
EC2を使用して、パブリックに公開されたWEBサーバーを作成するCloudFormationテンプレートを作ってほしい
と入力しました。
こんな雑な聞き方で大丈夫なんでしょうか。やってみます。
おおおおお~~~!どんどん書かれていってます!!
生成には少し時間がかかりますので、ちょっと待ちます。
完成したようです!
ChatGPTさんは文字数制限からなのか固まってしまってますが、テンプレートは出来てるっぽいので良しとしましょう。
生成されたテンプレートの内容はこちら
---
AWSTemplateFormatVersion: "2010-09-09"
Description: Create a public web server using EC2
Parameters:
InstanceType:
Type: String
Default: t2.micro
AllowedValues: [t2.micro, t2.small, t2.medium]
Description: EC2 instance type
KeyName:
Type: AWS::EC2::KeyPair::KeyName
Description: Name of an existing EC2 KeyPair to enable SSH access to the instances
AMI:
Type: AWS::EC2::Image::Id
Description: AMI ID for the Amazon Linux 2 image
Default: ami-0a887e401f7654935 # Amazon Linux 2 AMI
Resources:
EC2Instance:
Type: AWS::EC2::Instance
Properties:
InstanceType: !Ref InstanceType
ImageId: !Ref AMI
KeyName: !Ref KeyName
SecurityGroupIds:
- !Ref InstanceSecurityGroup
UserData:
Fn::Base64: !Sub |
#!/bin/bash
yum update -y
yum install httpd -y
systemctl start httpd
systemctl enable httpd
echo "<html><body><h1>Hello from your new web server!</h1></body></html>" > /var/www/html/index.html
InstanceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Enable HTTP and HTTPS access
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
Outputs:
WebsiteURL:
Description: URL for the website
Value: !Sub "http://${EC2Instance.PublicDnsName}/"
コードの内容をコピーして.yamlファイルとして保存しておきます。
テンプレートの内容
- OSはAmazon Linux 2
- 「Parameters」セクションで[インスタンスタイプ]・[AMI]・[キーペア]を受け取る
- 「ユーザーデータ」でApacheをインストールして[/var/www/html/index.html]にページ作成
- [80]と[443]のポートでインバウンド許可する「セキュリティグループ」を設定
- 「Outputs」で対象のWEBサーバーにアクセスするURLを出力
という内容のようです。
ではこのCloudFormationテンプレートを実際に流してみたいと思います。
スタックの作成
CloudFormation>スタック>スタックの作成
- テンプレートの準備 :テンプレートの準備完了
- テンプレートソース :テンプレートファイルのアップロード
- テンプレートファイルのアップロード :「ファイルを選択」から先程保存したテンプレートファイルを選択
スタックの名前をつけて、お好きなインスタンスタイプ・キーペアを選択
- タグ :任意
- アクセス許可 :前準備で作成したCFn用のIAMロールを選択
- スタックの失敗オプション:すべてのスタックリソースをロールバックする
「詳細オプション」は必要であれば設定してください。
最終画面で問題なければ「送信」から作成を実行します。
スタックの作成エラー
スタックがロールバックしたので内容を確認したところ、指定したAMIが存在しなかったようです。
Parameter validation failed: parameter value ami-0a887e401f7654935 for parameter name AMI does not exist. Rollback requested by user.
リージョンを変更してスタックの作成
調べてみるとChatGPTさんが使用したAMIは「米国東部 (バージニア北部)us-east-1」のものでした。
「us-east-1」でスタックを作成すると、無事作成完了しました!
「出力」タブにWEBサーバーにアクセスするURLが表示されているのでアクセスしてみます。
ブラウザでもWEBサーバーが起動されていることを確認できました。
え、すごくないですか??
ChatGPT生成(2回目)
次はちょっと難しめに、いくつか要件をあげてみます。
以下の要件を踏まえてCloudFormationのテンプレートを作成してほしい
・東京リージョンで起動
・LAMP環境
・EC2に「phpMyAdmin」を使用してRDSのデータベースを表示できるページを用意
さっきの反省も活かしてリージョンも東京で指定します。
生成が止まってしまいました。
文字数制限がある(?)とのことなので、分割してでもいいからどんどん続けてもらいます。
最終的に完成したテンプレートはこちらです。
(※かなり長いのでご注意)
クリックで開く
---
Parameters:
KeyName:
Description: EC2インスタンスのキーペア
Type: AWS::EC2::KeyPair::KeyName
InstanceType:
Description: EC2インスタンスのインスタンスタイプ
Type: String
Default: t2.micro
AllowedValues:
- t2.micro
- t2.small
- t2.medium
DBName:
Description: データベース名
Type: String
DBUser:
Description: データベースのユーザ名
Type: String
DBPassword:
Description: データベースのパスワード
Type: String
NoEcho: true
Resources:
# VPC作成
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-VPC
# サブネット作成
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: ap-northeast-1a
CidrBlock: 10.0.1.0/24
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-PublicSubnet1
# インターネットゲートウェイ作成
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-InternetGateway
# VPCとインターネットゲートウェイを紐付け
VPCGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref InternetGateway
VpcId: !Ref VPC
# ルートテーブル作成
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-PublicRouteTable
# サブネットとルートテーブルを紐付け
PublicSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet1
RouteTableId: !Ref PublicRouteTable
# インターネットに接続するためのルートを作成
PublicRoute:
Type: AWS::EC2::Route
DependsOn: VPCGatewayAttachment
Properties:
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
RouteTableId: !Ref PublicRouteTable
# セキュリティグループ作成
WebSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP and SSH traffic
SecurityGroupIngress:
# HTTPのインバウンドアクセスを許可
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
# SSHのインバウンドアクセスを許可
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
VpcId: !Ref VPC
GroupName: !Sub ${AWS::StackName}-WebSecurityGroup
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-WebSecurityGroup
# EC2インスタンス作成
WebInstance:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-0c55b159cbfafe1f0 # Amazon Linux 2 LTS
InstanceType: !Ref InstanceType
KeyName: !Ref KeyName
NetworkInterfaces:
- AssociatePublicIpAddress: true
DeviceIndex: 0
GroupSet:
- !Ref WebSecurityGroup
SubnetId: !Ref PublicSubnet1
UserData:
Fn::Base64: !Sub |
#!/bin/bash
yum update -y
yum install -y httpd24 php72 php72-mysqlnd
chkconfig httpd on
service httpd start
cd /var/www/html
echo "" > index.php
# phpMyAdminのインストール
cd /tmp
wget https://files.phpmyadmin.net/phpMyAdmin/5.1.0/phpMyAdmin-5.1.0-all-languages.tar.gz
tar xzf phpMyAdmin-5.1.0-all-languages.tar.gz
mv phpMyAdmin-5.1.0-all-languages /var/www/html/phpmyadmin
rm phpMyAdmin-5.1.0-all-languages.tar.gz
# config.inc.phpの作成
cd /var/www/html/phpmyadmin
cp config.sample.inc.php config.inc.php
sed -i "s/\$cfg\['Servers'\]\[\$i\]\['host'\] = 'localhost';/\$cfg['Servers'][\$i]['host'] = '${DBEndpoint}';/" config.inc.php
sed -i "s/\$cfg\['Servers'\]\[\$i\]\['user'\] = 'root';/\$cfg['Servers'][\$i]['user'] = '${DBUser}';/" config.inc.php
sed -i "s/\$cfg\['Servers'\]\[\$i\]\['password'\] = '';/\$cfg['Servers'][\$i]['password'] = '${DBPassword}';/" config.inc.php
sed -i "s/\$cfg\['Servers'\]\[\$i\]\['AllowNoPassword'\] = false;/\$cfg['Servers'][\$i]['AllowNoPassword'] = true;/" config.inc.php
# RDS作成
RDS:
Type: AWS::RDS::DBInstance
Properties:
DBInstanceClass: !Ref DBInstanceClass
Engine: mysql
MasterUsername: !Ref DBUser
MasterUserPassword: !Ref DBPassword
AllocatedStorage: !Ref DBAllocatedStorage
DBInstanceIdentifier: !Sub ${AWS::StackName}-rds
MultiAZ: false
StorageType: gp2
VPCSecurityGroups:
- !Ref DBSecurityGroup
DBSubnetGroupName: !Ref DBSubnetGroup
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-RDS
# RDSセキュリティグループ作成
DBSecurityGroup:
Type: AWS::RDS::DBSecurityGroup
Properties:
GroupDescription: Allow MySQL traffic
DBSecurityGroupIngress:
- EC2SecurityGroupName: !Ref WebSecurityGroup
EC2SecurityGroupOwnerId: !Ref AWS::AccountId
# WebサーバーからMySQLへのアクセスを許可
# Webサーバーのセキュリティグループを参照する
# ※EC2SecurityGroupOwnerIdには自身のアカウントIDを指定
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-DBSecurityGroup
# RDSサブネットグループ作成
DBSubnetGroup:
Type: AWS::RDS::DBSubnetGroup
Properties:
DBSubnetGroupDescription: Subnet group for RDS
SubnetIds:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-DBSubnetGroup
とりあえずCloudFormationで流してみます。
スタックの作成
先ほどと同じ手順でスタックの作成を行います。
スタックの作成エラー
以下のようなエラーが。
Template format error: Unresolved resource dependencies [DBAllocatedStorage, DBInstanceClass] in the Resources block of the template
テンプレート内でリソースの依存関係が上手くいっていないようです。
結果
ChatGPT先生に色々問い詰めてみましたが、こちらの聞き方が悪いのか、ベストな解決策を教えてくれることはありませんでした。
完璧ではなかったものの、テンプレートの大部分を作成してくれたので、これだけでも作業時間がグッと減らせるのでは?と思います。
ChatGPT「Too many requests」エラー
また、試行錯誤してリクエストしまくってたら、以下のようなエラーが出てしばらく使えなくなりました。
「Too many requests in 1 hour. Try again later.」
あまりにも短期間にリクエストし過ぎるとこのようになるので、ご利用は計画的に。
感想
「ChatGPT」に全く同じ質問を投げかけても、返ってくる回答はその都度異なることが多いです。
AIが返しやすいような聞き方をするとか、これからAIと上手く付き合っていくために、使い手のスキルアップが必要だと感じました。
上手く使うことができれば、単純な作業はほぼこれで解決できるようになるんでしょうか…。
もっと鍛錬を積んで、AIと仲良くなれるように精進します。
ここまでお付き合いいただきありがとうございました。
好きなこと:音楽、猫、お酒、ゲーム、効率化
経歴:音楽専門学校 → テレビ業界AD → 通信回線代理店 → IT関連職業訓練 → 2022.12~ 株式会社ディーネット