【AWS】初心者が EC2 + RDS で簡単なサーバー構築とアプリケーションを動かすまでの手順

#概要
AWSを使って、簡単なサーバー環境を構築しました。　
目的は、AWSの学習・理解のためです。

行ったこととしては、
０、基礎知識を得る
１、サーバーを構築（EC2とRDS）
２、EC2上でNginx+PHPをインストール
３、EC2からRDS内のMySQLにPDO接続
４、AMIを使ってインスタンスをコピー
５、ALBを作成




#基礎知識
AWS素人がインフラ設計/構築を理解するために、まず最初におさえるべきキーワード15選
https://qiita.com/Futo23/items/318d89eccdbf5697f8bf
AWS入門者向け 初心者が最初に理解すべきEC2とVPCの基本的な用語解説
https://avinton.com/academy/aws/


#サーバーを構築（EC2とRDS）
こちらの記事を参考に簡単なサーバー構築をします。
https://tech.recruit-mp.co.jp/infrastructure/retry-aws-minimum-vpc-server-environment/

流れとしては、

- VPCの作成
- Subnetの作成
 - EC2用
 - RDS用
- Internet Gatewayの作成・VPCと紐付け
- Route Tableの作成・public subnetと紐付け
- Security Groupの作成・インバウンドのルールの編集
 - アプリケーションサーバー
 internet接続（80番）
 SSH接続（22番）
 - DB アプリケーションサーバーからの接続（3306番）
- アプリケーションサーバーにターミナルでSSH接続
アプリケーションサーバーからMySQLに接続

まで行いました。


詰まったところは、
Public DNSが割り当てられなかったところでした。
→[AWSでPublic DNS(パブリックDNS)が割り当てられない時の解決法]
(https://qiita.com/sunadoridotnet/items/4ea689ce9f206e78a523)



#EC2上でNginxとphp-fpmをインストール
こちらの記事を参考にnginxとphpーfpmをインストール。テストファイルで接続確認まで行います。
[AWSのEC2で行うAmazon Linux（nginx・php7.1-fpm）環境構築]
(https://qiita.com/2no553/items/e1b85b48412bc4559240)


#EC2からRDS内のMySQLにPDO接続
簡単なアプリケーションでPDO接続を行います。
そのため、
１、ローカルでアプリケーション作成
２、ローカルのファイルをAWSのnginx内に送る
３、MySQL内にデータベース作成
４、接続して確認
の順序で行います。

##ローカルでアプリケーション作成
PDOでMySQLからデータを持ってくることが目的のため、簡単なアプリを作ります。

```php:index.php
<?php
function connectDB() {
  $dsn = 'mysql:dbname=practice; host=[RDSのエンドポイント]; charset=utf8';
  $user = '[MySQLのユーザーネーム]';
  $password = '[MySQLのパスワード]';
  $dbh = new PDO($dsn, $user, $password);
  $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  return $dbh;
}


try{
  $dbh = connectDB();
  $sql = 'select id, name from users where 1';
  $stmt = $dbh->prepare($sql);
  $stmt->execute();
  $dbh = null;
  echo 'User list<br>';
  while(true) {
    $rec = $stmt->fetch(PDO::FETCH_ASSOC);
    if ($rec == false) {
      break;
    }
    echo $rec['id'];
    echo $rec['name'];
    echo "<br>";
  }

} catch(Exception $e) {
  echo 'I am sorry but something might be wrong on this server..';
  exit();
}
```

このように、
ユーザーのidと名前を一覧表示させるアプリにします。

##ローカルのファイルをAWSのnginx内に送る

ターミナルで、

```
scp -i ~/.ssh/[鍵名] -r 送りたいファイルの絶対パス ec2-user@パブリックDNS:/usr/share/nginx/html/
```

を実行します。
これで、
ローカルのファイルをAWSの```/usr/share/nginx/html/```に送ります。

##MySQL内にデータベース作成
まだMySQL内にデータベースを作成していないため、これから作成します。

サーバーを構築する際に行った手順と同様に、
アプリケーションサーバーにターミナルでSSH接続します。

```
ssh -i ~/.ssh/[鍵名] ec2-user@パブリックIP
```

その後、アプリケーションサーバーからMySQLに接続します。

```
 mysql -h [RDSのエンドポイント] -P 3306 -u [ユーザー名] -p
```

その後、
MySQL内で、
```practie```のデータベースを作成し、usersというテーブルを作ります。```id```と```name```のカラムを作り、
適当にいくつかのレコードを挿入します。

##データが表示されるか確認

実際に```パブリックIP```にアクセスして、データが表示されるか確認してみます。



###404エラー
ここで、```４０４エラー```が発生しました。


以前に接続確認まで行っていたので、
なんで```404エラー```？
と思いました。

nginxのconfigの設定をみると、全てのエラーが404に返っていたようです。

また、エラー原因は、```php71-pdo```がインストールされていないことでした。

よって、

```
sudo yum install -y php71-pdo
```
をインストール。
その後、アクセスして、確認します。

###could not found driverエラー
```could not found driver```というエラーが出ました。これは、
[PHP7+Nginx+MariaDBでPDO接続したとき"could not find driver"が出た際にやったこと](https://qiita.com/toriiico/items/e2d951bc7e598d7609fb)
を参考に解決しました。


###アクセスしてデータを表示
このようにデータが表示され、無事に確認ができました。
<img width="637" alt="スクリーンショット 2019-11-21 14.12.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408619/30ce1718-6bf4-aa20-fc00-7fa206939aeb.png">


#AMIを使ってインスタンスをコピー
ALBを使って負荷分散をさせるために、EC２インスタンスを複製させます。

[[AWS] EC2 インスタンスのコピーを作成]
(https://agohack.com/aws-duplicate-ec2-instance/)
を参考に、 コピーのインスタンスを作成します。

その後、
```Elastic IP``` を新しいインスタンスに割り当てます。



#ALBを作成
[ALB（Application Load Balancer）を導入する]
(https://qiita.com/kobayashi-m42/items/9f6dd14ad1e4dc7cab4c)
を参考にALBを作成します。

セキュリティグループには以前に作った既存のものを選択します。
ターゲットには、作成した```EC2インスタンス```を二つ登録します。



###片方のnginxを停止
EC2サーバーの片方の```nginx```をストップさせます。
EC２内のターミナルで、

```
sudo service nginx stop
```

###ブラウザ確認
その後、ロードバランサーの```DNS```にアクセスして、起動しているか確認します。

片方のサーバーが動いた状態で、無事にアクセスできれば成功です。