🗒️

Gitのブランチをベースにした環境(プレビュー環境)をGitHub Actionsで構築する

2024/10/14に公開

こんにちは、ツクリンクでSREエンジニアをやってるida.です。

ツクリンクのサービスは現在AWS上に構築していますが、以前はHerokuで運用していました。
Herokuには「Review App」というブランチごとに簡単に動作確認ができる素晴らしい機能があり、その恩恵を大いに享受して開発してきました。
しかし、AWSに移行した後は同様の機能がないため、GitHub ActionsとTerraformを用いて自作で同等の機能を作成しました。

プレビュー環境について

まず、このブランチをベースにした環境について、ツクリンクでは「プレビュー環境」と呼んでいます。
PR作成時に、mainにマージする前にAWS上にアップロードして確認したい時に、
そのブランチのリソースで立ち上がる環境になります。ざっくりとしたイメージは以下です。

【プレビュー環境のイメージ】

アーキテクチャについて

GitHub Actionsで、ブランチに応じた環境を構築・削除するワークフローを組み立てています。
プレビュー環境を起動するには、事前にPR(プルリクエスト)を作成しておきます。


  1. プレビュー環境起動のワークフロー
     
    プレビュー環境の起動は、PRに特定のコメントをすることでトリガーされて動作します。

    トリガー後はPRのブランチのリソースをチェックアウトしてインフラから順番に
    AWSにデプロイしていきます。
    インフラデプロイ後はサーバ起動、DBやElasticsearchの準備をして、
    ワークフロー完了後にすぐ利用できる状態になります。
     
    このワークフローは以下のステップで構成されています。
    【ワークフロー】 

  1. プレビュー環境削除のワークフロー
     
    プレビュー環境の削除は、PRに特定のコメントをするか、PRがクローズされることでトリガーされて動作します。

    クローズもトリガー条件に入れたのは削除するのを忘れてマージしたりクローズした際に漏れないためです。
    トリガー後は起動時と逆の順番で停止していきます。
    バックアップ等も取らずまっさらにするのでシンプルな構成になっています。
     
    このワークフローは以下のステップで構成されています。
    【ワークフロー】

     


構築のポイント

構築していく中で、利便性や開発メンバーの意見を取り入れながら以下の工夫を行いました。

  • データベースの復元
     
    これが今回の注目ポイントになります!
    「Review App」の時は毎回空のデータベースがアタッチされるので、そこからデータを準備しないと検証できませんでした。
    そのため環境を立ち上げてもすぐに検証できず準備する工数を費やしていました。
    そこで、今回作成する環境では、常設のテスト環境のDBで毎日取得しているスナップショットを利用することにしました。
    スナップショットを指定してRDSを複製して立ち上げることで、テスト環境と同じデータをそのままプレビュー環境で使うことができます。
    これによって、データを充実させた状態で環境を立ち上げることができ、大幅にテスト効率が向上しました!
     
  • 複数ブランチへの対応
     
    開発中、複数のPRが並行して進むことは頻繁に起こります。
    そのため、各ブランチごとに個別の環境を立ち上げられるよう、
    Terraformのworkspace機能を活用して環境を分離しました。
     
  • ブランチの正確なチェックアウト
     
    GitHub Actionsはissue_commentをトリガーに起動した場合、
    ブランチを指定せずにチェックアウトするとデフォルトブランチから取得されます。
    そのためPRの変更内容が反映されません。ブランチごとにリソースを正しく取得できるよう、
    ブランチを指定してチェックアウトするように構築しました。
    sample.yml
    - uses: actions/github-script@v7
      id: set-target-branch
      with:
        github-token: ${{secrets.GITHUB_TOKEN}}
        result-encoding: string
        script: |
          const pull_request = await github.rest.pulls.get({
            owner: context.repo.owner,
            repo: context.repo.repo,
            pull_number: context.issue.number
          })
          return pull_request.data.merged ? pull_request.data.base.ref : pull_request.data.head.ref;
    - uses: actions/checkout@v4
      with:
        ref: ${{ steps.set-target-branch.outputs.result }}
    
     
  • Slack連携での通知
     
    非機能面ではありますが、ワークフローの成功や失敗をSlackに通知する機能を追加しました。
    これにより、チーム全体が迅速に進行状況やエラーを把握できるようになりました。
     

まとめ

AWSへの移行後も、ブランチをベースに環境を立ち上げて検証できる仕組みを整えました。
特に、ローカル環境で動作するけど、AWS上では動かないといった問題を未然に防ぐため、
本番環境に近い構成で事前に検証できるのは大きなメリットです。
開発メンバーへHeroku上で運用していた時と同様の開発体験を提供して、効率的な開発に繋げられたので良かったと思います。

Discussion