🐈

Laravel + AWS Elastic Beanstalk環境をGithub Actionsでデプロイする

2021/02/27に公開

はじめに

前回の記事でAWS Elastic Beanstalk でLaravelを動かす方法を書きましたが、今回はそれに加えてGithub Actionsでのデプロイ方法を説明します。
前回の記事を参照されていない方はそちらからぞうぞ。

設定条件

  • サーバー:AWS Elastic Beanstalk(環境設定済み)
  • 公開するプログラム:Laravel(通常のdeploy方法で完了済み)

Github Actions

Github ActionsはCIのひとつでGithub公式のツールです。Githubへのpushやマージ、プルリクエストをトリガーにすることで、様々な操作を実行できます。
Github Actionsでは1つの操作手順セットを”ワークフロー”といいます。Github上にはあらかじめよく使うワークフローサンプルが多数用意されており、そちらを選択するだけで基本的な設定ができてしまう機能もあります。

ワークフローの設定はGithubの"Actions"タブを選んで行うか、ローカルリポジトリに指定のディレクトリを作成してその中に設定ファイルを置くことで指定できます。

とは言えGithubの方から行った場合でも結局リポジトリ内に指定ディレクトリとファイルが配置されるだけなので、アプローチは違うものの結果的には同じです。

ワークフローの設定

新規アクションの設定は、ここではGithubの画面上から行うかたちにします。Githubの"Actions"タブを選んで“set up a workflow yourself →”を選択します。

あらかじめ用意されているワークフローパッケージを選択して書き換えてもいいのですが、ちょうどいいのが無かったのでここでは1から作ります。

とはいえこの設定で始めても、下記のようにあらかじめ書き方のサンプル的なものが用意されていますので、それにそって書いていけばOKです。

大分類として、下記の設定箇所があります。

  • name: ワークフローの名前です。任意の名前が付けられます。
  • on: 何の操作をトリガーにしてワークフローを実行したいかを指定します。
  • jobs: こちらが実行する具体的なワークフローを記述する箇所になります。

この中にさらに細かな設定を色々書いていくのですが、それをすべて書くとキリが無いので今回は完成形を先に示してしまいます。

on:
  push:
    branches:
      - master

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout source code
        uses: actions/checkout@v2
      
      - name: Replace .env
        run: cp .env.prod .env && rm .env.prod

      - name: Generate deployment package
        run: zip -r ../deploy.zip . -x '*.git*'

      - name: Get timestamp
        uses: gerred/actions/current-time@master
        id: current-time

      - name: Run string replace
        uses: frabert/replace-string-action@master
        id: format-time
        with:
          pattern: '[:\.]+'
          string: "${{ steps.current-time.outputs.time }}"
          replace-with: "-"
          flags: "g"

      - name: Beanstalk Deploy for app
        uses: einaregilsson/beanstalk-deploy@v11
        with:
          aws_access_key: ${{secrets.AWS_ACCESS_KEY}}
          aws_secret_key: ${{secrets.AWS_SECRET_KEY}}
          application_name: online2020.styling-collection.com
          environment_name: Online2020stylingCollectioncom-env
          region: ap-northeast-1
          version_label: "my-app-${{ steps.format-time.outputs.replaced }}"
          deployment_package: ../deploy.zip

      - name: AWS Deployed!
        run: echo App deployed to ELB

個別解説

name: deploy

これはもうただの名前付けです。

on:
  push:
    branches:
      - master

masterブランチにpushした時点でその後に記述するjobsが起動します。ちなみにプルリクエストのことは書かなくても、pushを書いているだけでもプルリクエストをマージした時点でjobsは起動します。pull_request:という書き方はどういうときに使うんだろう。。また調べます。

jobs:
  build:
    runs-on: ubuntu-latest

ここからが具体的な操作フローです。Github Actionsではワークフローが起動するためにGithub側で仮想サーバーが立てられ、その中ですべての処理が実行されます。
ここではruns-onのところで「ubuntu最新版を起動しますよ」という指定をしています。

Github Actionsはデプロイ時に使うだけでなく、テストフローで動かしたりもするので(むしろそちらの需要の方が多い)、ここでsentOSなどubuntu以外のサーバーや別のバージョンで検証したりもするために起動したいサーバーを選択する形になります。

steps:
  - name: Checkout source code
    uses: actions/checkout@v2
  • name: ステップ管理をするための名前です。Github Actionsは実行中にその状況がGithub上に表示されるのですが、その進行状況を確認するための手がかりとして各ステップに名前を付けます。
  • uses: 使用する公開アクションを指定します。
    ここでは別の指定でrun: という記述をすることで、サーバーのコマンドを直接指定することもできるのですが、それをすべて毎回書いていたらとても大変です。そのために、一般的によく使われる操作は公開アクションとしてパッケージ化されています。
    ここではuses: actions/checkout@v2という指定で”checkout”という公開アクションを使用することでき、現在のリポジトリを仮想サーバー上にチェックアウトすることができます。
    これによって、仮想サーバー上でのプログラム実行やファイル操作を行うことができます。
- name: Replace .env
    run: cp .env.prod .env && rm .env.prod

.envファイルを公開用に書き換えています。
この操作は必ずしもここでやる必要は無くデプロイ時にEB側の設定で行ってもいいですが、Github Actionsのデプロイフロー内で.envの記述に関わる操作(例えばテストフローでのDB操作とか)を行う場合は必須となります。

- name: Generate deployment package
   run: zip -r ../deploy.zip . -x '*.git*'

公開ファイルをzip圧縮します。
前回の記事で手作業でやっていたことをそのまま自動化しています。

- name: Get timestamp
  uses: gerred/actions/current-time@master
  id: current-time

- name: Run string replace
  uses: frabert/replace-string-action@master
  id: format-time
  with:
    pattern: '[:\.]+'
    string: "${{ steps.current-time.outputs.time }}"
    replace-with: "-"
    flags: "g"

このあとのステップでBeanstalkに渡すタイムスタンプの値を作っています。ここの詳細は理解しなくてもOKなので、お決まりのおまじない的な感じで。

- name: Beanstalk Deploy for app
  uses: einaregilsson/beanstalk-deploy@v11
  with:
      aws_access_key: ${{secrets.AWS_ACCESS_KEY}}
      aws_secret_key: ${{secrets.AWS_SECRET_KEY}}
      application_name: sample-application
      environment_name: sample-application-env
      region: ap-northeast-1
      version_label: "my-app-${{ steps.format-time.outputs.replaced }}"
      deployment_package: ../deploy.zip

  - name: AWS Deployed!
    run: echo App deployed to ELB

実際のデプロイ操作はこちらになりますが、前回の記事でAWSコンソールからファイルをアップロードしていた操作をそのままシミュレートするものをつくってくださったbeanstalk-deployという公開パッケージがあるので、そのチカラをお借りしています。

withのところでいろいろとパラメータを指定していますが${{secrets.xxxxxx}}となっている箇所はGithubのシークレットパラメータを参照しています。
シークレットパラメータはGithub上のSettings > Secretsのところから指定できます。

もちろんわざわざ変数を使わずに直書きすることもできるのですが、publicリポジトリの場合はこのあたりのパスワード系も公開されてしまうため、このあたりは徹底しておいた方が確実です。
参考: https://docs.github.com/ja/actions/reference/encrypted-secrets#creating-encrypted-secrets-for-a-repository

あとはapplication_name、environment_name、regionをひと通り設定すれば完了です。

AWS Deployed!のところは、そのまま完了メッセージを出力しているだけです。

ワークフローの実行

すべて記述できたら保存して、あとはmasterへpushしてみるだけです。
実行中はGithubのActionsタブで進行中の表示がリアルタイム確認できますので、うまく実行されているかどうかを追うことができます。

また何らかの要因でエラー終了してしまったときに、記述は変更せずもう一度実行したいときは、こちらの画面内右上の”Re-run jobs”をクリックすることでそのまま再実行が可能です。

おわりに

今回GitHub ActionsをEBと連携して使う方法を書きましたが、まさにこれな回答が見当たらなかったので記事にしてみました。
GitHub Actionsの公開パッケージのおかげでかなり簡単に記述することができました。

Discussion