GitHub Actions の再利用可能ワークフローを用いた様々なイベントで動く複数の CI/CD パイプラインの運用
はじめに
こんにちは。トドケールの山本(@hayata-yamamoto)です。
今回は、GitHub Actions の再利用ワークフローを題材に、弊社がどのように GitHub Actions を運用しているかを紹介します。
GitHub Actions の再利用ワークフローについて
GitHub Actions の Reusable Workflows とは、GitHub Actions 内で頻繁に用いるワークフローを、再利用可能な状態で切り出すための機能です。
例えば、よくあるブランチごとにデプロイする環境を分けるような Action を考える時、従来であれば、環境ごとに YAML ファイルを記載し、デプロイの処理をコピペして利用していました。
しかし、この処理では開発環境で動いた処理が、本番でも同様に動くことを保証しづらく、シークレットキーなどの環境差分に加えて、コピペ時のヒューマンエラーを誘発してしまっておりました。
また、コピペでの運用では、プロダクトが成長し、デプロイの実行制御や実行前後での処理が追加された際に、全ての YAML ファイルに変更を加え、更新を施す必要があり、この際にもヒューマンエラーが発生したりしていました。(私もよくやっていました...)
Reusable Workflow を用いれば、デプロイやビルドなどどの環境でも同様に行われる処理を一箇所にまとめ、シークレットキーや環境ごとに異なる変数を外部から引き渡すことが可能になります。
どのように運用しているか
Speee さんが公開していた運用を参考に弊社では、GitHub Actions のワークフローを運用しています。
具体的には以下のような設計でワークフローを管理しています。
実際のディレクトリ構造は以下のような感じになっています。弊社のリポジトリは、モノレポ運用をしているため、ある特定のサービスだけに依存する処理は、<service>-<github-event-name>.yml
で定義されています。
.github/
└── workflows/
├── \_backend-deploy.yml
├── \_frontend-deploy.yml
├── \_mobile-build.yml
├── backend-on-pr.yml
├── mobile-on-pr.yml
├── mobile-on-push-develop.yml
├── mobile-on-push-staging.yml
├── on-push-develop.yml
├── on-push-main.yml
└── on-push-staging.yml
フロントエンドのデプロイ処理は以下のように定義しており、引数の指定を変更するだけで、全ての環境で同じ処理が走るような実装にしています。[1]
- workflow_call.inputs
- workflow_call.secrets
に要求したい情報を記載していくことで、CircleCI で言うところの commands のような使い方ができる設計となっています。(設定次第で、ワークフロー実行時の環境変数をそのまま引き継ぐこともできるのですが、暗黙的な依存ができてしまうためあまりおすすめはしません)
name: フロントエンドデプロイ用コマンド
on:
workflow_call:
inputs:
amplify-react-app-id:
description: Amplify React AppId
required: true
type: string
amplify-nextjs-app-id:
description: Amplify Nextjs AppId
required: false
default: ""
type: string
aws-default-region:
description: AWS DEFAULT REGION の値
default: ap-northeast-1
required: false
type: string
branch-name:
description: deploy したいブランチ
required: false
type: string
default: develop
secrets:
aws-access-key-id:
description: AWS アクセスキー
required: true
aws-secret-access-key:
description: AWSシークレットキー
required: true
jobs:
deploy:
name: Deploy Frontend to Amplify
runs-on: ubuntu-latest
env:
AWS_ACCESS_KEY_ID: ${{ secrets.aws-access-key-id }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.aws-secret-access-key }}
AWS_DEFAULT_REGION: ${{ inputs.aws-default-region }}
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Deploy frontend
run: |
aws amplify start-job --app-id ${{ inputs.amplify-react-app-id }} --branch-name ${{ inputs.branch-name }} --job-type RELEASE
aws amplify start-job --app-id ${{ inputs.amplify-nextjs-app-id }} --branch-name ${{ inputs.branch-name }} --job-type RELEASE
また、デプロイ時の処理では以下のような感じで定義しています。バックエンドのデプロイが完了したら、フロントエンドのデプロイが実行される制御を入れています。
name: Workflow on push to develop
on:
push:
branches: [develop]
jobs:
deploy-backend:
name: Deploy Backend
uses: ./.github/workflows/_backend-deploy.yml
with:
stage: dev
secrets:
aws-access-key-id: ${{ secrets.DEV_AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.DEV_AWS_SECRET_ACCESS_KEY }}
deploy-frontend:
name: Deploy Frontend
uses: ./.github/workflows/_frontend-deploy.yml
needs:
- deploy-backend
with:
amplify-react-app-id: xxx
amplify-nextjs-app-id: xxx
secrets:
aws-access-key-id: ${{ secrets.DEV_AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.DEV_AWS_SECRET_ACCESS_KEY }}
どうして、イベントごとにワークフローを定義しているのか?
最後に、よくメンバーからも出る質問に答えてこの記事を終わりにします。
GitHub Actions のサンプルコードを見ていると、<usecase-name>.yml
と命名された CI/CD のファイルをよく目にします。例えば、 xxx-deploy.yml とか、 build.yml のような命名のモノです。
これ自体が悪いとは思いませんが、GitHub Actions のように、さまざまなイベントでトリガーが引かれるような CI/CD を管理する場合、あまりわかりやすい命名ではないだろうと考え、今回は採用しませんでした。具体的な理由としては以下のようなことが挙げられます。
- そのユースケースが、どのタイミングで実行されるのかファイルの中身を見ないとわからないため
- 複数のイベントに対応するワークフローを記載してしまうと、
if github.event_name == 'pull_request'
のような、yaml ファイル内での条件分岐が発生してしまい、ワークフローが複雑になってしまうため。
実際問題、運用時には「〇〇ブランチにプッシュされた時に、XXX って処理が走るようにしよう」といった具合に、ブランチとイベントのペアで物事を考えることが多く、個別のユースケースについては、ジョブの名前にしたり、再利用可能ワークフローの名前にしたりするでも、十分対応が可能です。
であれば、実際に開発・改修を入れる時に考える思考プロセスと同じようにファイル名を定義し運用する方が、初めてコードを読む際の認知負荷を下げることができ、スムーズに作業に取り掛かれると考えて、上記のような設計としました。
終わりに
今回は、GitHub Actions の再利用ワークフローを題材に、弊社がどのように GitHub Actions を運用しているかを紹介しました。各社さまざまな運用があるかと思いますが、弊社は上のような形で CI/CD のフローを管理し、自動化を進めています。
この記事や弊社に少しでもご興味持っていただけたら、是非カジュアル面談などにお越しください!
Discussion