FAQ | This is a LIVE service | Changelog

Skip to content
Snippets Groups Projects
Rich Wareham's avatar
Dr Rich Wareham authored
It is more convenient to set non-secret information via environment
variables. Expose this functionality.
a728822a
History

Scheduled script run within Google Cloud

This terraform module configures a single-file Python script to be run regularly in Google Cloud using a cron-style scheduling syntax. It supports single-file scripts with requirements specified via a requirements.txt-style list of packages.

The scripts may have secrets passed to them by a Google Secret Manager secret created for this script.

A dedicated service account is created for the script which represents the identity which the script runs as within Google Cloud.

Monitoring is configured with alerts sent if the number of successful invocations of the script within a configurable time period falls below a given threshold.

This module is not suitable for multi-file scripts or scripts which need to be passed parameters which differ from run-to-run.

Versioning

The master branch contains the tip of development. Releases are made automatically using release automation.

Required APIs and services

The following APIs must be enabled to use this module:

  • appengine.googleapis.com
  • cloudbuild.googleapis.com
  • cloudfunctions.googleapis.com
  • cloudscheduler.googleapis.com
  • secretmanager.googleapis.com

In addition there must be an app engine application configured for your project. This is a requirement to configure Cloud Scheduler jobs. You can ensure an app engine application is configured by means of the google_app_engine_application resource:

resource "google_app_engine_application" "app" {
  location_id = "europe-west2"
}

Monitoring

Cloud Monitoring resources are associated with a Monitoring Workspace which may be hosted in a project which differs from the project containing other resources. The google.monitoring provider is used when creating Monitoring resources and it should be a provider configured with credentials able to create monitoring resources.

Implementation

The script is implemented as a Cloud Function and so it should conform to the Cloud Function Python runtime. The entrypoint to the function can be customised but the default is to use main.

A dedicated Cloud Storage bucket is created to store the source code in. This is created with a random name.

Example

A minimal example of running a script:

module "scheduledscript" {
  source = "..."

  # Name used to form resource names and human readable description.
  name        = "my-script"
  description = "Log a message."

  # Project and region to create resources in.
  project = "..."
  region  = "europe-west2"

  # A directory which can be used to store local files which are not checked in
  # to source control.
  local_files_dir = "/terraform_data/local"

  # The script itself.
  script = <<-EOL
      import logging

      LOG = logging.getLogger()
      logging.basicConfig(level=logging.INFO)

      def main(request):
          LOG.info('I ran!')
          return '{ "status": "ok" }', {'Content-Type': 'application/json'}
  EOL

  # Cron-style schedule for running the job.
  schedule = "*/5 * * * *"

  # Alerting threshold. Specify the minimum number of successful invocations and
  # the period over which this should be measured.
  alert_success_threshold = 5
  alert_success_period    = "3600s"  # == 1hr

  # Email addresses to receive alerts if invocations are failing.
  alert_email_addresses = ["someone@example.com"]

  # Use a separate provider with rights over the Cloud Monitoring workspace for
  # monitoring resource management.
  providers = {
    google.monitoring = google.monitoring
  }
}

See the variables.tf file for all variables.

Additional Python package requirements can be specified in the requirements variable which should be a list of Python packages, one per line, as used by requirements.txt files.

A custom entry point for the script can be configured via the entry_point variable.

Configurations can be passed to the application via the secret_configuration variable. This should be a string which is placed in a Google Secret Manager secret and is made available to the script. The secret is passed as a URL of the form sm://[PROJECT]/[SECRET]#[VERSION] in the SECRET_CONFIGURATION_SOURCE environment variable.

Requirements

Name Version
terraform >= 0.14
archive >= 2.2.0
google > 3.60
random >= 3.1

Inputs

Name Description Type Default Required
alert_email_addresses DEPRECATED. An optional list of email addresses which should recieve alerts.
This creates a separate Notification Channel for every email address in the list which is often not desired.
Consider creating a Notification Channel separately and passing its ID to the alert_notification_channels
variable instead.
list(string) [] no
alert_enabled Flag indicating if alerting should be enabled for this script. bool true no
alert_failure_period Period over which 'alert_failure_threshold' is used. string "3600s" no
alert_failure_threshold The number of failures which will trigger a failure alert within 'alert_success_period'. number 1 no
alert_notification_channels A list of notification channel IDs to send alerts to. The format for the channel IDs should
be as follows.

[
"projects/[PROJECT_ID]/notificationChannels/[CHANNEL_ID]"
]
list(string) [] no
alert_success_period Period over which 'alert_success_threshold' is used. Default: "3600s" which
is one hour.
string "3600s" no
alert_success_threshold The minimum number of successes within 'alert_success_period' below which an
alert is fired.
number 5 no
available_memory_mb Maxiumum memory available to the script in MiB. Default: 128 MiB. number 128 no
description Longer human-friendly description of the script string "" no
enable_versioning The bucket's versioning configuration.
While set to true, versioning is fully enabled for the bucket.
bool true no
entry_point Entrypoint to script. Defaults to 'main'. string "main" no
environment_variables Additional environment variables to set on the function. map(string) {} no
failure_alert_enabled Flag indicating if failure alerts should be enabled for this script, separate
to the default alert which is raised if a successful invocation has not been
detected within the alerting period.
bool false no
keep_versions The number of file versions to keep if enable_versioning is set to true.
Default: 1
number 1 no
local_files_dir A local directory where files may be created which persist between runs but
which are not checked into source control.
string n/a yes
monitoring_project Project to create Cloud Monitoring resources in. Defaults to the project
used by the google.monitoring provider if not specified.
string "" no
name Short resource-friendly name for the script. string n/a yes
project Project to create resources in. Defaults to provider project. string "" no
region Region to create resources in. Defaults to London, UK. string "europe-west2" no
requirements requirements.txt-style file containing script dependencies string "" no
runtime Python runtime for script. See
https://cloud.google.com/functions/docs/concepts/exec. Default: "python38".
string "python38" no
schedule Schedule for script running. Defaults to twice per hour. See
https://cloud.google.com/scheduler/docs/configuring/cron-job-schedules for a
description of the format.
string "*/30 * * * *" no
script The script to run. This should match the requirements for the Cloud Function
Python runtime. The entrypoint defaults to "main" unless overridden via the
"entry_point" variable.
string "def main(request):\n return 'ok'\n" no
secret_configuration Configuration which is placed in a Google Secret which can be read by the
service account identity which the script runs as. A path to the secret of
the form "sm://[PROJECT]/[SECRET]#[VERSION]" appears as the
"SECRET_CONFIGURATION_SOURCE" environment variable.
string "" no
service_account Optional existing service account to run script as. If one is not provided
then one is created. Either way, the relevant permissions will be given to
the account.

Note: one needs to pass the actual service account object here which will be
mirrored to the service_account output.
object({
account_id = string
display_name = optional(string)
description = optional(string)
disabled = optional(bool)
project = optional(string)
id = string
email = string
name = string
unique_id = string
member = string
})
null no
time_zone Time zone which "schedule" should be evaluated in. Default: 'Europe/London'. string "Europe/London" no
timeout Maximum time, in seconds, that a script can take to execute. Invocations
which take longer than this fail. Default: 120 seconds.
number 120 no

Outputs

Name Description
function google_cloudfunctions2_function resource for the Cloud Function created to
run the script.
job google_cloud_scheduler_job resource for the Scheduled Job which runs the script.
service_account google_service_account resource for the Service Account which the script
runs as.