Cloud Run Jobs allows to run containers as jobs, i.e. as short-lived tasks that spin up a container every time that they’re invoked. As with every container you can use environment variables to pass context. But what if we want to pass arguments to the container?
In this case, the GCP API specifies containerOverrides. When using terraform, we can pass those with the google_cloud_scheduler_job
resource by customizing the http_target
body like so:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
resource "google_cloud_scheduler_job" "job-with-args-override" {
name = "job-with-args"
description = "Cloud Run job with args"
schedule = "*/5 * * * *" # every 5 minutes
attempt_deadline = "20s"
region = var.gcp_region
project = var.gcp_project_id
retry_config {
retry_count = 3
}
http_target {
http_method = "POST"
uri = "https://${google_cloud_run_v2_job.job.location}-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/${var.gcp_project_id}/jobs/${google_cloud_run_v2_job.job.name}:run"
body = base64encode("{\"overrides\":{\"containerOverrides\":[{\"args\":[\"${var.job_args}\"],\"clearArgs\":\"FALSE\"}]}}")
oauth_token {
service_account_email = google_service_account.service-account[0].email
scope = "https://www.googleapis.com/auth/cloud-platform"
}
}
depends_on = [google_cloud_run_v2_job.job, google_cloud_run_v2_job_iam_binding.job-binding]
}
|
In order for this to work though, we need the run.jobs.runWithOverrides
permission. If you don’t want to create a custom role with this permission, you can use the run.developer
permission, which is quite powerful, so give it to a custom service account:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
resource "google_service_account" "service-account" {
account_id = "job-service-account"
description = "Service account for job"
}
resource "google_cloud_run_v2_job_iam_binding" "job-binding" {
for_each = toset(["run.invoker", "run.developer"]) // run.developer grants run.jobs.runWithOverrides
name = google_cloud_run_v2_job.job.name
location = var.gcp_region
project = var.gcp_project_id
role = "roles/${each.value}"
members = [
"serviceAccount:${google_service_account.service-account.email}"
]
}
resource "google_cloud_run_v2_job" "job" {
// the job definition
}
|
Et voilĂ , the job will now run with the arguments provided as input. I hope this can help someone.