今更だけどEC2にGithub Actionを使って初めてのCI/CDを構築する

# 更新履歴

- 10/8 EC2用に変更

# はじめに

- 今や必須のCI / CD、絶対これから環境の構築に必要になるの
- けどやり方知らん（絶望）
- キャッチアップするか〜〜〜〜
- エンジニア歴半年の備忘録

# やりたいこと

- EC2 + Ubuntu 22.04 LTS への自動デプロイとテスト

# やっていく

### Github Actionについて

- Github内で完結するCI / CD
- `.github/workflows`に保存することで実行可能、カスタマイズも可能
- テンプレが多数あり、簡単に実装ができる
- YAMLで記述、書き方に少しクセがあるので参考から詳細は確認

### デプロイ先の準備

- node.jsとgitは必要（当たり前）

もしない場合は以下でインストールします

```
// とりあえずアップデート
$ sudo apt update

// node.jsのセットアップ
$ sudo apt install nodejs

// 確認
$ node -v

// gitのセットアップ
$ sudo yum -y install gcc curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-ExtUtils-MakeMaker autoconf```
$ npm install git

// 確認
$ git -v
```

ちなみに2023.10.3現在だとUbuntu 22.04ではnode 12がインストールされます

### ~~接続用の公開鍵と秘密鍵を用意する~~（EC2の場合必要ない）

```
// .sshに移動する
$ cd ~/.ssh

// キーを作る
ssh-keygen -t rsa -b 4096 -C [任意の名前]
```

Enter 何たらかんたら〜 って出ますが基本確認なのでEnter押せば進みます

![スクリーンショット 2023-10-06 15.39.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3504047/10d853f5-3dc1-bfc7-4599-a231c3335506.png)

これで公開鍵（id_rsa.pub）と秘密鍵（id_rsa）ができました。

### ~~.sshのconfigを編集する~~（EC2の場合必要ない）

configがない場合は作ります

```
Host github
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_rsa
```

### Github側に公開鍵を登録

https://github.com/settings/keys

![スクリーンショット 2023-10-06 15.49.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3504047/a6f07e00-70e0-d993-f76a-445a57620c7d.png)


SSH keysのNew SSH keyより先ほどの公開鍵を登録します

### ~~公開鍵の有効化~~（EC2の場合必要ない）

ここはコマンドを叩くだけ

```
$ eval `ssh-agent`
$ ssh-add ~/.ssh/id_rsa
```

### レポジトリの設定

![スクリーンショット 2023-10-06 16.08.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3504047/850444ac-8a21-7a71-a429-75232e7b1cab.png)


レポジトリのSetting → Secrets → Actionsより以下ようにの情報を登録します

![スクリーンショット 2023-10-06 16.46.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3504047/7bcca0b3-da4e-6535-4b97-1e7a9ff8b013.png)


続けて以下の項目を追加していきます

- EC2_USER_NAME（EC2のユーザー情報）

例：Ubuntu, ec2-userなどのデプロイサーバログインのユーザネーム

- EC2_HOST_NAME（EC2のホスト情報）

例：ec2-54-178-72-250.ap-northeast-1.compute.amazonaws.comなどのサーバのホスト情報、またはIP

- GIT_PRIVATE_KEY（EC2にアクセスする用のアクセスキー）

例：EC2のインスタンスを立ち上げた時にもらった鍵


### Jobを作成する

```yaml
name: EC2 auto deploy

on:
 pull_request:
   branches: [ main ]
   types: [closed]

 workflow_dispatch:

jobs:
 build:
   runs-on: ubuntu-latest

   steps:
     # BranchをCheckout
     - name: Checkout
       uses: actions/checkout@v2

     # デプロイする
     - name: Deploy
       uses: appleboy/ssh-action@master
       with:
          host: ${{ secrets.EC2_HOST_NAME }}
          username: ${{ secrets.EC2_USER_NAME }}
          key: ${{ secrets.GIT_PRIVATE_KEY }}
          script: |
            cd /home/ubuntu/develop/backend
            git pull origin main
```

やっていること

- PRのmergeが実行されてPRが閉じるとactionsが起動
- ブランチのチェックアウト
- pullを実行

今思ったけど、パスの部分を変数にしちゃえば使いまわせるね

あとscriptの部分にdockerのビルドコマンドも書けるのでdockerを使ってる人でも安心

# 参考

https://knowledge.sakura.ad.jp/23478/

https://qiita.com/nanbuwks/items/ed8adb2d4324c939a349

https://qiita.com/shuncask/items/db41ec7cc4d4f23b1a28

https://hakushi.biz/second_lab_list/lab_blog_detail?rd_url=5122f2a4-ac44-4b59-b377-070a1ea2631d

### アドバンス（備忘録用）

- AWS_SECURITY（AWS セキュリティグループ）
- AWS_ACCESS_KEY（AWS CLIのアクセスキー）
- AWS_SECRET_ACCESS_KEY（AWS CLIのシークレットアクセスキー）

これを追加することにより、これから作成するファイルから変数として参照することが可能となります。

また、セキュリティグループ要らなくね？って感じるかもしれませんが、Github  Actionでは実行するサーバのIPが変わるので必須なのです。

AWS CLIを使うのは、上記の実行時にIPを取得して一時的に解放するためです。

もしEC2の設定でSSHのポート（22）を解放しており、全IPを許可している場合はAWS CLI + セキュリティグループによる許可を使う必要ありません。

AWS CLI + セキュリティグループによる許可が必要な場合

```yaml
name: EC2 auto deploy

on:
 pull_request:
   branches: [ main ]
   types: [closed]

 workflow_dispatch:

jobs:
 build:
   runs-on: ubuntu-latest
   steps:

     # IP取得ライブラリをインストール
     - name: Public IP Install
       id: ip
       uses: haythem/public-ip@v1.2

     # BranchをCheckout
     - name: Checkout
       uses: actions/checkout@v2

     # AWS CLIをインストールする
     - name: AWS CLI install
       run: |

         curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
         unzip awscliv2.zip
         sudo ./aws/install --update
         aws --version

     # AWS CLIにキーを設定をする
     - name: AWS set Credentials
       uses: aws-actions/configure-aws-credentials@v1
       with:
         aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
         aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
         aws-region: ap-northeast-1

     # デプロイする
     - name: Deploy
       run: |

         # SSHのセキュリティグループを開放する
         aws ec2 authorize-security-group-ingress --group-id ${{ secrets.EC2_SECURITY_GROUP_ID }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32

         # SSH接続して、git pullする
         echo "${{ secrets.GIT_PRIVATE_KEY }}" > private_key
         chmod 600 private_key
         ssh -oStrictHostKeyChecking=no ${{ secrets.EC2_USER_NAME }}@${{ secrets.EC2_HOST_NAME }} -i private_key "cd /develop/magicbox && git fetch --prune && git checkout main && git pull origin main"

         # SSHのセキュリティグループを閉じる
         aws ec2 revoke-security-group-ingress --group-id ${{ secrets.EC2_SECURITY_GROUP_ID }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32
```