(CodeDeploy+CodePipeline) git pushするだけでAWS EC2に自動デプロイする



###参考サイト
[【AWS】git pushでEC2にも自動デプロイ(CodeDeploy / CodePipeline)](https://qiita.com/nasuB7373/items/081f5974e31419a1a844)

###手順
**①IAMロールの作成**
**②EC2を作成し、CodeDeployエージェントをインストール**
**③ローカル環境とGithub上での設定**
**④CodeDeployの設定**
**⑤CodePipelineの設定**



###①IAMロールの作成
**流れ**
IAMからロールの作成をする
↓
下記のポイントに気をつけながら進める
↓
EC2にアタッチする

**ポイント**
・AWSCodeDeployRoleとAmazonS3FullAccessのポリシーを選択
・信頼関係のタブの信頼関係の編集の「"Service": 」を配列化して"codedeploy.amazonaws.com"を追加



###②EC2を作成し、CodeDeployエージェントをインストール
**流れ**
EC2インスタンス内にSSHで入る
↓
下記のポイントに気をつけながらCodeDeployエージェントをインストールする
↓
タグの追加をしてメモしておく
↓
セキュリティグループにHTTPアクセスできる(ポート80)があるか確認。なければ追加する
↓
CodeDeployエージェントがインストールできているか確認

**ポイント**
・「ap-northeast-1」の部分はリージョンによって変わるので要注意
![スクリーンショット 2021-11-11 23.01.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687490/03829e85-2e24-44b1-077b-2675c70531d3.png)


```
#!/bin/bash
# CodeDeployAgentのインストール
yum install -y ruby
cd /home/ec2-user
curl -O https://aws-codedeploy-ap-northeast-1.s3.amazonaws.com/latest/install
chmod +x ./install
./install auto
```

**タグの追加でのポイント**
・CodeDeployのところで使うのでメモしておくといい

CodeDeployエージェントがインストールできているか確認コマンド

```
sudo yum info codedeploy-agent
```



###③ローカル環境とGithub上での設定
**流れ**
appspec.yml(設定ファイル)をダウンロード
[AWS公式サンプルスクリプト](https://github.com/aws-samples/aws-codedeploy-samples/tree/master/applications/SampleApp_Linux)
↓
scriptsフォルダの中を変更
↓
appspec.ymlファイルの中を変更
↓
GitHubへpush


**「scriptsフォルダの中を変更」でのポイント**
Apacheを使っている場合
変更なし
nginxを使ってる場合
sriptsの中の２つファイルの中のhttpdをnginxに変更
・start_server
・stop_server

**.ymlの拡張子について**
・構造データ
・プログラムみたいにコードを持たないやつ

**「appspec.ymlファイルの中を変更」でのポイント**

```
files:
  - source: /
```
EC2内でのアプリへのパスを記入(私の場合は下記のようなパスでした)

```
destination: /var/www/アプリのフォルダ名/
```

###④CodeDeployの設定
**流れ**

**「デプロイの作成」のポイント**
・リポジトリ名をGitHubからコピーする際、アカウント名/リポジトリ名の「/」の前後に半角のスペースが入ってるのでこれを消す
・コミットIDはローカルのターミナルでgit logで最新のコミットIDが見れる


**ここで出たエラー解決の流れ**
このエラーがCodeDeployのブラウザ画面に表示された

```
The overall deployment failed because too many individual instances failed deployment, too few healthy instances are available for deployment, or some instances in your deployment group are experiencing problems.
```
エラーの日本語訳

```
展開に失敗した個々のインスタンスが多すぎる、展開に使用できる正常なインスタンスが少なすぎる、または展開グループ内の一部のインスタンスで問題が発生しているため、全体的な展開が失敗しました。
```

code deploy agantのエラーログを見る

```
tail -50 /var/log/aws/codedeploy-agent/codedeploy-agent.log
```

最新のコミットIDじゃないことが判明
ローカルのターミナルで調べる

```
git log
```
最新のコミットのコミットIDをコピペする

コミットIDを最新のものしたらエラーログの内容が変わった
ファイルがすでにありますというエラーが出た

```
the deployment failded because a specified file already exists  at this location 
```

.DS_Storeがgithubにないのにサーバー上にあるから混乱してるかも?
と仮説を立てた
codedeploy実行ユーザーを確認

```
ps aux | grep codedeploy
```

試しに.DS_Storeを消してみる

```
sudo rm .DS_Store
```
codedeployでデプロイの再試行をクリック
codedeployのブラウザに同じエラーが出た

```
The overall deployment failed because too many individual instances failed deployment, too few healthy instances are available for deployment, or some instances in your deployment group are experiencing problems.
```
エラーログをもう一度見る

```
tail -50 /var/log/aws/codedeploy-agent/codedeploy-agent.log
```
エラー内容

```
the deployment failed because a specified file already exists  at this location
```

コードデプロイがファイルを上書きするオプション指定がない場合にファイルがあると出るエラー
ファイル上書きがうまく行ってなかったのが原因だったようだ
[EC2/オンプレミスのデプロイに関する問題のトラブルシューティング](https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/troubleshooting-deployments.html)

なので一度アプリのフォルダの中身を全部消してみる
.envとかは再設定をしないといけないから、消す前にアプリごと１階層上辺りにバックアップをとった方がいい
アプリの中のすべてのディレクトリとファイルを削除する

```
sudo rm -rf ./*
```

codedeployでデプロイの再試行をクリック
codedeployのブラウザでまたエラーが出た
エラーログを見に行く

```
tail -50 /var/log/aws/codedeploy-agent/codedeploy-agent.log
```

editorconfigがすでにあるよというエラーが出ていた
ls -alで見ると.で始まるファイルが消せていなかった
このタイミングで.envを一階層上に上げることにした

```
sudo mv .env ../
```

.で始まるファイルをまとめて消す

```
sudo rm ./.*
```
.gitが消せなかったので消す

```
sudo rm -rf .git
```

.ファイルと..ファイルだけは残しておく
codedeployでデプロイの再試行をクリック
成功した！！！
![スクリーンショット 2021-11-12 17.07.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687490/e90f5051-f58e-694f-7a88-8dc65d721a2a.png)


.envは後で戻すのでこのまま⑤に進む


###⑤CodePipelineの設定
**CodePipelineを設定していないと・・・**
④までだと下記３つの手順を毎回しないといけないのでデプロイが面倒
・Githubにプッシュ
・コミットIDを書き換え
・デプロイの作成

**CodePipelineを設定すると・・・**
・プッシュと同時に自動デプロイ

非常に手間が減る！

**流れ**
パイプラインを作成
↓
Githubにpushして動作確認

**ポイント**
・出力アーティファクト形式はデフォルトを選択する

**作成の手順**
・AWSのcodepiplineを開く
・パイプラインのパイプラインの作成をクリック
・ソースプロバイダーはGitHub(バージョン2)を選択
・GitHubに接続するボタンをクリック
・接続名を命名する
・新しいアプリをインストールするボタンをクリック
・出力アーティファクト形式
・gitでクローンしてコミットログとか見れるではなくて
・EC2上はファイルだけでログとかを含まないでやるかどうか？
・完全クローンだとコミットログが残るのでファイルが競合してしまう可能性があるっぽい。なのでデフォルトを選んでEC2はただのコピーですよという状態にする
・ビルドはスキップ

これで繋がったはず・・・

**正常な動きをするか見る**
・ローカルにtest.txtを作成してみてgit push
・EC2内のアプリのフォルダ内でlsコマンドを叩いてtest.txtがあれば成功

**.envをコピペする**
1階層上に移動してあった.envをコピー＆アプリのディレクトリに移動する

```
sudo cp -r ../.env ./.en
```

コピーされたかを確認

```
ls -al
```
**ここで出たエラーの解決の流れ**
ブラウザで表示されない状態になっているhttp error 500になっている

nginxが起動してるかを確認

```
ps aux | grep nginx
```

設定にもよるが、masater process と worker process があれば OK 。
![スクリーンショット 2021-11-12 17.30.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687490/76fafd0e-b830-7258-1bd1-2790ad5a1eec.png)

php-fpmの再起動がだいぶ前なので再起動させてみる

```
sudo systemctl restart php-fpm
```

まだ500エラー
nginxかphp-fpmのエラーを見てみる
nginxのエラーログの場所を忘れたのでnginxの設定のところを見て確認する

```
sudo vi /etc/nginx/nginx.conf
```

error_logのパスをコピペ

```
/var/log/nginx/error.log
```
エラーログを見る

```
sudo tail -100 /var/log/nginx/error.log
```
エラーが見つかる

```
require(public.../vendor/autoload.php) failed to open stream
```

vendorフォルダがなにか影響してるようだということがわかる

EC2内にvendorフォルダがあるかを確認

```
ls -al
```

vendorフォルダがないことがわかった
GitHubで.envファイルとvendorフォルダはgitignoreに入っていてgit cloneをしてもクローンされない対象になっている模様

vendorを作成するためにcomposerをインストールする

```
sudo composer install
```

vendorフォルダが作成されたか確認

```
ls -al
```

ブラウザで見れるか試す
エラー500は解消されてlaravelのエラーが出た

```
storage/logs/laravel.log cloud not be opened in append mode: failed  to open stream : Permission denied
```

logsフォルダの権限を変える。書き込み権限を与える

```
sudo chmod 777 storage/logs
```

ブラウザを更新する
違うエラーが出た

```
storage/freamework/sessions/xxxxxxxxxxx cloud not be opened in append mode: failed  to open stream : Permission denied
```

セッションとかログは書き込み権限が必要

```
sudo chmod 777 storage/freamework/sessions
sudo chmod 666 storage/freamework/sessions/*
```

ファイルに対しては666、フォルダに対しては777

ブラウザを更新
違うエラーがでた

```
storage/freamework/views/xxxxxxxxxxx cloud not be opened in append mode: failed  to open stream : Permission denied
```
viewsフォルダの権限も変更

```
sudo chmod 777 storage/freamework/views
````

ブラウザを更新
成功！！！

**これでgit pushしたら自動デプロイされてデプロイされてるアプリをリロードしたら変更が反映されるようになりました！！**