Temporal Common Shared Infrastructure Module
The Temporal Common module provisions the database infrastructure required by the Temporal Workflow Engine on Google Cloud Platform. It creates Cloud SQL resources (a database user, two PostgreSQL databases, and one Secret Manager secret) and exposes outputs consumed by Temporal GKE.
Unlike most *_Common modules, Temporal Common does not produce a config output. It is a lower-level infrastructure module that manages only the Temporal-specific Cloud SQL objects and the associated database password secret.
1. Overview
Purpose: Centralise the creation of Temporal's Cloud SQL databases, the shared PostgreSQL user, and the password secret in a single module that can be safely called before the GKE deployment starts.
Architecture:
Temporal_GKE
└── Temporal_Common (this module)
Creates:
- Cloud SQL user (temporal_<prefix>)
- Cloud SQL DB (temporal_<prefix>) ← persistence
- Cloud SQL DB (temporal_<prefix>_vis) ← visibility
- Secret Manager secret (<prefix>-temporal-db-password)
Produces outputs:
db_user, db_password, db_password_secret_id,
db_name, db_visibility_name,
secret_ids, secret_values, storage_buckets, path
└── App_GKE (via Temporal_GKE)
Key characteristics:
- Both databases (
temporal_defaultandtemporal_visibility) share a single PostgreSQL user. The naming convention replaces hyphens in the resource prefix with underscores to produce a valid PostgreSQL identifier. - The module guards all Cloud SQL resource creation with
count = var.postgres_instance_name != "" ? 1 : 0. Whensql_discoveryreturns an empty instance name, the resources are skipped rather than producing a GCP API error. - The database user password is a 32-character alphanumeric string generated by
random_passwordand stored in Secret Manager. A 30-secondtime_sleepensures global replication before outputs are resolved. storage_bucketsalways returns an empty list — Temporal does not require GCS storage.
2. GCP Resources Created
| Resource | ID / Name | Purpose |
|---|---|---|
google_project_service.secretmanager | secretmanager.googleapis.com | Enables Secret Manager API |
random_password.temporal_db | (32 chars, no special chars) | Auto-generated database password |
google_sql_user.temporal | <db_name_full> on <postgres_instance> | Cloud SQL user for both Temporal databases |
google_sql_database.temporal_default | <db_name_full> | Primary persistence database (workflow state, schedules, etc.) |
google_sql_database.temporal_visibility | <db_name_full>_vis | Visibility database (workflow search and filtering) |
google_secret_manager_secret.temporal_db_password | <prefix>-temporal-db-password | Secret Manager secret container |
google_secret_manager_secret_version.temporal_db_password | (latest version) | Stores the generated database password |
time_sleep.wait_for_secrets | (30s delay) | Waits for Secret Manager replication |
Resource Naming
The database user name and database names are derived from the resource prefix with hyphens replaced by underscores:
resource_prefix = "apptemporaldemod1a2b3c"
db_name_full = "apptemporaldemod1a2b3c"
db_visibility_name_full = "apptemporaldemod1a2b3c_vis"
When resource_prefix is not set, the prefix is auto-generated as app<application_name><tenant_deployment_id><deployment_id>.
3. Outputs
| Output | Type | Description |
|---|---|---|
db_user | string | PostgreSQL username for Temporal server connections |
db_password | string (sensitive) | Raw database password |
db_password_secret_id | string | Secret Manager secret ID (resolved after 30s wait) |
db_name | string | Name of the primary persistence database |
db_visibility_name | string | Name of the visibility database |
secret_ids | map(string) | { POSTGRES_PWD = "<secret-id>" } — for Secret Manager CSI injection |
secret_values | map(string) (sensitive) | { POSTGRES_PWD = "<raw-password>" } — for direct Kubernetes Secret injection |
storage_buckets | list | Always empty — Temporal does not use GCS buckets |
path | string | Filesystem path of this module; used to reference scripts/schema-init.sh |
The secret_ids output maps the POSTGRES_PWD environment variable name to the Secret Manager secret ID. Temporal GKE passes this map directly as module_secret_env_vars to App GKE, which injects the secret value into the Temporal server pod at runtime.
4. Scripts Directory
Temporal Common ships one script in scripts/:
| File | Purpose |
|---|---|
schema-init.sh | (Available but not used in the current auto-setup deployment pattern — see §5) |
schema-init.sh uses temporal-sql-tool from the ghcr.io/temporalio/admin-tools image to:
- Initialise the default schema (
setup-schema -v 0.0, thenupdate-schema). - Initialise the visibility schema with the same pattern.
This script is retained for use-cases where manual or external schema management is preferred. In the default Temporal GKE deployment, schema initialisation is handled automatically by the temporalio/auto-setup image at startup.
5. Relationship to Temporal GKE
Temporal GKE calls Temporal Common after running sql_discovery to locate the Services GCP-managed Cloud SQL instance:
module "temporal_common" {
source = "../Temporal_Common"
project_id = var.project_id
deployment_id = local.random_id
tenant_deployment_id = var.tenant_deployment_id
resource_prefix = local.resource_prefix
resource_labels = var.resource_labels
application_name = var.application_name
postgres_instance_name = module.sql_discovery.db_instance_name
}
The resource_prefix is passed explicitly so that all Secret Manager secrets align with the resource names produced by App GKE. The outputs are then consumed as:
module_secret_env_vars = module.temporal_common.secret_ids
module_storage_buckets = module.temporal_common.storage_buckets
environment_variables = {
DBNAME = module.temporal_common.db_name
VISIBILITY_DBNAME = module.temporal_common.db_visibility_name
POSTGRES_USER = module.temporal_common.db_user
# ...
}
6. Input Variables
Temporal Common is not intended to be called directly by end users. All variables are passed from Temporal GKE.
| Variable | Type | Default | Description |
|---|---|---|---|
project_id | string | (required) | GCP project ID. |
postgres_instance_name | string | "" | Cloud SQL PostgreSQL instance name from sql_discovery. Empty string is valid in standalone mode — the count guards in main.tf skip SQL resource creation when no instance is provided. |
deployment_id | string | "" | Deployment identifier suffix for auto-generated prefixes. |
tenant_deployment_id | string | "demo" | Tenant identifier for resource naming. |
resource_prefix | string | "" | When set, overrides the auto-generated prefix. Pass local.resource_prefix from the calling module to align names. |
resource_labels | map(string) | {} | Labels applied to all created resources. |
application_name | string | "temporal" | Used in auto-generated prefix when resource_prefix is empty. |
7. Platform-Specific Notes
Temporal Commonis GKE-only. There is noTemporal CloudRunmodule because Temporal's gRPC-based architecture and long-lived workflow execution model are not suitable for Cloud Run's stateless, request-scoped model.- The visibility database (
_vissuffix) is used by the standard PostgreSQL visibility store. Whenenable_elasticsearch = trueinTemporal GKE, Elasticsearch takes over as the advanced visibility store, but the_visdatabase continues to exist in Cloud SQL.