😱

GitHub Actionsの無料枠を使い切った話

2024/08/15に公開

はじめに

こんにちは、畑田です。
一瞬にしてGitHub Actionsの枠を食い潰した経験があったので、皆様にもご共有いたします。
当然の対策を怠っていたことによる出来事なので、公開するのもお恥ずかしいですが、このポストモーテムが皆様の予算の節約につながれば幸いです。

経緯

ある月初めのこと、弊社のGitHub Actionsが以下のエラーメッセージを吐いて、failしていました。
Payment Error Message

GitHub Actionsの無料枠である3000分/month (弊社は当時Teamプランでした)が使い切られているため、以下のフォームから予算のキャップを外さないとGitHub Actionsが起動できないという旨です。
予算設定フォーム

嘘だろ、まだ今月始まったばかりだぜ!?!?

弊社ではたくさんのプロダクトの開発を行っており、そのすべてでテストやデプロイを自動化していますが、それぞれのプロジェクトのデプロイ頻度なども1日に1、2回程度であり、数日で3000分を使い切るということは直感的に考えにくいです。

この原因を探していくと、悲しいことが判明しました。
以下のlogを見つけました。
6時間経過してタイムアウトしているテスト

それまで大人しく3分程度で終了していたテストが終了せず、GitHub Actionsのjobあたりのタイムアウトのデフォルト値である360分を超えてfailしていました。😱

これの具体的な理由はjestのoptionsに不備があり、CI環境で--detectOpenHandles optionをつけていたり、--ci optionをつけていなかったりして、jestが実行を継続していたというものです。

悲しいですが、予算のキャップを外し、泣く泣く追加料金を支払って、CI/CDをぶん回しました。

解決策

もちろん個別の事象に対する対策としては、テストコマンドを正しく設定するとか、jestについて学習するとか、いろいろあるでしょうが、CI/CDを回すにあたって、包括的な対策の必要性を感じました。

そこで、GitHub Actionsにタイムアウトを明示的に設定することにしました。

GitHub Actionsには実行の単位として、Workflows、Jobs、Stepsというものがありますが、このJobsStepsにはそれぞれタイムアウトを設定できます。

詳細は公式ドキュメントに譲りますが、実際の方法論だけ書いておきます。
以下はステージング環境にCloud Functionsをデプロイするためのworkflowです。
diffをつけてハイライトした行に注目すると、deployというjobに対して10分間の、Test all environment variables are setというstepに対して5分間のタイムアウトを設けています。
基本的にはjobにタイムアウトが設けられていれば十分でしょうが、数十分単位の長いjobにおいては、各stepでタイムアウトを設けてfast fail的に早くタイムアウトに気づきたいという需要も生じるでしょう。

on:
  pull_request:
    branches:
      - staging
    types: [closed]

name: Deploy Cloud Functions to Staging Environment

jobs:
  deploy:
    name: Deploy Cloud Functions
    runs-on: ubuntu-latest
+    timeout-minutes: 10

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      # Skip details

      - name: Install node modules
        run: yarn

      - name: Test all environment variables are set
        run: yarn functions test
+        timeout-minutes: 5

      - name: Deploy
        run: |
          yarn functions deploy:staging

これで一安心ですね。

まとめ

弊社では簡単なユニットテストなど一見大したことのないはずのCI/CDにもタイムアウトを設けることにしています。これは節約につながるだけでなく、早く異変に気づくのにも役立ちますし、どの処理にどれくらいかかっているかをCI/CDの設定者に認知させるきっかけにもなります。

また、今回はGitHub Actionsを例に説明しましたが、そのほかのCI/CDパイプラインでも同様の対策が必要です。弊社ではBitbucketのパイプラインや、AWS CodeBuildなど様々なCI/CDパイプラインを使用していますが、すべてでタイムアウトを設定しています。

皆様も小さなことからコツコツと基本的な対策を怠らぬようお気をつけください。

記載内容の間違いのご指摘や訂正案、より良い内容のご提案など、忌憚なきご意見を頂けますと幸いです。
今後、アプリの環境ごと再現性を高めながらデプロイメントの簡単化及び高頻度化を図ることで、質の高いアプリを量産していくため、積極的に社内のinfrastructureをIaCで管理していきたいと考えております。

R&Dテックブログ

Discussion