Laravel Envoy+CircleCIでEC2にデプロイ

## 概要
Laravel EnvoyとCircleCIを利用して、EC2にデプロイするということを試してみました。
https://laravel.com/docs/8.x/envoy
GithubのmasterブランチにマージされたらEC2上の本番サーバに、developブランチにマージされたらステージングサーバにデプロイされる想定です。

## 前提
### 設定
* AWS上に本番環境(production)とステージング環境(staging)がEIPが割り当てられたEC2として存在する
* EC2からgit pull可能
* Githubでmasterとdevelopのブランチが存在するリポジトリ
* Githubのリポジトリにpushした際CircleCIが実行されるよう連携済み

### バージョン
PHP: 7.4.7
Laravel Envoy: 2.3.1

## 手順
### Laravel Envoyの設定
```bash
$ composer require laravel/envoy
```

今回簡易的に以下のようにEnvoy.blade.phpを作成します。

```php:Envoy.blade.php
@servers(['production' => 'ec2-user@xx.xx.xx.xx', 'staging' => 'ec2-user@yy.yy.yy.yy'])

@setup
    $docRoot = '/var/www/html';
@endsetup

@story('deploy')
    git
@endstory

@task('git', ['on' =>  $server])
    cd {{ $docRoot }}
    git pull origin {{ $branch }}
@endtask

@finished
    echo "${server}へデプロイしました!";
@endfinished
```

### CircleCIからEC2にデプロイするための設定
#### CircleCIからEC2にSSHするための設定
CircleCIのプロジェクトの設定ページから`SSH Keys>Additional SSH Keys`へ進み、「Add SSH Key」で各サーバへSSH接続するための秘密鍵を登録します。`Hostname`にEIP、`Private Key`に秘密鍵を入力します。
登録すると`Fingerprint`が表示されているので、これを控えておきます。
![スクリーンショット 2020-09-24 0.06.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183878/1c64c9e3-7ef4-c032-a293-ad23368755ee.png)
EC2作成時に生成されるキーペアを用いる場合は不要ですが、新しく鍵を生成した場合は下記のようにして、公開鍵を`~/.ssh/authorized_keys`に追記しておく必要があります。

```bash
$ cat id_rsa.pub >> authorized_keys
```

#### 環境変数の登録
CircleCIのプロジェクトの設定ページから`Environment Variables`へ進み、「Add Variable」で必要な環境変数を登録します。今回は本番/ステージングサーバのEIP、先程作成されたFingerprint、ユーザー名、SSHのポート番号を登録しています。
![スクリーンショット 2020-09-24 0.09.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183878/0a2343d2-c476-35d3-a8f2-33846f6534b0.png)

#### configの設定
```yml:.circleci/config.yml
version: 2
jobs:
  build:
    docker:
      - image: circleci/php:7.4-apache
      - image: circleci/postgres:11-alpine
        environment:
          POSTGRES_DB: default_test
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
    steps:
      - checkout
      ##### 〜〜中略〜〜 #####
      # ----------------------------------------------------------------------------
      # Deploy

      - add_ssh_keys:  
          fingerprints:  
            - "${KEY_FINGERPRINT}" 
            - "${KEY_FINGERPRINT_DEV}"

      - run:  
          name: Start ssh-keyscan  
          command: ssh-keyscan -p ${SSH_PORT} ${HOST_NAME} >> ~/.ssh/known_hosts 

      - run:  
          name: Start ssh-keyscan(dev)
          command: ssh-keyscan -p ${SSH_PORT} ${HOST_NAME_DEV} >> ~/.ssh/known_hosts 

      - run:
          name: Deploy to EC2 server
          command: |
            if [ "${CIRCLE_BRANCH}" == "master" ]; then
              ./vendor/bin/envoy run deploy --server=production --branch=master
            elif [ "${CIRCLE_BRANCH}" == "develop" ]; then
              ./vendor/bin/envoy run deploy --server=staging --branch=develop
            fi
```

## 動作確認
### masterでもdevelopでもないブランチにpush
デプロイは実行されずに終了している。
![スクリーンショット 2020-09-24 0.42.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183878/87634023-4f06-df3d-85bb-e4f0c8b2c884.png)

### developにマージ
developブランチをpullしている。
![スクリーンショット 2020-09-24 0.47.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183878/ddf068d9-028c-33bc-a211-7ed74e0ba748.png)

### masterにマージ
masterブランチをpullしている。
![スクリーンショット 2020-09-24 0.50.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183878/cea9b64e-64f7-7179-d6dd-20f3cda654f4.png)

## 所感
関係ないブランチにも不要な処理が入ってしまうのはイマイチだった気がします。
もっと良いやり方ありましたら是非教えていただけたらと。

## 参照
* [AES EC2上でsshを使ってgit clone を成功させるまでの手順](https://qiita.com/konuma1022/items/986eb58d4b94bef0c0a5)
* [Laravel Envoy でデプロイ対象サーバを指定してデプロイする](https://qiita.com/kaihiro/items/0b98d014d309b764ea23)
* [CircleCI2.0の私的ベストプラクティス](https://www.karakaram.com/circleci-best-practice/)