GitHub ActionsによるWindowsタスクスケジューラの自動反映

OGP

はじめに

こんにちは。SRE部BtoBチームの田村です。BtoBチームが担当してるサービスには、クラウドで構成されているFBZ、オンプレ環境で稼働しているブランド様の自社ECシステム支援事業もあります。その自社ECシステムでは、バッチ処理が多数稼働しています(執筆時点でバッチ214本)。

バッチ処理のスケジュールはWindowsのタスクスケジューラで管理しており、定期メンテナンスや新規サービスリリースの際に運用者が手作業でタスクスケジューラの設定を更新していました。

手作業を伴い、繰り返される要素もあったため、我々のチーム内で「バッチの運用」はトイルの1つとして認識されていました。また、前回の記事と同様に、設定戻し漏れのリスク、作業工程の履歴を別帳票で管理する煩雑な運用があり、万全とは言えない状態でした。そこで、前回の記事をヒントにトイル撲滅運動としてタスクスケジューラ設定の自動反映の仕組みを構築したので、その方法について共有します。

目指す姿

今回目指す、GitHub ActionsによるWindowsタスクスケジューラ自動反映のフローは以下の通りです。

  1. 開発者によるPull Request作成
  2. 承認者によるレビューとマージ実行
  3. Pull Requestマージイベントによる発火
  4. セルフホストランナーでワークフロー実行
  5. Windowsタスクスケジューラへの反映

概要図

実現するために対応したこと

目指す姿を実現するために以下のことを対応しました。

  • セルフホストランナーの導入
  • セルフホストランナーにschtasksコマンド実行権限を付与
  • ワークフロー設定
  • タスクスケジューラ自動反映スクリプト作成

セルフホストランナーの導入

GitHub Actionsワークフローを独自環境で実行できるセルフホストランナーを導入します。今回は、Windowsタスクスケジューラ設定を反映する必要のある、開発環境と本番環境のサーバーに導入しました。

導入手順は、公式サイトのセルフホストランナーの追加をご確認ください。

なお、「パブリックリポジトリ」でのセルフホストランナーの利用は推奨されておりません。必ず公式の情報を確認のうえ、十分に検証したうえでご利用ください。

カスタムラベルの登録

セルフホストランナーに対してカスタムラベルを設定することで、開発環境と本番環境どちらで実行させるかを指定できます。開発環境ではdevというカスタムラベルを付け、ワークフローで以下のように設定すると開発環境のランナーで実行できます。追加手順は、公式サイトのセルフホストランナーとのラベルの利用をご確認ください。

GitHub Actions runners custom label

セルフホストランナーにschtasksコマンド実行権限を付与

セルフホストランナー導入直後はschtasksコマンドの実行権限がないため、下記手順で実行権限を付与します。

  1. セルフホストランナー登録時に作成したactions-runnerディレクトリのプロパティを確認
  2. セキュリティタブに追加されているGITHUB_ActionsRunner_hogeのユーザーを確認
  3. C:\Windows\System32\TasksGITHUB_ActionsRunner_hogeのフルアクセス権限を付与

ワークフロー設定

ワークフローの内容は以下の通りです。

  1. 特定ブランチに対するPull Requestイベントかつ、特定ファイルに変更があった場合のみ実行
  2. 追加・変更されたファイル差分を取得
  3. 反映コマンド確認用のスクリプト実行
  4. Pull Requestがマージされたら自動反映スクリプトを実行

下記の設定は、ワークフローファイルのサンプルの一部です。

name: Apply task scheduler (dev_server)

# 特定ブランチに対するPull Requestイベント、特定ファイルの変更のみ実行
on:
  pull_request:
    types: [opened, synchronize, closed]
    branches:
      - 'hoge_branch'
    paths:
      - 'hoge_path'

jobs:
  schtasks:
    # 開発環境ホストランナー
    runs-on: [self-hosted, windows, x64, dev]

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

      # git diff時の文字化け解消
      - name: Git config quotepath
        run: git config --local core.quotepath false

      # Pull Request baseブランチフェッチ
      - name: Fetch base_sha
        run: git fetch origin ${{ github.event.pull_request.base.sha }}

      # 差分ファイルリストをdiff.txtへ出力
      - name: Output diff.txt
        run: git diff ${{ github.event.pull_request.base.sha }} --diff-filter=ACMR --name-only > diff.txt

      # 反映コマンドの確認(マージ前チェック用:schtasksコマンドの出力)
      - name: Check command
        run: tasks/check.ps1

      # マージされたら、反映スクリプト実行
      - name: Apply
        if: github.event.pull_request.merged == true
        run: tasks/apply.ps1

タスクスケジューラ自動反映スクリプト作成

必要なschtasksコマンドを生成して実行する「自動反映スクリプト」はPowerShellで書きました。同リポジトリ内に反映スクリプトファイルを置き、ワークフローから実行するようにしています。反映スクリプトの処理の流れは以下の通りです。

  1. 必要なファイル差分リストの取得
  2. 反映コマンドの作成
  3. 反映コマンドの実行

以下は、実際にGitHub Actionsが実行された結果です。

GitHub Actions Result

運用について

BtoBチームではリリース可能なメンバーは少数に限定しており、リリース内容のレビューを実施する実質的な承認者をリリーサーと呼んでいます。リリーサーのみに自動反映スクリプトの実行権限を与えるため、特定ブランチへのマージ権限をリリーサーに限定しました。また、開発者はそのブランチに向けてPull Requestを作成してもらうことにしました。

リリーサーがPull Requestのレビューとマージをすることでタスクスケジューラ反映の自動化を実現しています。これにより、本番環境への反映が必ず承認者を経由し実施される安全運用となっています。

まとめ

今回の対応によって冒頭で申し上げたような計画的なタスクスケジューラ設定についてはある程度自動化できました。ただ、緊急時においては対応スピードの観点で要件を満たさないため、どうしても手作業での設定変更は残ってしまいます。ベターな対応について運用面含め検討は続きます。

また、我々のプロダクトではリリースを含め、まだまだ手作業を必要とするものが残っています。今回の取り組みで、手作業部分を解消し自動反映後の監視の仕組み強化など、本来注力したいことに対しエンジニアの労力を割くいい流れができました。

すべてを自動化することはできませんが、手作業を伴って繰り返されるタスクについて着目し、定期的に仕組み化を検討するトイル撲滅運動を継続していきます。

さいごに

ZOZOテクノロジーズでは、一緒にサービスを作り上げてくれる方を募集中です。ご興味のある方は、以下のリンクからぜひご応募ください!

tech.zozo.com

カテゴリー