既存LaravelプロジェクトをAWS EC2で動かす

個人的勉強としてAWSを触ってみたかったので、既存のLaravelプロジェクトをEC2で動かす試みをやりました。
S3は画像保存で何度か触ったことがあったのですが、サーバー構築は初めてです。

## 前提条件
・既存のプロジェクトはgithubにpush済み

## 構築内容
VPCの中にパブリックサブネットを作成、その中にEC2インスタンスを作成し、Laravelプロジェクトを動かす。
(Laravelプロジェクトはgit cloneで引っ張ってくる)
データベースに関しては、プライベートサブネットを作成し、EC2からアクセスできるようにする。(MySQLを使用)

## 想定インフラ構想図
![スクリーンショット 2021-03-25 23.29.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255267/1ba099a2-7814-4dce-151a-7b0030367271.png)

## 用語の説明
出てくる単語一個一個不明のため、簡単ですが調べました。

### VPC
Virtual Private Cloudの略。
AWSの仮想ネットワークで、他の仮想ネットワークから論理的に切り離されて(セキュリティ性が高い)います。

**現在EC2インスタンスを立ち上げるために必須のもの**

1アカウント最大で5つまでのVPCが作れるが、以外に少なくて上限に引っかかったりして困る可能性もある。

### サブネット
VPCのIPアドレスの範囲。

サブネットにはパブリックとプライベートがある。

プライベートには、RDS等のデータベースを配置することが多い。

### ルートテーブル

ネットワークトラフィックの経路を判断する際に使用される、ルートと呼ばれる一連のルール。

ルートによって特定のVPCの中のサブネットにアクセスする。


### インターネットゲートウェイ

VPC 内のリソースとインターネット間の通信を可能にするために VPC にアタッチするゲートウェイ。

つまり、AWSからVPCに接続するためのゲートのことで、アタッチするためにはVPCを指定してあげる必要あり。

### CIDR ブロック
クラスレスドメイン間ルーティング。

インターネットプロトコルアドレスの割り当てとルート集計方法。

### セキュリティーグループ

EC2インスタンスに適用可能なAWS標準のファイアウォール機能。

セキュリティグループは、EC2インスタンスへのアクセスを許可し、トラフィックを制御するファイアウォールとして動作する。

また、1つのセキュリティグループを複数のEC2インスタンスに割り当てることもでき、各セキュリティグループでは、EC2インスタンスへのアクセスを許可するトラフィック規定のルールを設定し、ここで設定・許可しないアクセストラフィックは全て拒否される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255267/80122a9e-e6f2-5080-1db5-c47cfb066a68.png)



## 実際の構築の流れ
実際にLaravelの画面が表示されるまでにやったことを記載します。

具体的な作業や操作については、多くの方の文献の方が詳細に記載されているため、今回は省略します。

あくまで、私自身が次回構築時に迷わない用の備忘録位置付けです。

1. CloudWatchで料金アラート設定
1. VPCの作成
1. サブネットの作成(publicとprivateを作成)
1. インターネットゲートウェイの作成
1. インターネットゲートウェイをVPCにアタッチ
1. ルートテーブルの作成
1. ルートテーブルにpublicサブネットを関連付け
1. EC2を準備(セキュリティーグループ設定、キーペア作成)
1. Apacheインストール
1. ファイアーウォールの設定(セキュリティグループのポート番号を設定し、HTTP許可)
1. Elastic IPアドレスの設定(IPアドレス変化防止)
1. Route 53でドメイン設定
1. privateサブネットの冗長化
1. セキュリティーグループの構築(作成済みEC2インスタンスにセキュリティグループをあてがう)
1. サブネットグループの作成(冗長化の関係で)
1. パラメータグループ、オプショングループの作成
1. データベース作成
1. WEBサーバーの冗長化(ロードバランサー)
1. publicサブネットを作成(冗長化の関係で)
1. EC2はAMIで作成
1. ロードバランサーの設定
1. ロードバランサーとRoute53を紐付け、ドメインでロードバランサーにアクセスさせる
1. アプリケーションのクローン


## 手こづったところ
Apacheのインストールからの表示は問題なかったのだが、ファイル許可が必要。

つまり、Apache httpd は、Apache ドキュメントルートと呼ばれるディレクトリに維持されるファイルを提供している。
しかし、そのディレクトリにアクセスできるのはroot権限ではないとできない。
(ちなみにドキュメントルートは/var/www/html)

sshでログインした場合、ec2-userユーザーとしてログインしているため、もちろんアクセスはできない。

そのため、このディレクトリで複数のファイルを操作することを許可するには、ディレクトリの所有権とアクセス許可を変更する必要がある。

そのためにやることは下記内容

1. ec2-user を apache グループに追加
1. apache ディレクトリの所有権を /var/www グループに付与
1. グループへの書き込み権限を割り当てる

```
$ sudo usermod -a -G apache ec2-user
$ exit
$ ssh -i {keypair.pemを指定} ec2-user@XX.XXX.XX.XXX
$ groups
ec2-user adm wheel apache systemd-journal
$ sudo chmod 2775 /var/www
$ find /var/www -type d -exec sudo chmod 2775 {} \;
$ find /var/www -type f -exec sudo chmod 0664 {} \;
```

### ファイル変更前にgit cloneしておくこと

Apacheファイルは、laravelプロジェクトのpublicディレクトリを参照しているため、まずはcloneしておく。

### Apacheファイルの変更も必要
```
sudo vi /etc/httpd/conf/httpd.conf
```
ファイルを下記内容に修正

```
DocumentRoot “/var/www/自分のlaravel_project/public
<Directory /var/www/自分のlaravel_project/public>
AllowOverride All
</Directory>
```

Apatchをリスタートさせて、確認する。
ここでエラーなく起動することを確認する。
httpd.conf等のファイル編集が間違っているとここでエラーを吐く。

```
sudo service httpd restart
```


### Laravelプロジェクトにもパーミッション変更が必要

```
$ sudo chmod -R 777 /var/www/{プロジェクトのフォルダ名}/storage
$ sudo chmod -R 775 /var/www/{プロジェクトのフォルダ名}/bootstrap/cache
```

### .envの編集が必要
```
cp .env.example .env vi .env
APP_URL=http://IPアドレス ←サーバーのIPにする
DB_CONNECTION=mysql
DB_HOST=←RDSのエンドポイント
DB_DATABASE=データベース名
DB_USERNAME=RDS作成時のユーザ名
DB_PASSWORD=設定したパスワード
```

キーを生成し、キャッシュをクリアします。

```
php artisan key:generate
php artisan config:clear
```
テーブルを作成。

```
php artisan migrate
```

シンボリックリンクを作成

```
php artisan storage::link
```

最終的に作られたインフラがこちら

![スクリーンショット 2021-03-25 23.29.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255267/1ba099a2-7814-4dce-151a-7b0030367271.png)

あえて二つ目のパブリックサブネットにLaravelプロジェクトを入れていないのは、ロードバランサーが正常に動いているかの確認です。

privateサブネットが二つあるのはバックアップ体制のためです。(冗長化)

必要に応じてアベイラビリティーの設定を変更する事で、WEBサーバー x 2　DBサーバー x 2はできます。


## 今後の目標

・Githubにpushしたら自動デプロイ機能が動き、AWSへデプロイできるような構成にしたい。そのためにはECSの勉強が必要だと感じる。

・フロント側もAWSに持っていきたい。