営業時間外にインスタンスを止めるワークフローの書き方(on.schedule の if 制御) [GitHub Actions]
概要
営業時間外にインスタンスを止めたいときなどに on.schedule
を使うと思いますが開始と停止でワークフローを分けるのも不便なので 1 つのワークフローに書く方法の紹介です。
ワークフロー
まずは全体のワークフローです。
name: Schedule
on:
schedule:
- cron: '0 1 * * 1-5' # 10:00 JST
- cron: '0 10 * * 1-5' # 19:00 JST
workflow_dispatch:
inputs:
job:
description: 'Select job'
required: true
type: choice
options:
- ''
- start
- stop
jobs:
start:
if: github.event.schedule == '0 1 * * 1-5' || github.event.inputs.job == 'start'
runs-on: ubuntu-20.04
timeout-minutes: 5
steps:
- name: 開始コマンド
run: aws ec2 start-instances --instance-ids <instance-1> <instance-2> ...
stop:
if: github.event.schedule == '0 10 * * 1-5' || github.event.inputs.job == 'stop'
runs-on: ubuntu-20.04
timeout-minutes: 5
steps:
- name: 停止コマンド
run: aws ec2 stop-instances --instance-ids <instance-1> <instance-2> ...
on.schedule
時刻の指定は cron 形式で書くことができます。
後述しますがあくまで cron 形式であって cron そのものではないことに注意してください。
UTC なので 9 時間減らした時間を記載します。
右端は曜日なので月曜~金曜を示す 1-5
を指定します。
8 時始業の会社だと 0 23 * * 0-4
になるでしょうか。
実際は起動時間や残業の兼ね合いで営業時間の前後に少し余裕を持った方がいいと思います。
jobs
start
と stop
のジョブを定義します。
それぞれの if
で github.event.schedule
の値を見ることで今どちらの時間で実行されているか判断しています。
cron の文字列をそのまま書かなければいけないのがやや冗長ですが Re-run を考えると現在時刻を date
等で取得して判定するよりはいいのかなと思います。
視覚的にもどちらが実行されたか分かりやすいです。
開始や停止のコマンドはお使いのプラットフォームに合わせてください。
GitHub ホストランナーの場合は OIDC などで認証も必要です。
schedule を使用する際の注意点
cron ではないので cron の代わりにしようとすると嵌ります。
営業時間に合わせてインスタンスを開始/停止するくらいなら問題にならない項目もあると思いますが、一般的に気を付けた方がいい点について記載しておきます。
遅延
GitHub ホストランナーの実行タイミングは混雑具合に依存するのでキリのいい時間など混み合う時間帯は 1 時間以上遅延することもざらです。
セルフホストランナーならほとんど遅延しないと思われますが、GitHub 側でトリガーされてランナーで実際にジョブが開始するまでに少し時間がかかるので正確な時刻に起動したい場合は避けた方がいいでしょう。
実行間隔
cron だと 1 分間隔ですが schedule では最短の間隔は 5 分ごとに 1 回です。
時間経過による停止
リポジトリに 60 日以上アクティビティがないと schedule ワークフローは停止されます。
コミットを足せば回避はできますが、仕様が変わるかもしれないので死活監視に使用するのは絶対にやめましょう。
on.workflow_dispatch
トラブルや祝日など手動で実行したいときもあると思います。
ジョブを選択して実行できるようにしておきましょう。
本当は祝日も自動判定した方がいいとは思いますがここでは割愛します。
空文字列をデフォルト値にしておくと意図せぬ実行や無選択での実行を防げます。
空文字列を選択したときもこのエラーになります。
GitHub Enterprise Server (GHES) をお使いの方へ。
type: choice
は GHES 3.4 以降で使用できます。
Discussion