0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Amazon EventBridge、AWS Lambda、GitHub Actions workflow_dispatch を使って定期的にワークフローを実行する

0
Last updated at Posted at 2026-02-07

GitHub Actions の schedule トリガーを利用した場合の問題点

以前、 GitHub Actions の schedule を使って、定期的にワークフローを実装する仕組みを構築しました。

ワークフロー内で以下のように設定していたので、5分おきに実行されてほしいところだったのですが、実際に運用を始めてみると、10分間隔で実行されたり、20分くらい開いたり、酷いときは数時間ほど実行されていなかったりと、 schedule というトリガー名の割にはかなり不正確な実行間隔となっていました。

on:
  schedule:
    - cron: "*/5 * * * *"

ワークフローの一覧画面で右側に表示されている実行されたタイミングの時間を見てみると、実行間隔がまちまちになっていることがわかるかと思います。

image.png

schedule説明には以下のような記述があるため、こういった現象が発生することは事前にわかってはいましたが、それにしてもこれほどまでとは思っていませんでした。

The schedule event can be delayed during periods of high loads of GitHub Actions workflow runs. High load times include the start of every hour. If the load is sufficiently high enough, some queued jobs may be dropped. To decrease the chance of delay, schedule your workflow to run at a different time of the hour.

こういった状況を受けて、GitHubやMicrosoft Azureに詳しい @tsubakimoto_s さんに相談してみたところ、 ワークフローのトリガーを schedule ではなく、手動実行で呼び出す際に指定する workflow_dispatch を利用するようにして、外部から GitHub REST API を使って呼び出すことで、定期的にワークフローを実行できそうだと教えてもらいました。

上記の相談を元に @tsubakimoto_s さんは実際に手を動かし、以下のブログにまとめてくれています。(大感謝)

上記のブログの内容を参考にさせてもらって、今回は「Amazon EventBridge」と「AWS Lambda」、そして「GitHub Actions」の workflow_dispatch トリガーを使って、定期的にワークフローを実行する仕組みを改めて構築してみようと思います。
(すべての処理を AWS Lambda にまとめることもできるかと思いますが、今回は既存の GitHub Actions のワークフローを再利用することにしました。)

  • アーキテクチャ変更前
    • GitHub Actions の schedule トリガーで定期的に実行する。
  • アーキテクチャ変更後
    • Amazon EventBridge の「定期的なスケジュール」の機能を使って AWS Lambda 経由で GitHub Actions の workflow_dispatch トリガーを定期的に実行する。

GitHub Actions の workflow_dispatch トリガーを利用する場合の設定手順

personal access token を作成

AWS Lambda 経由で以下のような GitHub の REST API を呼び出すことになるので、前準備として GitHub の「personal access token」を作成します。

「personal access token」の作成方法については以下のページを参照してください。

GitHubの画面右上のアイコンをクリックしてメニューを表示します。

2026-02-07_23-06_1.png

メニューの中から「Settings」をクリックします。

2026-02-07_23-07.png

画面左側に表示されているメニューの中から「Developer Settings」をクリックします。

2026-02-07_23-10.png

画面左側に表示されている「Personal access tokens」のメニューから「Fine-grained tokens」をクリックします。

2026-02-07_23-11.png

「Generate new token」ボタンをクリックします。

2026-02-07_23-13.png

「Token name」、「Expiration」あたりは適宜入力してください。長期運用する想定なので「No Expiration」でもよいかと思いましたが、今回はひとまず数ヶ後の月末日を設定しました。

2026-02-07_21-49.png

「Repository access」では GitHub Actions を呼び出したい対象のリポジトリを選択し、「Permissions」は以下のように設定しました。

  • Contents: Read
  • Actions: Read, Write
  • Pull Requests: Read, Write
  • Metadate: Read (Requiredな権限のためデフォルトで選択状態になっている)

2026-02-07_21-56.png

Amazon EventBridge でスケジュールを作成

personal access token の準備ができたので Amazon EventBridge のスケジュールを作成していきます。

AWS の Amazon EventBridge のトップ画面で「EventBridge スケジュール」を選択して「スケジュールを作成」ボタンをクリックします。

image.png

または AWS の Amazon EventBridge の画面左側のメニューから「スケジュール」をクリックして

image.png

「スケジュールを作成」ボタンをクリックします。

image.png

「スケジュール名」を入力して、「スケジュールグループ」を選択します。

image.png

「定期的なスケジュール」、「rateベースのスケジュール」を選択して、「rate式」を5分毎に実行されるように設定します。

image.png

次の画面で「テンプレート化されたターゲット」から「AWS Lambda」を選択します。

image.png

Lambdaが未作成の状態なので、「新しい Lambda 関数を作成」をクリックします。

image.png

関数名を入力し、ラインタイムは「nodejs24.x」を選択します。その他はデフォルト設定で問題ありません。

image.png

「コードソース」の画面で index.mjs に以下の内容を入力します。

export const handler = async () => {
  const owner = process.env.GITHUB_OWNER;
  const repo = process.env.GITHUB_REPO;
  const workflow = process.env.GITHUB_WORKFLOW;
  const ref = process.env.GITHUB_REF;
  const token = process.env.GITHUB_TOKEN;

  const url = `https://api.github.com/repos/${owner}/${repo}/actions/workflows/${workflow}/dispatches`;

  const res = await fetch(url, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${token}`,
      Accept: "application/vnd.github+json",
      "Content-Type": "application/json",
      "User-Agent": "aws-lambda"
    },
    body: JSON.stringify({ ref })
  });

  if (!res.ok) {
    const text = await res.text();
    throw new Error(`GitHub API failed: ${res.status} ${text}`);
  }

  console.log("GitHub Actions workflow dispatched");
};

入力内容を確認して「Deploy」ボタンをクリックします。

image.png

「設定」のタブに移動します。

image.png

画面左側のメニューから「環境変数」をクリックします。

image.png

Lambda で利用する環境変数を設定します。

image.png

Lambda の準備ができたので Amazon EventBridge の画面に戻って、再読み込みのボタンをクリックし、作成済みの Lambda 関数を選択します。

image.png

次の「設定 - オプション」の画面ではすべてデフォルト設定のままとします。

image.png
image.png

確認画面が表示されるので、「スケジュールを作成」をクリックします。

image.png
image.png


運用開始

5分毎の定期実行に成功

すべての準備が整ったので GitHub Actions の画面でワークフローの一覧を表示してみると、だいたい5分毎に実行されていることが確認できました。

2026-02-07_22-24.png

問題発生

意図通りの動作になったので安心していましたが、数日後に「Run failed」という件名の大量のメールを受信しました。

image.png

GitHub の通知画面でも同様に大量のエラーを確認することができました。

image.png

通知内容を確認すると支払いに関するエラーが発生していることがわかりました。

The job was not started because recent account payments have failed or your spending limit needs to be increased. Please check the 'Billing & plans' section in your settings

image.png

支払いに関するエラーが表示されていたので、確認のために「Billing and licensing」の「Overview」の画面に遷移します。

image.png

GitHub Actions の無料枠の範囲である「2000分/月」を見事に超えていました。

2026-02-07_23-35.png

しかし、無料枠の時間のことは定期実行の運用を始めるタイミングで頭の片隅に置いていました。
1回の実行には10秒程度かかっており、実行時間を月で換算すると「1440分」くらいになるはずなので、「2000分」は超えないと踏んでいたのですが、どうやらアテが外れたようです。

利用状況を確認するために「Billing and licensing」の「Usage」の画面に遷移します。

image.png

ゾッとするグラフが表示されました。無料枠の範囲を超えたらエラーで落ちる仕組みだったので助かった。。。

2026-02-07_23-36.png

GitHub Actions が無料枠の範囲を超える前の時間帯の実行状況を見てみると、1〜2分毎の間隔で実行されていることがわかりました。

2026-02-07_22-25.png

無料枠の上限に到達した後の実行はすべて失敗しています。無料枠の範囲を超えてエラーで落ちる仕組みじゃなかったらクラウド破産するところだった。。。

image.png

無料枠の範囲を超える前後の時間帯の CloudWatch のログを確認してみると、タイムアウトが発生して同じ RequestId で複数回実行されていることが確認できました。直接の原因はタイムアウト後の複数回のリトライで間違いないようです。

2026-02-07_23-01.png

なぜタイムアウトが頻発したのか

これは有名な話かもしれませんが Lambda のデフォルトタイムアウトは「3秒」です。このタイムアウト設定を変更することを失念していたのがそもそもの原因かと思います。

それと、 Amazon EventBridge の「設定 - オプション」の画面で「再試行ポリシー」の設定をデフォルトのままとしました。

image.png

これにより、最大で185回の再試行回数が設定されていたことになります。(危ねぇ。。。)

image.png


対策案

上記の状況を受け、以下のように変更を行います。

  • AWS Lambda のタイムアウトを「3秒」から「30秒」に変更する。

image.png

  • Amazon EventBridge の実行間隔を「5分毎」から「10分毎」に変更する。

image.png

  • Amazon EventBridge の再試行ポリシー
    • 「イベント最大経過時間」を「24時間」から「5分」に変更する。
    • 「試行回数」に「1回」を指定する。

image.png


設定変更後の運用状況

GitHub Actions の画面で実行状況を確認してみたところ、キッチリ10分毎に実行されているようです。
前回はうまく動いてそうと早計に判断して監視を怠ったので、これから数日程度は引き続き運用状況を注視しようと思いますが、ひとまずは対策案がうまくいってそうですね。

image.png

設定変更を行って数時間後に実行時間の間隔を眺めてみると、数回程度ですが1分後にリトライしているような状況が発生していました。

image.png

CloudWatch のログを確認すると GitHub の API が「500番」のエラーを返しており、タイムアウトによるリトライではないことがわかりました。
10分毎に実行していると中にはこういったエラーが発生することもあるのでしょう。
「再試行ポリシー」で設定した「試行回数」の1回が効いているようで、複数回のリトライも発生していないため、問題ない範囲の現象だと判断しました。

2026-02-07T23:45:20.440Z	146987ce-61e9-431a-9775-ffb138925744	ERROR	Invoke Error 	{
    "errorType": "Error",
    "errorMessage": "GitHub API failed: 500 {\"message\":\"Failed to run workflow dispatch\",\"documentation_url\":\"https://docs.github.com/rest/actions/workflows#create-a-workflow-dispatch-event\",\"status\":\"500\"}",
    "stack": [
        "Error: GitHub API failed: 500 {\"message\":\"Failed to run workflow dispatch\",\"documentation_url\":\"https://docs.github.com/rest/actions/workflows#create-a-workflow-dispatch-event\",\"status\":\"500\"}",
        "    at BufferedInvokeProcessor.handler (file:///var/task/index.mjs:23:11)",
        "    at process.processTicksAndRejections (node:internal/process/task_queues:103:5)",
        "    at async BufferedInvokeProcessor.processInvoke (file:///var/runtime/index.mjs:1092:22)",
        "    at async _Runtime.processSingleConcurrent (file:///var/runtime/index.mjs:1178:7)",
        "    at async _Runtime.start (file:///var/runtime/index.mjs:1165:7)",
        "    at async ignition (file:///var/runtime/index.mjs:1634:5)"
    ]
}

関連URL

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?