👟
定期実行ジョブを Cloud Scheduler + Cloud Run Jobs で作る
概要
定期実行ジョブを実現する際には、タイトルとは別の選択肢として Cloud Run Function を利用する方法があります。しかし、Cloud Run Functions では、Cloud Scheduler と Cloud Run Functions の間に Cloud PubSub を挟まなければなりません。
Cloud Run Jobs を利用すればシンプルな構成で定期実行ジョブを実現できます。ただし、完全な上位互換ではないことに注意です。
terraformで構築する
variable "region" {
type = string
}
variable "project_id" {
type = string
}
Cloud Run Jobs
- 今回は
us-docker.pkg.dev/cloudrun/container/job:latest
を実行するだけのジョブです。- Cloud Scheduler でコマンド引数を上書きしていますが、このイメージでは書き換えたところで出力結果は変わりません。
- ジョブの制限に
cpu = "1000m"
,memory = "512Mi"
を指定していますが、現在はこれが最小値となります。[1]- Cloud Run Functions で設定できる最小値は
cpu = "83m"
,memory = "128Mi"
。[2]
- Cloud Run Functions で設定できる最小値は
resource "google_service_account" "example_job" {
account_id = "example-job"
display_name = "example-job"
description = "Service Account for Cloud Run Jobs"
}
# ジョブを実行するにあたって必要な権限を付与する
#resource "google_project_iam_member" "cloudsql_admin" {
# project = var.project_id
# role = "roles/cloudsql.admin"
# member = google_service_account.example_job.member
#}
resource "google_cloud_run_v2_job" "example_job" {
name = "example-job"
location = var.region
template {
parallelism = 1
task_count = 1
template {
max_retries = 1
timeout = "60s"
service_account = google_service_account.example_job.email
containers {
image = "us-docker.pkg.dev/cloudrun/container/job:latest"
env {
name = "GOOGLE_CLOUD_PROJECT"
value = var.project_id
}
resources {
limits = {
cpu = "1000m"
memory = "512Mi"
}
}
}
}
}
lifecycle {
ignore_changes = [
client,
template[0].template[0].containers[0].name,
template[0].template[0].containers[0].image,
]
}
}
Cloud Scheduler
- 単にジョブを実行するだけでなく、いろいろオーバライドしてジョブを実行することができます。
resource "google_service_account" "example_scheduler" {
account_id = "example-scheduler"
display_name = "example-scheduler"
description = "Service Account for Cloud Scheduler"
}
resource "google_project_iam_member" "run_jobs_executor_with_overrides" {
project = var.project_id
role = "roles/run.jobsExecutorWithOverrides"
member = google_service_account.example_scheduler.member
}
resource "google_cloud_scheduler_job" "scheduler_1" {
name = "scheduler-1"
description = "Scheduler 1"
schedule = "0 8 * * 1-5"
time_zone = "Asia/Tokyo"
attempt_deadline = "60s"
retry_config {
retry_count = 1
}
http_target {
uri = "https://${google_cloud_run_v2_job.example_job.location}-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/${var.project_id}/jobs/${google_cloud_run_v2_job.example_job.name}:run"
http_method = "POST"
headers = {
"Content-Type" = "application/json"
}
body = base64encode(jsonencode(
{
"overrides" : {
"containerOverrides" : [
{
"args" : ["scheduler_1"]
}
]
}
}
))
oauth_token {
service_account_email = google_service_account.example_scheduler.email
}
}
}
resource "google_cloud_scheduler_job" "scheduler_2" {
name = "scheduler-2"
description = "Scheduler 2"
schedule = "0 20 * * 1-5"
time_zone = "Asia/Tokyo"
attempt_deadline = "60s"
retry_config {
retry_count = 1
}
http_target {
uri = "https://${google_cloud_run_v2_job.example_job.location}-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/${var.project_id}/jobs/${google_cloud_run_v2_job.example_job.name}:run"
http_method = "POST"
headers = {
"Content-Type" = "application/json"
}
body = base64encode(jsonencode(
{
"overrides" : {
"containerOverrides" : [
{
"args" : ["scheduler_2"]
}
]
}
}
))
oauth_token {
service_account_email = google_service_account.example_scheduler.email
}
}
}
Discussion