【ChatGPTとUdemyで効率的に学ぶ方法】AWSとLaravelを例に紹介

## はじめに

この記事ではAWSを活用してLaravelをEC2上にデプロイしてRDS postgreSQLに接続するまでを学習した記録です。Udemy講座の「**Laravelシステム開発講座 【AWS PHP 8 Laravel 9 RDS(PostgresSQL)】**」を利用して学習しました。

講座が作成されてから少し時間がたってしまったようで、AWSの画面が動画と多少差異があったり、設定ミスによるエラーに遭遇しましたが、ChatGPTを活用することでエラーを効率的に対応できました。この、ChatGPTを活用した勉強方法についてもTips的な形で共有しようと思います。

Tipsだけでも読んでいってください！
[Tipsはこちら](#tips-chatgptを利用した学習の効率化)

下記キャンペーンに触発されて記事を書いています。
https://qiita.com/official-events/a7151fbde8cf94527b7f

## この記事の構成
最初に、Udemy講座の選定について紹介します。
実務でAWS関連の設計や構築等の経験がないため、ネットワークに関係する部分の基礎知識を記載します。（手書きは愛嬌です）
今回使用するAWSサービスについて紹介します。
EC2、RDSを乗せるVPCの設定、EC2,RDSの設定、Laravel自体の設定等の操作を記載します。
設定時に詰まったところを記載します。
最後にTipsとしてChatGPTを活用したUdemy講座での学習の効率化を紹介します。

## 受講したUdemy講座について【おすすめ】
Laravelシステム開発講座 【AWS PHP 8 Laravel 9 RDS(PostgresSQL)】
https://www.udemy.com/course/laravel-aws-system/

3.5時間の動画でLaravelをAWSで利用するハンズオン的な動画になっています。
EC2インスタンスとRDSの無料利用枠を活用して個人で学習する用のアプリ開発の幅を広げたいと思っていたところにちょうどいい講座でした。

短時間で学べるので、本当にAWSを利用したいけど、方法がわからない・イメージできないWebエンジニアにとっては非常に良い講座かと思います。
Udemy講座は長時間のものが多い印象ですが、短時間で学べるという点がこの講座の最重要ポイントかと思います。
EC2・RDSを活用する環境は結構多くて需要があるとも思いますのでぜひ受講を検討してみてください。

## ネットワーク 基礎知識
### リージョン・VPC・アベイラビリティゾーン(AZ)の関係
![IMG_4526.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/781232/039fdf1d-7034-9bb7-de52-d00994138c06.png)

VPCでは仮想のプライベートネットワーク空間を作成することになります。プライベートIPアドレスを設定することが推奨されていてます。
プライベートIPの例： 192.168.0.0 ~ 192.168.255.255

### サブネット
使用できるIPアドレスの範囲はサブネットで指定する。
サブネットとは/16とか/24みたいにIPアドレスの横に書いてあるもの。VPCを細かく区切ることができる。
下の図でなんとなくイメージしてください。
![IMG_4525.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/781232/b233f935-822a-ba08-de0e-8dec80ec5b21.png)

### ルーティング
下の図は東京リージョンに作成したVPCの１つのAZにプライベートサブネットとパブリックサブネットを作成しています。パブリックサブネットをインターネットに接続させるためのルート設定を表しています。

![IMG_4527.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/781232/97a1e011-c9c9-76fc-2f37-f6e993eabea4.jpeg)

## 今回使用したAWSサービスについて
### VPC

AWS（Amazon Web Services）のVPC（Virtual Private Cloud）は、ユーザーがAWSクラウド内にプライベートな仮想ネットワーク環境を作成できるサービスです。VPCを使用すると、ユーザーは自分のAWSリソース（例えば、EC2インスタンスやRDSデータベース）をこのプライベートな仮想ネットワーク内に配置し、セキュリティとネットワークの設定を制御することができます。

VPCは「セキュリティ」を強化します。ユーザーは自分のVPC内でセキュリティグループとネットワークアクセス制御リスト（NACL）を設定し、インバウンドとアウトバウンドのトラフィックを詳細に制御できます。

また、「カスタマイズ可能」なネットワーク設定もVPCの特徴です。ユーザーはIPアドレス範囲の選択、サブネットの作成、ルーティングテーブルの設定、ネットワークゲートウェイの設定など、自分のネットワーク環境を完全に制御できます。

さらに、VPCは「プライベート接続」を提供します。ユーザーは自分のオンプレミスのネットワークからAWS Direct ConnectやVPNを使用してVPCに安全に接続することができます。

これらの特性により、VPCはAWSリソースを安全に、かつ効率的に管理するための重要なツールとなっています。
### RDS
AWS（Amazon Web Services）のRDS（Relational Database Service）は、クラウド上でリレーショナルデータベースを設定、運用、スケーリングするためのサービスです。RDSは、アプリケーションに必要なデータベースを簡単に提供し、管理することができます。

RDSは「管理が容易」であるという特性を持っています。データベースソフトウェアのパッチ適用、バックアップ、故障復旧、フェイルオーバーなど、一般的に時間と労力を要するデータベース管理タスクを自動化します。

また、「スケーラビリティ」もRDSの重要な特性です。ユーザーはデータベースの要件に応じて、コンピューティングリソースとストレージを簡単にスケーリングすることができます。

さらに、「可用性と耐久性」もRDSの特徴です。マルチAZ（Availability Zone）デプロイメントを利用することで、データベースのダウンタイムを最小限に抑え、データの耐久性を高めることができます。

RDSは、MySQL、PostgreSQL、MariaDB、Oracle、SQL Server、Amazon Auroraなど、多くの人気のあるデータベースエンジンをサポートしています。これにより、開発者は自分たちが最も慣れ親しんだデータベース環境を選択して使用することができます。

750時間分無料で利用可能です。詳しくは[こちら](https://aws.amazon.com/jp/rds/free/)
### EC2
EC2（Elastic Compute Cloud）は、ユーザーが仮想サーバーをレンタルできるクラウドコンピューティングサービスです。これにより、ユーザーは自分のアプリケーションをホストしたり、データを処理したりするためのコンピューティングパワーを必要なだけ確保できます。
EC2は「スケーラブル」なサービスで、つまりユーザーは自分の需要に応じてコンピューティングリソースを増減することができます。これにより、トラフィックの増減に応じてリソースを調整し、コストを最適化することが可能です。
さらに、EC2は「柔軟性」があります。ユーザーは自分のニーズに合わせて、OS、アプリケーション、ストレージ、メモリ、CPUなどを選択できます。
無料利用枠として750時間使用可能です。無料利用枠については[こちら](https://aws.amazon.com/jp/ec2/pricing/)
Elastic IPを取得してアタッチしたEC2インスタンスを停止したままにすると料金が発生するのでご注意ください。
参考：https://qiita.com/s_tatsuki/items/c808a916acf044d94afc

## 以下、操作部分の注意点
- 操作はすべてap-northeast1（東京リージョン）で行います。
- 自分の操作メモを記載したものなため、わかりにくいかもしれません。
- すべて無料で利用可能な設定ですが、EC2のインスタンスがすべて停止した場合、RDSインスタンスがすべて停止している場合などは課金されます。無料利用枠については注意してください。

## ネットワーク 関連のAWS操作
1. VPCを作成する。
    「VPC」コンソールのメニューバーから「お使いのVPC」を選択し、「VPCを作成」のオレンジ色のボタンをクリック。
     適当な名前を付けて、IPv4 CIDRに 192.168.0.0/16 を設定
    
2. サブネットを作成。
    左のメニューバーからサブネットを選択し作成
    パブリックサブネット用に192.168.10.0/24
    プライベートサブネット用に192.168.20.0/24
    を作成する。
3. インターネットゲートウェイの作成
    左のメニューバーから「インターネットゲートウェイ」を選択して作成する。適当な名前を付けるのみ。
4. インターネットゲートウェイをVPCにアタッチ
    「アクション」ボタンから「VPCにアタッチ」を選択し１でつくったVPCを関連付ける
5. ルートテーブルの作成
    左のメニューバーから「ルートテーブル」を選択。
    新しく作成する。このとき、VPCは１で作ったものを使用する。
6. ルートテーブルにサブネットを関連付ける
    チェックをつけて下のメニューの「sサブネットの関連付け」をクリック
    パブリックサブネットとして作成したものを設定する。
7. ルートの設定
    下のメニューの「ルート」を選択してルートを編集します。
    送信先0.0.0.0./0でターゲットを３でつくったインターネットゲートウェイに設定して保存します。（３枚目の絵の設定です）
    

## EC2インスタンスを設定

1. 「EC2」から「インスタンスを起動」ボタンをクリック
    1. (以下設定が必要な部分だけ記載)
    2. 名前は適当に設定する
    3. アプリケーションおよびOSイメージは「Amazon Linux」を選択
    4. AMIの設定はAmazon Linux２のものを選択する。
    5. インスタンスタイプは「t2.micro」を選択
    6. キーペアの部分では「新しいキーペアの作成」をクリックしキーペア名を入力して作成
    7. ネットワーク設定の「編集」をクリック
        1. VPCは前の手順で作成したものを選択
        2. サブネットも前の手順で作成した、パブリックサブネットのものを選択
        3. パブリック IP の自動割り当ては有効化を選択(インターネットに接続するため)
        4. セキュリティグループを作成する
            1. 「セキュリティグループルールを追加」ボタンをクリック
            2. タイプが「HTTP」でソースに「0.0.0.0/0」を記載する
    8. インスタンスを起動をクリック
    9. 必ずキーペアをダウンロードする。(ここを逃すとダウンロードできない)
2. EC2ダッシュボードの左側のメニューから「Elastic IP」を選択
3. 「Elastic IP アドレスを割り当てる」をクリックしてElastic IPを取得する。
4. 「アクション」をクリックし、「Elastic IPアドレスの関連付け」を行う
    1. インスタンスは１の手順で作成したものを選択
    2. プライベートIPアドレスには198.168.10.10を設定
    
    注意：EC2インスタンスが停止している間、Elastic IPが割り当てられていると課金されてしまうので注意が必要

## VScodeからSSH接続する

1. 拡張機能から 「Remote SSH」を取得
2. 自分のローカルPCの.sshディレクトリ内でconfigファイルを作成
3. 2と同じディレクトリ内にEC2インスタンス作成時に取得したキーペアを置く
4. configファイルを設定する
    ```
    Host 任意の名前を記載
    HostName
    User ec2-user
    Port 22
    IdentityFile ~/.ssh/ダウンロードしたキーのファイル
    ```
5. Remote SSHを利用してVScodeからSSH接続する

## EC2インスタンス上でLaravelをインストールする
1. ターミナルを開いて、下記コマンドを入力する
```
# パッケージのアップデート
sudo yum update -y

# PHP の環境構築
# PHP8 をインストール
sudo amazon-linux-extras install -y php8.0

# 必要なモジュールをインストール
sudo yum install -y php-bcmath
sudo yum install -y php-mbstring
sudo yum install -y php-xml
sudo yum install -y php-dom
sudo yum install -y php-gd
sudo yum install -y php-intl

# 処理を高速化するために OPcache をインストールする。
sudo yum install -y php-opcache

# PHP-FPM をインストールする。
sudo yum install -y php-fpm

# PHP-FPM を起動する。サーバ再起動時も自動起動するよう設定する。その後確認。
sudo systemctl start php-fpm
sudo systemctl enable php-fpm
sudo systemctl status php-fpm

# Composer をインストールする。公式サイトに従ってコマンドを実行。
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
php -r "unlink('composer-setup.php');"

# Composer の場所を変更
sudo mv composer.phar /usr/local/bin/composer

# Nginx の環境構築
# Nginx をインストール。
sudo amazon-linux-extras enable nginx1
sudo yum install -y nginx

# Nginx を起動する。サーバ再起動時も自動起動するよう設定する。その後確認。
sudo systemctl start nginx
sudo systemctl enable nginx
sudo systemctl status nginx


# PHP-FPM と Nginx の接続
# PHP-FPM の設定ファイルを編集する。

cd /etc/php-fpm.d/
sudo cp www.conf www.conf_bk_20230516
sudo vim www.conf
```
2.開いたファイルの以下を変更。
```
### 24行目あたり ###
# 変更前
user = apache
# 変更後
user = nginx

### 26行目あたり ###
# 変更前
group = apache
# 変更後
group = nginx

### 48行目あたり ###
# 変更前
;listen.owner = nobody
# 変更後
listen.owner = nginx

### 49行目あたり ###
# 変更前
;listen.group = nobody
# 変更後
listen.group = nginx

### 50行目あたり ###
# 変更前
;listen.mode = 0660
# 変更後
listen.mode = 0660
```
3.Nginx の設定ファイルを編集する。
```
cd /etc/nginx/
sudo cp nginx.conf nginx.conf_bk_20211009
sudo vim nginx.conf
```
4.nginx.confを編集
```
server {
    listen       80;
    listen       [::]:80;
    server_name  _;
    root         /var/www/your_app_name/public;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";

    index index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass   unix:/run/php-fpm/www.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;
}
```
5.Nginxを再起動したのちLaravelをインストール
```
# Nginx を再起動。
sudo systemctl restart nginx

# 指定したドキュメントルートを作成
cd /var
sudo mkdir -p /var/www/

# 権限設定を変更
sudo chmod -R 777 www

# ec2-userフォルダに移動
cd /home/ec2-user

# Laravel9インストール
composer create-project laravel/laravel /var/www/your_app_name "9.*"

# パーミッションの設定
cd /var/www/your_app_name
sudo chmod -R 777 storage bootstrap/cache
```
6.AWS 「EC2」の「インスタンス」で作成したインスタンスを選択して下のメニューの「詳細」から「パブリックIPv4アドレス」を確認する。
7.ブラウザのURLに入力してLaravelの初期画面が出ることを確認する

## RDS設定

1. RDS用のプライベートサブネットを作成する
    1. VPCを開く
    2. 「サブネット」からサブネットを作成
    3. VPCは最初に作ったものを設定
    4. サブネット名を設定
    5. AZでap-northeast-1cに指定
    6. CIDRブロックに「192.168.21.0/24」を設定
    7. 「サブネットを作成」ボタンをクリック
2. RDS用のセキュリティグループを作成する
    1. 「EC2」を開く
    2. セキュリティグループを選択
    3. 名前と説明は適当に入力し、VPCは最初に作ったものを指定
    4. インバウンドルールを追加する。
        1. タイプにPostgreSQLを選択
        2. ソースはカスタムのまま、横の検索から、Webサーバー用に作成したセキュリティグループを選択する。
    5. 「セキュリティグループを作成」ボタンをクリックする。
3. RDS用サブネットグループを作成する
    1. RDSでメニューバーから「サブネットグループ」を選択
    2. 名前と説明を入力
    3. VPCは最初に作成したものを選択
    4. アベイラビリティゾーンは1aと１cを選択(192.168.20.0/24)・(192.168.21.0/24)
    5. 作成をクリック
4. RDS用にパラメーターグループを作成する
    1. メニューバーから「パラメータグループ」を選択
    2. 作成画面で設定
        1. パラメータグループファミリーに「postgres14」を選択
        2. 名前と説明を適切に入力
        3. 作成ボタンをクリック
5. 「データベースの作成」をクリックして設定
    1. PostgreSQLを選択（バージョンはデフォルトの12.7）
    2. テンプレートは「無料利用枠」を選択
    3. マスターユーザー名、マスターパスワードを設定
    4. 「ストレージの自動スケーリング」からチェックを外す
    5. 接続の設定で「EC2コンピューティングリソースに接続しない」を選択
    6. VPCは最初に作ったものを選択
    7. ３の手順で作成したサブネットグループをDBサブネットグループに設定
    8. VPCセキュリティグループでdefaultの設定を外し、EC2のセキュリティグループを設定
    9. AZは1aを設定
    10. 最初のデータベース名に任意のDB名を入力
    11. その他項目は任意
    12. 作成をクリック


## LaravelからRDSに接続する

1. Laravel用EC2インスタンスにSSH接続する。
2. /home/ec2-userディレクトリに移動
3. 以下コマンドを実行
    
    ```
    sudo yum install php-pdo_pgsql
    sudo systemctl restart php-fpm
    ```
    
4. LaravelのルートディレクトリをVScodeで開く。(/var/www/your_app_name)
5. .envファイルの以下の項目を変更して保存する
    - DB_CONNECTION=pgsql
    - DB_HOST=【RDSのエンドポイントを指定】
    - DB_PORT=5432
    - DB_DATABASE=【RDS作成時に作成したものを指定】
    - DB_USERNAME=【RDS作成時に作成したものを指定】
    - DB_PASSWORD=【RDS作成時に作成したものを指定】
6. migrationの実行
    ```
    cd /var/www/your_app_name
    php artisan migrate
    ```

## 私が詰まったこと

- SSH接続すると開いたVScodeウィンドウでエラーが発生する
    - エラーメッセージにconfigの中の内容がうまく解決できないみたいなことが書いてありました。
    - configの「IdentityFile」を「IdentifyFile」と書き間違えていたためです。
- SSH接続してターミナルから以下のコマンドを流すとエラーが発生する。
    - sudo amazon-linux-extras install -y php8.0
    - amazon-linux-extrasがないみたいなエラーです。
    - 結局、EC2インスタンス作成時にAMIをデフォルトで設定していて、Amazon Linux２にできていないため発生しているものでした。
- Laravelをインストールしてターミナルを利用した設定が終わったはずなのにLaravelが表示できない
    - ブラウザにパブリックIPアドレスを突っ込んで確認しようとしましたが映りませんでした
    - vimで操作したnginx.confが誤っている気がするため、以下のコマンドで構文を確認しました
        
        ```
        sudo nginx -t
        ```
        
    - タイポがありました。
    - 以下のコマンドを実行して反映させて移りました
        
        ```
        sudo systemctl restart nginx
        ```
        
- RDSとLaravelの接続がタイムアウトする。
    - 結果的に原因は複数個ありました。
    1. RDS用のセキュリティグループのインバウンドルールの設定時Postgresを指定しなかった
    2. RDS作成時にPostgres14.7を指定したが12.7を指定するべきだった。（認証情報関連の参照が古いため）
    3. RDS作成時、「接続」の設定のセキュリティグループの指定にRDS用のものだけでなく、EC2用のセキュリティグループも指定してしまっていた。


## Tips ChatGPTを利用した学習の効率化

上述の詰まった点を解決するときにChatGPTを活用しました。

AWSに関してはSAA認定試験を取得したので基本的なサービスの名称や概要はなんとなく理解していますが、普段実務で使用しないため、エラーが発生したときにどこが原因が検討が付きません。

以前は検索してヒットした記事から情報を集めていましたが、以下に共有する方法でChatGPTを活用すると効率的に進めることができました。

### エラーをChatGPTに共有して原因として主に考えられるものを列挙させる

エラー文のコピペと「原因として考えられるものを何点か列挙してください」的な文章を記載すると原因を箇条書きと簡単な説明付きで表示してくれます。

これによって、初学者特有のエラーの原因に検討がつかないという状況を補うことができます。

学び始めて浅い技術だとわからない単語が多数出てきますが、そんなときは以下の手法を活用します。

### わからない単語や概念が出てきたら「○○とはなんですか？」と質問して深堀する

知らない概念について知識を身に着けるチャンスです。わかりにくかったら「もっと簡潔に説明してください」「前提知識があればそれも教えてください」こんな感じで聞いてみると勉強になります。

もちろん、ChatGPTの回答が間違っている可能性もあるので後で自分で調べてみるのも大切です。

### ChatGPTが提示したものが原因だと仮定して解決策を試す

エラーを共有すればだいたい３～４件程度原因として考えられるものを挙げてくれるので、その中から１つ選んでそれを原因だと仮定して調べてみましょう。

解決策は検索して調べてもいいですし、ChatGPTに「○○が原因だと仮定して解決するための手順を示してください」とか聞いてみるのもいいと思います。

### ChatGPTに環境や使用しているツール、バージョンなどの背景情報をなるべく詳しく共有する

これでより正解にちかい回答が返ってくる可能性が高くなります。特にバージョンによって解決策が異なる場合が多いので教えておいたほうがいいです。

### ChatGPTの回答が的外れだったらNew Chatで別のアプローチで質問してみる

共有する情報を吟味したり、自分の仮説を共有したり、アプローチのパターンは無限にあります。

同じチャットで質問を続けずにあえて新しいチャットを開いたほうが早く解決する場合があります。

## 最後に

知識が浅い状態からでもUdemyとChatGPTを有効活用することで目的の知見を効率的に身に着けることができたと思います。

Tipsで共有したChatGPTの活用法は他のUdemy講座やプログラミング言語・フレームワークの学習など様々なことに流用できるものです。使ってみてください。

つたない文章で恐縮ですがここまで読んでいただきありがとうございました。
よろしければいいね等よろしくお願いいたします。

### 追記
Udemyや書籍を利用したフロントエンドのキャッチアップに使用した教材をまとめました。
よろしければこちらも見ていただけると嬉しいです。
https://qiita.com/ryosuke-horie/items/d05beb5ba33ba787e781