KAKEHASHI Tech Blog

カケハシのEngineer Teamによるブログです。

GitHub Actions料金 Datadogによる可視化と削減のヒント

開発コストのうちGitHub Actions料金が占める割合は小さい傾向にありますが、組織規模によっては削減の必要があるでしょう。

この記事では、主にDatadogを利用した可視化による特定方法と、一般的なコスト削減のヒントを述べます。

前提:パフォーマンスを改善する

従量課金のアプリケーションではパフォーマンス ≒ コストです。まずは実行時間から改善しましょう。

カケハシでは以下のような事例があります。

以下の記事も観点洗い出しができるのでおすすめです。

この記事では実行時間以外のコスト観点で解説します。

実行時間と課金時間の違いを学ぶ

GitHub Actionsの最低課金時間(billable time)は1分です。

1秒実行(Run time)でも1分分の料金になりますし、1分2秒なら課金時間は2分です。

実行時間が長いものに料金がかかるのは当然として、仕組み上、細かいものでも実行回数が多いと料金が嵩んできます

全体を分析する

GitHub Actionsの可視化はGitHubだけでは難しいです。CSVをダウンロードできるだけで、リポジトリ単位でも見づらく、横断での分析は困難です。

ここでDatadogのCI Visibility機能を使いましょう。リポジトリごとの実行時間を可視化できます。

Datadogでの見方要点

Tree Mapが便利です。

Tree MapからCI Pipelinesを選択し、LevelはPipeline、Durationの合計を選択します。リポジトリ、パイプライン名、ブランチでグループ化すると見やすいです。

DatadogでのDurationは課金時間(billable)を指しています。 ただし、現在のところ単価は考慮できません。Larger RunnerやMacインスタンスといった異なる単価が反映できるとよいですね。

可視化だけのためにDatadog CIを新しく使い始めると、料金がまずまずかかって本末転倒なことも。すでにDatadog CIを利用済みならコスト可視化を使いこなしましょう。

GitHub上での見方

Run DetailsのUsageに遷移すると各Jobの課金時間(billable time)が表示されます。

具体的な料金の削減方法

JobをStepにまとめる

ワークフローはJobで構成され、JobのなかにStepを配置する構造です。

課金はJob単位です。複数のJobを単一のJob内Stepとしてまとめるとコスト面では2つの点で有利です。

まず、課金時間の計算方法の違いです。同一の内容でもJobが5個あれば最低5分分課金されますが、一つのJobに5個Stepを詰め込めば最低1分分となります。

次に、Jobはコンテナのように隔離されており個別に初期化されるため、関連したJobをStep化すると合計の実行時間が若干節約できます。

注意点は、Jobと違いStepは並列実行できず、待ちが長くなる可能性があることです。同時に実行する別のJobがあるなら、Job同士の長さを調整して全体のリードタイムが増えないようにするとよいでしょう。

Linter類のようにあまりエラーにならずデバッグも容易なものはまとめやすいです。

重複の排除

GitHub Actionsでは様々な条件のイベントをもとにジョブを実行できます。

CIが複雑化すると、同じような検証処理が何度も実行されていることが多々あります。pushやpull requestのイベント、ブランチの種類といった視点で整理してみましょう。

renovate / dependabotをどこまで検証するか

パッケージのマイナーバージョンアップデートがCI実行時間の多くを占めていることがあります。通常のPRと同等の検証はどこまで必要でしょうか。

  • CIの一部を除外する、
  • PRをまとめる機能を使う
  • PRそのものではCIを実行せず、マージ段階でまとめてテストする

といったことが考えられます。

ソースコード以外の修正時の動作を考える

readmeの修正でワークフローがすべて動くのはもったいないでしょう。開発ツールの設定変更でソースコードのテストが動いてほしくないときもあります。インフラの設定も同様です。

ファイル種類ごとに整理しましょう。

pre commitで高速なツールを使う

Linterのようなpre commitには高速なものを採用しましょう。実行回数が多いことから、なるべく1分を超えないようにしたいですね。

PythonであればruffのようなRust系ツールがよいでしょう。

timeoutが初期設定6時間なので縮める

ワークフロー実行中に応答がなくなりタイムアウトが発生することがあります。タイムアウトの初期設定が6時間なので、発生すると10分のフローなら36回分消費されます。

タイムアウトを設定していないワークフローをコード検索で洗い出してみましょう。自組織を指定し、以下の条件で検索します。

NOT timeout-minutes: path:.github/ language:YAML language:YAML

終わりに

GitHub Actionsについてはパフォーマンス向上が優先であり、コストを毎月トラッキングするほどではないです。半年か四半期に一度ぐらいの頻度が適切でしょう。

文責:高木