GitHub Actions は、プロジェクトのビルドやテスト、デプロイをGitHubのリポジトリから直接行える自動化ツールです。本記事では、GitHub ActionsのWorkflowでデプロイ手順を定義し、AWSのEC2インスタンスへのデプロイを自動化する方法を紹介します。今回は rsync ではなく git pull でのデプロイです。

前提条件

  • Webアプリケーションを含むGitHubリポジトリ
  • AWS EC2インスタンスとSSH情報
    • 作業中の端末からEC2へのSSH
    • EC2からGitHubへのSSH(GitHubにSSH公開鍵を登録済)

※本稿ではEC2へのSSH接続、GitHubへのSSH接続はサポートしていません。

ToDoリスト

  1. デプロイ用のIAMユーザーを作成する
  2. GitHubにシークレットと変数を登録する
  3. GitHub ActionsのWorkflowを定義する
  4. テスト

作業の全体像

デプロイ用のIAMユーザーを作成し、mainブランチへの変更のタイミングでEC2にSSHでログインし、git pullします。GitHub Actionsの実行環境は固定IPではないため、IPアドレスを取得してCLIを通じてセキュリティグループの設定を変更することでセキュリティの問題を回避します。

所要時間

所要時間は10~20分くらいだと思います。
10分でSSHログインやデプロイ作業が自動化されるなら頑張りましょうw

1. デプロイ用のIAMユーザーを作成

まずはAWSコンソールからデプロイに使用するユーザーを作成します。AWSマネジメントコンソールへのユーザーアクセスを提供するは必須ではありません。なくても大丈夫です。EC2AutoDeployUserなど適当な名前をつけましょう。

許可は AmazonEC2FullAccess をつけておいてください。

作成したIAMユーザーのアクセスキーとシークレットアクセスキーはのちほど使用します。

次にアクセスキーを作成します。

コマンドラインインターフェイス(CLI)を選択してアクセスキーを作成しましょう。ここで作成したアクセスキーはのちほど使用します。

2. GitHubにシークレットを登録

  1. リポジトリに移動する
  2. Settings を選択
  3. Secrets and variables を選択
  4. アコーディオンメニューの中から Actions を選択
  5. New repository secretボタンを選択
  6. 遷移先でふたたびNew repository secretボタンを選択

シークレットの登録に必要なのは NameSecret だけです

次の通りシークレットを登録してください。

NameSecret
AWS_ACCESS_KEY作成したIAMユーザーのアクセスキー
AWS_SECRET_ACCESS_KEY作成したIAMユーザーのシークレットアクセスキー
EC2_HOSTデプロイ先のEC2のIPアドレス
EC2_SECURITY_GROUP_IDデプロイ先のEC2にアタッチされているセキュリティグループのID(sg-xxxxxxxx)
EC2_USER作成したIAMユーザー名(EC2AutoDeployUser)
SSH_PRIVATE_KEYデプロイ先のEC2へのSSH秘密鍵

次のように登録されていればOKです。

3. GitHub ActionsのWorkflowを定義

  1. リポジトリに移動する
  2. Actions を選択
  3. set up a workflow yourself を選択
  4. エディタを使用してジョブを定義します。(エディタ参照)
  5. Commit Changes を選択してCommitしてください。

main.yml

# 名前は適宜変えてください
name: EC2 auto deploy

# mainブランチにpushされたら走る
on:
 push:
   branches: [ main ]

# mainブランチへのプルリクエストがclosedしたら走る設定は以下
# on:
#  pull_request:
#    branches: [ main ]
#    types: [closed]

 workflow_dispatch:

jobs:
  build:
    #GitHub Actionsの実行環境
    runs-on: ubuntu-latest
    steps:

      # セキュリティグループにIPアドレスを登録するためにIPアドレス取得ライブラリを使用
      # GitHub Actionsの実行環境のIPアドレスは固定ではないため
      - name: Public IP Install
        id: ip
        uses: haythem/public-ip@v1.3

      # actions/checkout@v2は、GitHubリポジトリの最新のコードをチェックアウトして取得するための標準アクション
      - 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にキーを設定
      # ${{ secrets.XXX_XXX_XXX }}はGitHubに登録したSecretのName
      - 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: |

          # セキュリティグループを開放
          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.SSH_PRIVATE_KEY }}" > private_key
          chmod 600 private_key
          ssh -oStrictHostKeyChecking=no ${{ secrets.EC2_USER }}@${{ secrets.EC2_HOST }} -i private_key "cd /var/www/html/www.next.inc && 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

4. テスト

GitHub.com上でのテスト

  • リポジトリに移動する
  • Actions を選択
  • EC2 auto deploy を選択
  • Run workflowを選択
  • Run workflowボタンを選択
  • デプロイ成功

ローカル環境でのテスト

コードを変更してmainブランチにpushしてください。成功すれば次のように表示されます。

最後に

GitHub ActionsのWorkflowを使ってデプロイ作業を自動化してみました。SSHでログインしてデプロイされている方はぜひ使ってみてください。今回はgit pullのみの作業でしたが、npmなどを使ったビルドなども可能なので、別プロジェクトでも自動化してみたいと思います。

参考記事

GitHub Actionsを使ってEC2に自動デプロイ #AWS – Qiita