GitHub Logo

GitHub Actions vs EC2 cron:監視自動化はどっちで動かすべきか

WordPress サイトの定期監視(プラグイン更新通知、メール送信数の異常検知など)を実装する時、GitHub Actions の cron スケジュールで動かすか、EC2 上の cron で動かすか。コストもインフラもどっちでも実現できるのに、選択を間違えると後で痛い目を見るので、判断基準を整理する。

結論を先に:「外部から見るべき監視」は GitHub Actions、それ以外は好み

ただしこの結論には前提がある — 「すでに GitHub でデプロイ運用している」こと。repo 駆動デプロイをしていなければ判断材料が変わるので、後段の Layer 1 で前提を明示し、最後に Google Apps Script (GAS) や Cloudflare Workers などの代替案も比較する。

検討対象の 2 案

案 A: GitHub Actions cron

on:
  schedule:
    - cron: '*/5 * * * *'   # 5分ごと
  workflow_dispatch:

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - name: Configure AWS credentials (OIDC)
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_DEPLOY_ROLE_ARN }}
          aws-region: ap-northeast-1
      - name: Check and notify
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
        run: |
          # AWS CLI で監視対象を取得
          # 閾値判定
          # Slack に通知

案 B: EC2 上の cron

# crontab -e
*/5 * * * * /usr/local/bin/check-and-notify.sh
# /usr/local/bin/check-and-notify.sh
#!/bin/bash
# 監視対象を取得(aws cli は EC2 instance role で認証)
# 閾値判定
# Slack に通知

両方とも同じことを実現できる。技術的にはどちらでも書ける。

判断軸:2 つのレイヤーで考える

判断を「開発効率・保守性」と「セキュリティ・外部監視原則」の 2 層に分けると整理しやすい。

Layer 1: 開発効率・保守性

観点GitHub ActionsEC2 cron
コード管理リポジトリで完結crontab は本番直編集、スクリプトは別管理
ログGitHub UI で確認できるjournalctl / ファイル / mailto 等の設計が必要
既存パターン他の workflow と同じ流儀で書ける既存のシェルスクリプト群と同じ流儀
環境変数の管理GitHub Secrets で集約本番 .env or 環境変数で管理
デプロイpush で反映本番 SSH + ファイル配置(or rsync 設計)

repo 駆動デプロイをしている環境なら、GitHub Actions の方が一貫性で勝つ。新規 workflow を追加するコストが「YAML 1 枚 + push」で完結する。

EC2 cron だと「crontab を編集する」「シェルスクリプトをどこに置くか決める」「ログをどこに出すか決める」「環境変数をどう注入するか決める」と、毎回小さな設計判断が積み重なる。

🔑 ここが今回の判断の前提条件:すでに GitHub Actions でデプロイ workflow が動いているから、新しい監視 workflow も同じパターン(OIDC、Secrets、step 構成)で書ける。この前提が無ければ、わざわざ GitHub Actions を入れる動機は弱くなる — EC2 cron や後述の代替案を検討する余地が増える。「GitHub を使ってない人が、監視のためだけに GitHub Actions を導入する」のは過剰投資になる場合が多い。

Layer 2: セキュリティ・外部監視原則

ここが本記事の核心。

「監視主体は監視対象の外にあるべき」という古典的な原則がある。理由を 1 つの侵害シナリオで説明する。

シナリオ:EC2 が侵害された場合
  1. 攻撃者が WordPress プラグインの脆弱性を突いて EC2 内に侵入
  2. wp_mail() を使って大量のフィッシングメールを送信し始める
  3. ……同じ EC2 上の cron 監視も、攻撃者が crontab -r で削除できる
  4. 監視が止まる → 通知が来ない → 検知できない → 被害拡大

つまり「監視対象が侵害された瞬間、監視も死ぬ」。これが EC2 cron の構造的弱点。

GitHub Actions なら:

  1. 攻撃者が EC2 内に侵入しても、GitHub Actions の workflow は AWS の外側(GitHub のインフラ)から動いている
  2. CloudWatch API 経由でメトリクスを取得するので、EC2 が侵害されても監視は止まらない
  3. 異常値が検知されれば、ちゃんと Slack に通知が飛ぶ

この構造的安全性は、侵害検知用途では決定的な差になる。

もうひとつの構造的優位:認証方式。GitHub Actions は OIDC で短命 credential(数分〜数十分有効)を都度発行して AWS API を叩く。長期保存される access key はゼロ。これは「監視のために発行した認証情報が漏れて新たな攻撃面になる」リスクを潰してくれる。後述の GAS / Cloudflare Workers は AWS を叩くなら IAM ユーザーの long-lived key を持たされるので、この点で一段劣る。

ユースケース別の判定表

両レイヤーを踏まえると、こうなる。

ユースケースEC2 cron でも可?GitHub Actions の必要度
プラグイン更新の通知可(情報取得目的、侵害シナリオは薄い)Layer 1 で有利
パフォーマンス監視可(侵害シナリオじゃない)Layer 1 で有利
メール送信数の異常検知(侵害時に止まる)Layer 2 が決定的
バックアップ実行確認(バックアップ失敗時こそ通知必要)Layer 2 が決定的
不正アクセス検知(侵害が前提なのに監視も侵害される)Layer 2 が決定的
日次のデータ集計好み

侵害・障害時に通知が止まると困るタイプの監視」は GitHub Actions 一択。

それ以外の選択肢:GAS / Cloudflare Workers

「外部監視」を満たす方法は GitHub Actions だけじゃない。代表的な代替を 2 つ整理する。

Google Apps Script (GAS)

完全に Google 側で動く第三者ホスティング型。Layer 2 の「監視対象の外」原則は満たす。

観点評価
Layer 2(侵害シナリオでも止まらない)
無料枠✅(個人なら実質無料、1 日 90 分実行)
通知✅(Slack Webhook を直で叩ける)
AWS 認証⚠️ IAM ユーザーの long-lived Access Key が必要。Google → AWS の Workload Identity Federation を組めば回避できるが構築コストが重い
コード管理⚠️ GAS Editor or clasp で別管理。repo に直接乗らない
Google ecosystem 統合✅ スプレッドシート記録、Gmail 通知など Google サービスとの親和性は最強

決め手:認証セキュリティ。GAS から AWS を叩くには long-lived Access Key を持たされる。監視を作るために新しい認証情報を半永久的に管理することになり、「侵害検知のために攻撃面を増やす」本末転倒リスクが出る。GitHub Actions OIDC(短命)と比べると一段劣る。

ただし「監視対象が AWS じゃなくて Google Cloud」「結果をスプレッドシートに記録したい」「Gmail で通知したい」など Google サービス統合が主目的なら、GAS が一番すっきりする。

Cloudflare Workers (Cron Triggers)

似たような第三者ホスティング型の cron。wrangler.toml[triggers] crons = ["*/5 * * * *"] を書くだけでスケジュール実行できる。

観点評価
Layer 2
無料枠✅(10 万回/日まで無料)
AWS 認証⚠️ GAS と同じく long-lived key が必要
コード管理✅ ローカル開発→wrangler deploy で repo 駆動できる
既存パターン再利用❌ GitHub deploy と別 ecosystem

Cloudflare で fronted や DNS を運用してるなら、Cron も乗せてしまうのは自然。AWS 中心なら認証面で GitHub Actions の方が一段優位。

実装上のトレードオフ

GitHub Actions cron を選ぶ場合のデメリットも正直に書いておく。

検知遅延

GitHub Actions の cron は厳密ではない。高負荷時には数分〜数十分の遅延が起きうる。「5 分ごと」と設定しても「5 分前後」と捉える必要がある。

CloudWatch Alarm + SNS + Lambda の純 AWS 構成なら 1〜2 分以内に発火できるので、リアルタイム性が決定的に重要なら純 AWS 構成を選ぶ。

ただし、個人ブログレベルの監視で「3 分遅延すると致命的」というケースはほぼない。

実行時間枠の消費

GitHub Actions の Free 枠は月 2,000 分。5 分ごとの監視 workflow を 1 個動かすと、月 8,640 回実行 × 30 秒 ≒ 月 72 分の消費。Free 枠の 3.6 % で、複数の監視 workflow を持っても余裕。

ただし、組織アカウントで Actions を多用しているなら計算しておく。

AWS API コール料金

CloudWatch GetMetricStatistics は月 1,000 リクエストまで無料、超過分は $0.01 / 1,000 リクエスト。5 分ごとなら月 8,640 リクエスト = 約 $0.08 / 月。実質無料。

監視 workflow を書く時の定型

実装パターンを 1 つテンプレ化しておく。

name: <監視名>

on:
  schedule:
    - cron: '*/5 * * * *'
  workflow_dispatch:

permissions:
  id-token: write
  contents: read

env:
  THRESHOLD: 50  # 閾値は env で定数化(変更時に判定箇所と分離)

jobs:
  check:
    runs-on: ubuntu-latest
    environment: production
    steps:
      - name: Configure AWS credentials (OIDC)
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_DEPLOY_ROLE_ARN }}
          aws-region: ap-northeast-1

      - name: Check and notify
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
        run: |
          set -euo pipefail
          # 1. データ取得(aws cli, wp-cli, curl など)
          # 2. 閾値判定
          # 3. 異常時のみ Slack へ通知(沈黙=正常)

ポイント:

  • OIDC で短命 credential を使う。長期的な access key を Secret に置かない
  • secrets は必ず with: または env: 経由で渡す。run: の中に直接 ${{ secrets.X }} を書かない(コマンドインジェクション対策)
  • 沈黙=正常の設計にする。0 件の日もメッセージが飛ぶと通知疲れで見なくなる
  • 閾値は env: で定数化しておくと、テスト時に変えやすい

まとめ

状況推奨
「監視を自動化したい」だけどっちでもいい
「侵害検知・障害検知」が目的外部監視(Actions / GAS / Workers)
repo 駆動デプロイ運用中 + AWS 監視GitHub Actions(一貫性 + OIDC 短命 credential)
Google サービス中心、AWS は触らないGAS
Cloudflare 中心で運用Cloudflare Workers
AWS 中心、GitHub 使わないCloudWatch Alarm + SNS(純 AWS)
秒単位でアラート飛ばしたいCloudWatch Alarm + SNS
既存資産何もない・最小コストで始めるEC2 cron(Layer 2 を割り切るなら)

Layer 1 だけ見ると EC2 cron も全然アリ。でも Layer 2 を考えると「監視対象と監視主体を分ける」鉄則があり、特に侵害検知系の監視は外部から見るべき

そして外部監視を選んだあとは「認証方式」が次の判断軸になる。長期 Access Key を発行する代替案より、OIDC で短命 credential を使える GitHub Actions が、AWS 監視には一段安全。

crontab -e の手軽さに惹かれる時は、「この監視が止まったら誰が気付くか」を一度自問してみる。それが「監視自身しかない」なら、自己監視のパラドックスにハマっている。

Home » コンピューター » GitHub Actions vs EC2 cron:監視自動化はどっちで動かすべきか