はじめに

株式会社 AJA でバックエンドエンジニアをしている片山です。

「GitHub Actions ワークフローが更新されてないけど、動いているから OK」 そんな状況にあるチームは多いのではないでしょうか。

今回は、2022 年頃から更新が止まっていた GitHub Actions ワークフローを全面的に刷新しましたので、同じような状況にある方が参考にできそうなポイントをまとめます。

背景

AJA DSP では、Go 言語・Google Cloud Platform(GCP)・Kubernetes を中心とした技術スタックで動画広告配信プラットフォームを開発しています。システムを運用する中で、GitHub Actions ワークフローに現在のベストプラクティスと乖離が生じており、改善の必要性が高まっていました。

なぜ更新が止まっていた?

理由は単純で「動いているから触らない」という状況でした。

そして、以前は別チームが保守を担当していましたが、AJA 内で体制を整えて引き継いだタイミングでメンテナンスの優先度を見直し刷新にいたりました。

刷新したポイント

レガシーワークフローの刷新において、私たちが見直したポイントいくつかご紹介します。

同じような技術スタックの方は、ぜひ参考にしてみてください!

技術スタック:Golang, Kubernetes, マイクロサービス, Datadog, GitHub Actions

Workload Identityによる認証強化

GitHub Actions から GCP への認証方式を、サービスアカウントキーから Workload Identity に移行しました。

古いシステムだとサービスアカウントキーによる永続的な権限が払い出されていることが多いので、まず確認したい項目です。

Workload Identity により、サービスアカウントキーの管理が不要になり、セキュリティが強化されました。

Before(サービスアカウントキー):

- uses: 'google-github-actions/auth@v2'
  with:
    credentials_json: ${{ GCP_SA_KEY }}
    project_id: ${{ PROJECT_ID }}

After(Workload Identity):

- uses: 'google-github-actions/auth@v2'
  with:
    project_id: ${{ PROJECT_ID }}
    workload_identity_provider: ${{ WORKLOAD_IDENTITY_PROVIDER }}

と文字で書くとあっさりしていますが、実際にはかなりの作業量があります。GCS への書き込み、Artifact Registry へのプッシュ、Cloud Run の起動など権限の整理も必要です。

以下のポイントを押さえて小さく作っていくことを推奨します。

  • Workload Identity の準備が必要(ロールの整理、プール作成など)
  • 移行時は既存のサービスアカウントキーと並行運用し、動作確認後に切り替える(ワークフローが動かなくなった場合のチーム影響大)
  • GitHub Secrets の整理も併せて実施(不要なキーを刷新のタイミングで削除)

GitHub – google-github-actions/auth: A GitHub Action for authenticating to Google Cloud.

再利用可能なワークフローの導入

マイクロサービス構成では、各コンポーネントがそれぞれ Docker イメージを持つため、従来は 10 以上のコンポーネントそれぞれに類似したワークフローファイルが存在していました。

これによりメンテナンスコストが高く、セキュリティアップデートなどの変更を全ファイルに適用する必要がありました。

そこで、workflow_callを活用した再利用可能なワークフローを導入しました。

Before(コンポーネントごとに個別のワークフロー):

name: Docker Push component-a
on:
  push:
    paths: ["components/component-a/**"]
jobs:
  docker-publish:
    # 100行超のビルド・デプロイロジック
    # これが10個以上のコンポーネント分存在

After(再利用可能なワークフロー):

name: Docker Push component-a
on:
  push:
    paths: ["components/component-a/**"]
jobs:
  call-docker-push:
    uses: ./.github/workflows/docker-push.yml
    with:
      DOCKERFILE: dockerfiles/component-a.Dockerfile
      SERVICE_NAME: component-a
      IMAGE_NAME: component-a

マイクロサービスのような複数コンポーネント構成では、この変更により以下のメリットが得られました。

  • メンテナンス効率の向上:共通ロジックが一箇所に集約
  • 新規コンポーネント追加の高速化:テンプレート化により数行の設定のみで新しいコンポーネントのワークフローが構築可能

ワークフローの再利用 – GitHub Docs

Artifact Registryへの移行

コンテナイメージの管理に Container Registry(GCR)を利用していましたが、Artifact Registry への移行も併せて実施しました。

実は、GCR は2025年3月18日でサービス終了予定となっており、この移行は避けて通れない道でした。(多くの方が既に対応済みかと思いますが)マストで対応したいポイントです。

Container Registry の提供終了を準備する  |  Artifact Registry documentation  |  Google Cloud

アクションバージョンのハッシュ固定

私たちのチームに実害がなかったとはいえ、2025 年 3 月の GitHub Actions サプライチェーン攻撃の発生により、レガシーワークフローのセキュリティリスクが明確になりました。 セキュリティベストプラクティスに従い、アクションのバージョンをハッシュで固定しました。

Before:

- uses: actions/checkout@v2
- uses: docker/setup-buildx-action@v1

After:

- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0

この作業には pinact というツールを採用しました。

ハッシュ固定ツールには複数の選択肢がありましたが、pinact を選択した理由は以下の通りです:

  • Dependabot との連携:バージョンコメント形式(# v1.0.0)でハッシュを固定するため、Dependabot が自動的にバージョンアップデートを検出可能
  • 使いやすい更新プロセス:セマンティックバージョニングに基づいてハッシュを更新するため、直感的に利用しやすい

これにより、タグの付け替え攻撃を防ぎつつ、継続的なセキュリティアップデートも自動化できるようになりました。

GitHub – suzuki-shunsuke/pinact: pinact is a CLI to edit GitHub Workflow and Composite action files and pin versions of Actions and Reusable Workflows. pinact can also update their versions and verify version annotations.

ベストプラクティスの実践と継続的な改善

レガシーワークフローを刷新する際に、ぜひ一緒に適用していただきたいベストプラクティスと継続的に改善していくための工夫を紹介します。 これらは比較的簡単に導入できる一方で、運用の安定性に大きく寄与します。

タイムアウト設定による異常検知

timeout-minutes: 10

各ジョブにタイムアウトを設定することで、無限ループやハングアップを防止し、異常なビルド時間を早期検知できるようにしています。

環境変数設定

従来の::set-envコマンドから、より安全な$GITHUB_ENVへの書き込み方式に変更。

これにより、コードインジェクション攻撃のリスクを軽減できます。

- name: Set environment variable
  run: echo "BUILD_DATE=$(date)" >> "$GITHUB_ENV"

GitHub Actions: Deprecating set-env and add-path commands – GitHub Changelog

GitHub Actions 自体の品質向上を仕組み化

GitHub Actions ワークフローファイル自体にも lint を導入し、構文エラーやベストプラクティス違反を事前に検出できるようにしました。

name: GitHub Actions Lint
on:
  pull_request:
    paths:
      - ".github/workflows/*.yml"
jobs:
  actionlint:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
      - uses: reviewdog/action-actionlint@a5524e1c19e62881d79c1f1b9b6f09f16356e281 # v1.65.2

GitHub – rhysd/actionlint: :octocat: Static checker for GitHub Actions workflow files

Datadog による CI 監視

GitHub Actions ワークフローに Datadog CI Visibility を導入し、パイプライン実行状況を可視化しました。

Datadog コンソールと GitHub の設定画面から数クリックで連携でき、ワークフローファイルの変更は不要で既存のパイプラインがそのまま監視対象になります。

ワークフローファイルへの変更は不要と言ったものの、Job へ一意な名前を付与しておくと Datadog CI Visibility での計測からリポジトリ側での特定、改善が容易になります。

Datadog CI Visibility

導入により、パイプライン実行時間の分析でボトルネックとなるステップを特定できるようになり、成功率を定量的に把握できています。特に実行時間の長いパイプラインが明確に可視化され、継続的な改善のヒントとなっています。

「なんとなく遅い気がする」という感覚的な判断から、CI の監視によって定量的な判断ができるようになりました。

GitHub Actions のワークフローにトレースを設定する

まとめ

レガシーな GitHub Actions ワークフローの刷新により、セキュリティ、メンテナンス性、運用効率を向上させることができました。

セキュリティ

  • Workload Identity による認証強化で、永続的なサービスアカウントキーの管理リスクを排除
  • ハッシュ固定によるサプライチェーン攻撃への耐性向上

メンテナンス性

  • 再利用可能なワークフローにより、10 以上のコンポーネント用ワークフローを 1 つに集約
  • 新コンポーネント追加時のワークフロー作成が数行の設定のみで完了

運用効率

  • Datadog CI Visibility による定量的な監視で、感覚的だった問題特定が明確化
  • タイムアウト設定と lint ツールにより、異常検知と品質向上を自動化

レガシーシステムの改善は「動いているものに触りたくない」という心理的ハードルがありますが、適切な計画と段階的なアプローチをとれば、リスクを最小限に抑えながら大きな改善効果を得ることができます。

同じような課題を抱えているチームの参考になれば幸いです。