Introduction
Google Cloud Scheduler provides a fully managed cron-like service that executes jobs on a recurring schedule without requiring you to maintain a virtual machine or container for cron execution. When that scheduling capability is defined with Terraform, infrastructure as code, the jobs become version controlled, peer reviewable, and reproducible across environments. Terraform is an open-source tool that lets you provision and manage infrastructure by specifying the desired state in configuration files. These files can be treated as code and stored in version control systems like GitHub. This article covers how to provision Cloud Scheduler jobs with Terraform for direct HTTP targets, Pub/Sub targets, App Engine targets, and the common pattern of driving Batch jobs via Scheduler. The quickstart path shows how to use Terraform to create a Cloud Scheduler cron job, set a recurring schedule for the job, specify a Pub/Sub topic as the job target, run the job, and verify that the job has run successfully. Cloud Scheduler has a free tier and running this quickstart should not result in any costs. For more information, see Pricing.
Prerequisites and Project Structure
Before you begin, security constraints defined by your organization might prevent you from completing the following steps. A typical setup requires the Google Cloud SDK installed and configured, Terraform installed version 1.0.0 or later, and a GCP project with billing enabled.
A modular project layout keeps Scheduler definitions portable:
.
├── main.tf # Main Terraform configuration file
├── variables.tf # Variable definitions
├── outputs.tf # Output definitions
├── terraform.tfvars # Variable values
└── modules/
└── scheduler/
├── main.tf # Cloud Scheduler specific configurations
├── variables.tf # Module variables
├── jobs.tf # Job configurations
└── outputs.tf # Module outputs
The provider configuration pins the Google provider and passes project and region from variables.
```hcl
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 4.0"
}
}
}
provider "google" {
project = var.project_id
region = var.region
}
```
An alternative setup for newer modules uses provider version ~> 5.0:
```hcl
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 5.0"
}
}
}
provider "google" {
project = var.project_id
region = var.region
}
```
Variables are defined explicitly:
```hcl
variable "project_id" {
description = "The ID of the GCP project"
type = string
}
variable "region" {
description = "The region to deploy resources to"
type = string
default = "us-central1"
}
```
Core Scheduler Resource Model
The central resource is google_cloud_scheduler_job. Cloud Scheduler uses standard unix-cron format with 5 fields.
| Field | Range | Special Characters |
|---|---|---|
| Minute | 0-59 | , - * / |
| Hour | 0-23 | , - * / |
| Day of Month | 1-31 | , - * / |
| Month | 1-12 or JAN-DEC | , - * / |
| Day of Week | 0-7 or SUN-SAT | , - * / |
If you do not set time_zone, it defaults to UTC. Be explicit about the timezone, especially for jobs that need to run at specific business hours.
A minimal HTTP job example shows the pattern used in practice:
```hcl
resource "googlecloudschedulerjob" "httpjob" {
name = "http-job"
description = "HTTP job to trigger an endpoint"
schedule = "*/10 * * * *"
timezone = "America/NewYork"
attempt_deadline = "320s"
http_target {
uri = ...
}
}
```
The same resource can be extended with retry configuration for production workloads:
```hcl
resource "googlecloudschedulerjob" "hourlyreport" {
name = "hourly-report-job"
description = "Triggers the report generation endpoint every hour"
schedule = "0 * * * *"
timezone = "America/NewYork"
region = var.region
retryconfig {
retrycount = 3
maxretryduration = "300s"
minbackoffduration = "5s"
maxbackoffduration = "60s"
max_doublings = 3
}
httptarget {
httpmethod = "POST"
uri = "https://your-service-abc123-uc.a.run.app/api/reports/generate"
body = ...
}
}
```
HTTP Target Jobs and Authentication
The most common pattern is triggering an HTTP endpoint on a schedule. The three target types, HTTP, Pub/Sub, App Engine, cover most scheduling needs.
For HTTP targets, authentication should use OIDC tokens. Never use API keys or hardcoded tokens in the scheduler configuration. OIDC tokens are automatically rotated and scoped to the service account.
A service account is typically created for the scheduler:
hcl
resource "google_service_account" "scheduler" {
account_id = "cloud-scheduler-sa"
display_name = "Cloud Scheduler Service Account"
}
The job then references the service account for OIDC authentication to the target. Keep the body payload small. Cloud Scheduler has a 1MB limit for HTTP request bodies. For large payloads, have the scheduler trigger a job that reads the actual data from Cloud Storage or a database.
Deployment steps for a simple HTTP project are:
- Authenticate and Select Project:
gcloud auth application-default logingcloud config set project your-project-id
- Configure Variables: Create a terraform.tfvars file based on the example:
- projectid = "your-project-id"
- region = "us-central1"
- jobname = "my-scheduler-job"
- schedule = "0 */3 * * *"
- target_uri = "https://your-cloud-run-service-uc.a.run.app"
- Deploy:
terraform initterraform apply
Outputs from the apply include Job Name, Schedule, and Target.
Pub/Sub and Fan-Out Patterns
Use Pub/Sub for fan-out patterns. If a scheduled event needs to trigger multiple actions, publish to a Pub/Sub topic and have multiple subscribers handle different aspects.
The quickstart shows specifying a Pub/Sub topic as the job target. Terraform can create the topic and the scheduler job together, ensuring the target exists before the job is created.
Batch Job Orchestration with Scheduler
Although Terraform doesn't have resources for Batch, this tutorial shows how you can use Terraform to create Batch jobs. Specifically, you can use Terraform to schedule and run a Cloud Scheduler cron job that targets the Batch API to create and run Batch jobs.
Objectives for this pattern are:
- Create a Terraform directory and a configuration file that defines a Cloud Scheduler cron job that creates Batch jobs
- Deploy the Terraform configuration to run the cron job
- Verify that the cron job creates Batch jobs
- Update the Terraform configuration to pause the cron job so that it stops creating Batch jobs
This tutorial is intended for Batch users who already manage infrastructure with Terraform and want to incorporate Batch jobs into Terraform. Cloud Scheduler is a Google Cloud service that allows you to automatically schedule cron jobs and supports Terraform.
Costs to be aware of include billable components of Google Cloud used in this document. When you finish the tasks described in this document, you can avoid continued billing by deleting the resources that you created.
Retry, Monitoring and Operational Best Practices
Set appropriate retry configurations. Not all jobs should be retried the same way. A billing job might need many retries with long backoff. A cache-warming job might not need retries at all.
The retry_config block controls behavior:
- retry_count
- maxretryduration
- minbackoffduration
- maxbackoffduration
- max_doublings
Monitor job execution. Cloud Scheduler logs job attempts in Cloud Logging. Set up alerts for failed executions, especially for critical jobs like billing or data pipelines.
Think of Cloud Scheduler as a reliable, managed alternative to running cron on a VM - except you do not have to worry about the VM going down and missing a scheduled run.
Example Module Composition
A complete module often defines provider, service account, scheduler job, and outputs:
```hcl
resource "googlecloudschedulerjob" "hourlyreport" {
name = var.jobname
description = var.description
schedule = var.schedule
timezone = var.time_zone
region = var.region
httptarget {
httpmethod = var.httpmethod
uri = var.targeturi
oidctoken {
serviceaccountemail = googleservice_account.scheduler.email
audience = var.audience
}
}
}
```
Schedule is configurable cron expression with default every 3 hours. Target is HTTP/HTTPS endpoint with OIDC authentication support. Time Zone is configurable with default UTC.
Comparison of Common Patterns
| Pattern | Target | Typical Use Case | Authentication |
|---|---|---|---|
| HTTP | Cloud Run / Cloud Functions endpoint | Trigger API every N minutes | OIDC service account |
| Pub/Sub | Pub/Sub topic | Fan-out to multiple subscribers | None, IAM on topic |
| App Engine | App Engine service | Legacy app warm-up | IAM |
| Batch via API | HTTP to Cloud Run proxy that calls Batch API | Schedule Batch jobs without native Terraform resource | OIDC |
Conclusion
Cloud Scheduler with Terraform gives you reliable, managed cron jobs without the operational overhead of maintaining a scheduler infrastructure. The three target types, HTTP, Pub/Sub, App Engine, cover most scheduling needs, and the retry configuration ensures jobs eventually complete even when transient failures occur.
By defining your scheduled jobs as Terraform code, you get version control, code review, and reproducibility for your scheduled workloads. Provider version pinning, explicit time_zone settings, OIDC-based authentication, and bounded retry policies together produce production-ready schedules that are auditable and safe to change.
For processing the work that Cloud Scheduler triggers, see guides on creating Cloud Tasks queues with Terraform. Keep payloads under 1MB, monitor executions in Cloud Logging, and delete resources when finished to avoid continued billing.