はじめに
コスト削減のため、踏み台VMや開発・ステージング環境でのVMは、営業時間外は停止しておきたいという要件はよくあると思います。
GCPでは自動停止構成を組む選択肢2つあり、個人的には後述2つ目がシンプルで良いなと思ったので、メリデメとterraformの例をまとめました。
構成案
案1. Scheduler + Functionsで停止
AWSでも EventBridge + Lambda でEC2やRDSを自動停止させたりする上、ドキュメントでも紹介されており真っ先に思いつきそうな構成です。自分も最初はこの構成組んでました。
terraformで管理する場合は、下記リソースが必要です。
- Cloud Functions + Cloud Scheduler + Pub/Sub
- Functionsのソースコード
- Cloud Storage(ソースコードをアップロードする用)
案2. GCEのインスタンススケジュールで停止
なんと、GCEネイティブの機能で自動停止できます。(起動も可能)
https://cloud.google.com/compute/docs/instances/schedule-instance-start-stop?hl=ja
cron式も使えるため柔軟に設定可能です。
インスタンス スケジュールのメリデメ
-
メリット
-
構成がめちゃくちゃシンプル
案1の場合は上記の通り色々リソースが必要で、terraformのコードも長くなる。
一方、インスタンススケジュールはリソースが1つだけなのでめちゃくちゃシンプルに書ける。
また、対象インスタンスへのラベル付与も不要。
-
構成がめちゃくちゃシンプル
-
デメリット
-
厳密な時間指定不可
ドキュメントに記載があるが、スケジュール時刻から停止が最大15分遅れる。(そもそもビジネスクリティカルなGCEは自動停止させないと思うので、あまり問題にならない?) -
スケジュールの変更不可
作成したインスタンススケジュールは時刻変更できないので、一旦削除して再作成が必要。
さらに一つのGCEを複数のスケジュールに設定できない関係で、terraform applyで一気にdestroy&createしようとするとエラーが出るため、一旦手動で既存スケジュール削除してからapplyする必要があり地味に手順が煩雑。
-
厳密な時間指定不可
デメリットを許容できるようであれば、インスタンススケジュールを使うのが楽で良いかと思います。スケジュールの変更もたまにしかないと思いますし。
terraformの記述例
resource "google_compute_resource_policy" "stop_compute_engines" {
name = "stop-compute-engines"
region = var.region
description = "GCEの夜間自動停止"
instance_schedule_policy {
vm_stop_schedule {
schedule = "0 22 * * *" # 毎日夜10時に停止
}
time_zone = "Asia/Tokyo"
}
}
# 停止対象GCEへのポリシー登録
resource "google_compute_instance" "vm" {
project = var.project-name
# (中略)
resource_policies = [
google_compute_resource_policy.stop_compute_engines.id
]
}
GCEへのポリシー登録がterraformのドキュメントに書かれてなかったため、「ここは手動か〜惜しい」と思ってましたが、ちゃんとありました。(terraformいじってたら偶然発見)