From 77d168a8ed670aa16198d6a6cbe7a60768d70694 Mon Sep 17 00:00:00 2001 From: "Lenny (Temporal)" Date: Wed, 9 Sep 2026 16:24:13 -0700 Subject: [PATCH 01/12] Document Cloud Run OTel and Worker identity setup --- .../workers/serverless-workers/cloud-run.mdx | 105 +++++++++++- .../workers/serverless-workers/cloud-run.mdx | 123 +++++++++++++- .../workers/serverless-workers/cloud-run.mdx | 152 +++++++++++++++++- .../workers/serverless-workers/cloud-run.mdx | 121 +++++++++++++- .../serverless-workers/cloud-run/index.mdx | 39 ++--- 5 files changed, 505 insertions(+), 35 deletions(-) diff --git a/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx b/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx index 465e5982af..b7114211de 100644 --- a/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx @@ -23,7 +23,7 @@ import { ReleaseNoteHeader } from '@site/src/components'; On a [GCP Cloud Run worker pool](https://cloud.google.com/run/docs/resource-model#worker-pools), you run a standard long-lived Temporal Worker. Register Workflows and Activities the same way you would with any other .NET Worker, and Temporal Cloud scales the pool up and down as work arrives and drains. -A Cloud Run Worker needs no Cloud Run-specific package. +A Cloud Run Worker needs no Cloud Run-specific runtime or handler. The one addition to a standard Worker is [Worker Versioning](/worker-versioning), which is required for Serverless Workers. For the end-to-end deployment guide covering the Worker Pool, IAM, and compute configuration, see [Deploy a Serverless Worker on GCP Cloud Run](/production-deployment/worker-deployments/serverless-workers/cloud-run). @@ -135,7 +135,104 @@ public static string Process(IReadOnlyList items) For how scale-in decisions are made, see [Serverless Workers on GCP Cloud Run](/serverless-workers/cloud-run#lifecycle). -## Add observability {/* #add-observability */} +## Configure OpenTelemetry {/* #opentelemetry */} + +Configure the .NET OpenTelemetry exporter and the Temporal Runtime to send telemetry by OTLP to `localhost:4317`. The following code sample configures the Worker only. You must separately run an OTLP-compatible receiver at that address. In a Cloud Run Worker Pool, run that receiver as a sidecar. + + +[src/OpenTelemetry/CoreSdkForwarding/Program.cs](https://github.com/temporalio/samples-dotnet/blob/main/src/OpenTelemetry/CoreSdkForwarding/Program.cs) +```cs +var resourceBuilder = ResourceBuilder. + CreateDefault(). + AddService("TemporalioSamples.OpenTelemetry", serviceInstanceId: instanceId); + +using var tracerProvider = Sdk. + CreateTracerProviderBuilder(). + SetResourceBuilder(resourceBuilder). + AddSource(TracingInterceptor.ClientSource.Name, TracingInterceptor.WorkflowsSource.Name, TracingInterceptor.ActivitiesSource.Name). + AddOtlpExporter(). + Build(); + +// Shared by the client and by Core SDK log forwarding below. The OpenTelemetry provider exports +// logs to the dashboard alongside the traces and metrics. +using var loggerFactory = LoggerFactory.Create(builder => + builder. + AddSimpleConsole(options => options.TimestampFormat = "[HH:mm:ss] "). + AddOpenTelemetry(options => + { + options.SetResourceBuilder(resourceBuilder); + options.IncludeFormattedMessage = true; + options.IncludeScopes = true; + options.AddOtlpExporter(); + }). + SetMinimumLevel(LogLevel.Information)); + +// Create a client to localhost on default namespace +var connectOptions = ClientEnvConfig.LoadClientConnectOptions(); +connectOptions.TargetHost ??= "localhost:7233"; +connectOptions.LoggerFactory = loggerFactory; +connectOptions.Interceptors = new[] { new TracingInterceptor() }; +connectOptions.Runtime = new TemporalRuntime(new TemporalRuntimeOptions() +{ + Telemetry = new TelemetryOptions() + { + Metrics = new MetricsOptions() + { + OpenTelemetry = new OpenTelemetryOptions() + { + Url = new Uri("http://localhost:4317"), + }, + }, + Logging = new LoggingOptions() + { + // Core SDK logs default to WARN; lowered here so there is more to see. + Filter = new TelemetryFilterOptions(core: TelemetryFilterOptions.Level.Info), + + // The Core SDK writes its logs to the console itself unless Forwarding is set, in + // which case they go to this ILogger instead. + Forwarding = new LogForwardingOptions(loggerFactory.CreateLogger("Temporalio.Core")), + }, + }, +}); +var client = await TemporalClient.ConnectAsync(connectOptions); +``` + + +The [OpenTelemetry sample](https://github.com/temporalio/samples-dotnet/tree/main/src/OpenTelemetry) shows the tracing, metrics, and log-export configuration. Its Docker Compose file runs the .NET Aspire Dashboard locally and exposes its OTLP endpoint on port `4317`; it does not define a Cloud Run sidecar. Configure your Cloud Run sidecar to export the received telemetry to your backend. + +## Set a Worker identity {/* #worker-identity */} + +Use `WorkerIdPlugin` to identify each Worker instance as `@`. The plugin reads Cloud Run environment variables and instance metadata when the Client connects, then Workers created from that Client inherit the identity. + + +[src/Gcp/CloudRun/WorkerId/Program.cs](https://github.com/temporalio/samples-dotnet/blob/main/src/Gcp/CloudRun/WorkerId/Program.cs) +```cs +var address = GetEnvironmentVariable("TEMPORAL_ADDRESS") ?? "localhost:7233"; +var temporalNamespace = GetEnvironmentVariable("TEMPORAL_NAMESPACE") ?? "default"; +var taskQueue = GetEnvironmentVariable("TEMPORAL_TASK_QUEUE") ?? "cloud-run-worker-sample"; + +using var loggerFactory = LoggerFactory.Create(builder => builder. + AddSimpleConsole(options => options.TimestampFormat = "[HH:mm:ss] "). + SetMinimumLevel(LogLevel.Information)); +var logger = loggerFactory.CreateLogger("CloudRunWorkerId"); + +// Register the Cloud Run plugin once on the client. At connect time it reads the Cloud Run instance +// id from the metadata server, and the worker pool / service name and revision from the environment, +// then sets the client Identity to the worker identity "{instanceId}@{revision}" (unless one was +// already configured). Every worker created from this client inherits that identity. The plugin only +// sets the worker identity; it does not configure anything else. +// +// NOTE: this requires the process to be running on a Cloud Run worker pool or service. Running it +// elsewhere throws at connect time because the metadata server is unreachable. +var clientOptions = new TemporalClientConnectOptions(address) +{ + Namespace = temporalNamespace, + LoggerFactory = loggerFactory, + Plugins = new[] { new WorkerIdPlugin() }, +}; + +var client = await TemporalClient.ConnectAsync(clientOptions); +``` + -A Cloud Run Worker emits the same traces and metrics as a Worker anywhere else. -For how to configure metrics export and OpenTelemetry tracing interceptors, see [Observability - .NET SDK](/develop/dotnet/platform/observability) and the [SDK metrics reference](/references/sdk-metrics). +The plugin requires the Cloud Run metadata server, so it fails when the Worker runs outside Cloud Run. For a complete example, see the [.NET Cloud Run Worker Id sample](https://github.com/temporalio/samples-dotnet/pull/219). diff --git a/docs/develop/go/workers/serverless-workers/cloud-run.mdx b/docs/develop/go/workers/serverless-workers/cloud-run.mdx index 101b6469ae..34e1f705c3 100644 --- a/docs/develop/go/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/go/workers/serverless-workers/cloud-run.mdx @@ -23,7 +23,7 @@ import { ReleaseNoteHeader } from '@site/src/components'; On a [GCP Cloud Run worker pool](https://cloud.google.com/run/docs/resource-model#worker-pools), you run a standard long-lived Temporal Worker. Register Workflows and Activities the same way you would with any other Go Worker, and Temporal Cloud scales the pool up and down as work arrives and drains. -A Cloud Run Worker needs no Cloud Run-specific package. +A Cloud Run Worker needs no Cloud Run-specific runtime or handler. The one addition to a standard Worker is [Worker Versioning](/worker-versioning), which is required for Serverless Workers. For the end-to-end deployment guide covering the Worker Pool, IAM, and compute configuration, see [Deploy a Serverless Worker on GCP Cloud Run](/production-deployment/worker-deployments/serverless-workers/cloud-run). @@ -112,7 +112,122 @@ func MyActivity(ctx context.Context, input MyInput) (string, error) { For how scale-in decisions are made, see [Serverless Workers on GCP Cloud Run](/serverless-workers/cloud-run#lifecycle). -## Add observability {/* #add-observability */} +## Configure OpenTelemetry {/* #opentelemetry */} -A Cloud Run Worker emits the same traces and metrics as a Worker anywhere else. -For how to configure metrics export and OpenTelemetry tracing interceptors, see [Observability - Go SDK](/develop/go/platform/observability) and the [SDK metrics reference](/references/sdk-metrics). +Run an OpenTelemetry Collector as a sidecar in the Worker Pool. The Cloud Run OpenTelemetry plugin exports metrics and traces by OTLP gRPC to the Collector at `localhost:4317`. By default, it derives the service name from `OTEL_SERVICE_NAME`, `CLOUD_RUN_WORKER_POOL`, or `K_SERVICE`. + +Create the plugin before connecting, then add it to the Client options. Client plugins that implement `worker.Plugin` also apply to Workers created from that Client: + + +[gcp/cloudrun/otel/worker/main.go](https://github.com/temporalio/samples-go/blob/gcp-cloud-run-otel/gcp/cloudrun/otel/worker/main.go) +```go +// ... + otelPlugin, err := otel.NewPlugin(ctx, otel.PluginOptions{}) + if err != nil { + log.Fatalln("Unable to create OpenTelemetry plugin", err) + } + + // Load the Temporal connection from the environment (see temporal.toml or the + // TEMPORAL_* environment variables) and install the plugin. Client plugins + // that also implement worker.Plugin are applied to workers automatically. + clientOptions, err := envconfig.LoadDefaultClientOptions() + if err != nil { + log.Fatalln("Unable to load Temporal client options", err) + } + clientOptions.Plugins = append(clientOptions.Plugins, otelPlugin) + + c, err := client.Dial(clientOptions) + if err != nil { + log.Fatalln("Unable to create Temporal client", err) + } +``` + + +Configure the Collector sidecar to receive OTLP gRPC on `localhost:4317`, export traces to Google Cloud, and export metrics to Google Managed Service for Prometheus: + + +[gcp/cloudrun/otel/otel-collector-config.yaml](https://github.com/temporalio/samples-go/blob/main/gcp/cloudrun/otel/otel-collector-config.yaml) +```yaml +# Google-Built OpenTelemetry Collector configuration for a Cloud Run worker pool +# sidecar. The Temporal worker exports OTLP gRPC to localhost:4317; this collector +# adds GCP resource attributes and exports to Google Cloud. +# +# Metrics use googlemanagedprometheus with NO batch processor: batching can merge +# periodic and forced-shutdown snapshots of the same cumulative series into a +# single Google Monitoring write, which Managed Service for Prometheus rejects as +# duplicate data. Traces may be batched independently. +receivers: + otlp: + protocols: + grpc: + endpoint: localhost:4317 + +processors: + # Guard the sidecar against unbounded memory growth. + memory_limiter: + check_interval: 1s + limit_percentage: 65 + spike_limit_percentage: 20 + # Detect Google Cloud resource attributes (project, region, revision, ...). + resourcedetection: + detectors: [gcp] + timeout: 10s + # Batch is used ONLY for traces. + batch: + send_batch_size: 200 + timeout: 5s + +exporters: + debug: + googlemanagedprometheus: + googlecloud: + +extensions: + # Health check used as the container startup probe. Bind on all interfaces + # so the Cloud Run startup probe can reach it. + health_check: + endpoint: 0.0.0.0:13133 + +service: + extensions: [health_check] + pipelines: + # No batch processor in the metrics pipeline. + metrics: + receivers: [otlp] + processors: [memory_limiter, resourcedetection] + exporters: [googlemanagedprometheus, debug] + traces: + receivers: [otlp] + processors: [memory_limiter, resourcedetection, batch] + exporters: [googlecloud, debug] + telemetry: + logs: + level: info +``` + + +On shutdown, stop the Worker and call `otelPlugin.Shutdown` with a deadline shorter than Cloud Run's termination window so telemetry can flush. For a Collector configuration that exports traces to Google Cloud and metrics to Google Managed Service for Prometheus, see the [Go Cloud Run OpenTelemetry sample](https://github.com/temporalio/samples-go/pull/528). + +## Set a Worker identity {/* #worker-identity */} + +Use the Cloud Run Worker Id plugin to identify each Worker instance as `@`. The plugin reads Cloud Run environment variables and instance metadata once when the Client connects, then Workers created from that Client inherit the identity. + + +[gcp/cloudrun/workerid/worker/main.go](https://github.com/temporalio/samples-go/blob/main/gcp/cloudrun/workerid/worker/main.go) +```go +// ... + plugin := workerid.NewPlugin(workerid.PluginOptions{}) + clientOptions := client.Options{ + HostPort: getenv("TEMPORAL_ADDRESS", client.DefaultHostPort), + Namespace: getenv("TEMPORAL_NAMESPACE", client.DefaultNamespace), + Plugins: []client.Plugin{plugin}, + } + + c, err := client.Dial(clientOptions) + if err != nil { + log.Fatalf("Unable to create Temporal client (is this running on a Cloud Run worker pool or service?): %v", err) + } +``` + + +The plugin requires the Cloud Run metadata server, so it fails when the Worker runs outside Cloud Run. For a complete example, see the [Go Cloud Run Worker Id sample](https://github.com/temporalio/samples-go/pull/531). diff --git a/docs/develop/java/workers/serverless-workers/cloud-run.mdx b/docs/develop/java/workers/serverless-workers/cloud-run.mdx index bc718fa966..54905a107a 100644 --- a/docs/develop/java/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/java/workers/serverless-workers/cloud-run.mdx @@ -23,7 +23,7 @@ import { ReleaseNoteHeader } from '@site/src/components'; On a [GCP Cloud Run worker pool](https://cloud.google.com/run/docs/resource-model#worker-pools), you run a standard long-lived Temporal Worker. Register Workflows and Activities the same way you would with any other Java Worker, and Temporal Cloud scales the pool up and down as work arrives and drains. -A Cloud Run Worker needs no Cloud Run-specific package. +A Cloud Run Worker needs no Cloud Run-specific runtime or handler. The one addition to a standard Worker is [Worker Versioning](/worker-versioning), which is required for Serverless Workers. For the end-to-end deployment guide covering the Worker Pool, IAM, and compute configuration, see [Deploy a Serverless Worker on GCP Cloud Run](/production-deployment/worker-deployments/serverless-workers/cloud-run). @@ -149,7 +149,151 @@ public class GreetingActivitiesImpl implements GreetingActivities { For how scale-in decisions are made, see [Serverless Workers on GCP Cloud Run](/serverless-workers/cloud-run#lifecycle). -## Add observability {/* #add-observability */} +## Configure OpenTelemetry {/* #opentelemetry */} -A Cloud Run Worker emits the same traces and metrics as a Worker anywhere else. -For how to configure metrics export and OpenTelemetry tracing interceptors, see [Observability - Java SDK](/develop/java/platform/observability) and the [SDK metrics reference](/references/sdk-metrics). +Run an OpenTelemetry Collector as a sidecar in the Worker Pool. The Cloud Run OpenTelemetry plugin exports metrics and traces by OTLP gRPC to the Collector at `localhost:4317`. It configures the endpoint and service name from Cloud Run defaults. + +Create the plugin and register it on `WorkflowServiceStubsOptions` before you create the Client: + + +[gcp/cloud-run/opentelemetry/src/main/java/io/temporal/samples/gcp/cloudrun/CloudRunWorker.java](https://github.com/temporalio/samples-java/blob/gcp-cloud-run-otel/gcp/cloud-run/opentelemetry/src/main/java/io/temporal/samples/gcp/cloudrun/CloudRunWorker.java) +```java +ClientConfigProfile profile = ClientConfigProfile.load(); +CloudRunOpenTelemetryPlugin telemetryPlugin = CloudRunOpenTelemetryPlugin.newBuilder().build(); + +WorkflowServiceStubsOptions serviceOptions = + WorkflowServiceStubsOptions.newBuilder(profile.toWorkflowServiceStubsOptions()) + .setPlugins(telemetryPlugin) + .build(); +WorkflowServiceStubs service = WorkflowServiceStubs.newServiceStubs(serviceOptions); +``` + + +Configure the Collector sidecar to receive OTLP gRPC on `localhost:4317`, export traces to Google Cloud, and export metrics to Google Managed Service for Prometheus: + + +[gcp/cloud-run/opentelemetry/collector-config.yaml](https://github.com/temporalio/samples-java/blob/main/gcp/cloud-run/opentelemetry/collector-config.yaml) +```yaml +receivers: + otlp: + protocols: + grpc: + endpoint: localhost:4317 + +processors: + # Batch traces for throughput. Do not add this processor to the cumulative metrics pipeline: + # a shutdown flush can otherwise be batched with a recent periodic export of the same series. + batch/traces: + send_batch_max_size: 200 + send_batch_size: 200 + timeout: 5s + memory_limiter: + # This is the collector's memory polling cadence, not the SDK metric export interval. + check_interval: 1s + limit_percentage: 65 + spike_limit_percentage: 20 + resourcedetection: + detectors: [gcp] + timeout: 10s + # Avoid collisions with labels that Google Managed Service for Prometheus adds. + transform/collision: + metric_statements: + - context: datapoint + statements: + - set(attributes["exported_location"], attributes["location"]) + - delete_key(attributes, "location") + - set(attributes["exported_cluster"], attributes["cluster"]) + - delete_key(attributes, "cluster") + - set(attributes["exported_namespace"], attributes["namespace"]) + - delete_key(attributes, "namespace") + - set(attributes["exported_job"], attributes["job"]) + - delete_key(attributes, "job") + - set(attributes["exported_instance"], attributes["instance"]) + - delete_key(attributes, "instance") + - set(attributes["exported_project_id"], attributes["project_id"]) + - delete_key(attributes, "project_id") + # The Telemetry API expects the Google Cloud project in gcp.project_id. + transform/set_project_id: + error_mode: ignore + trace_statements: + - set(resource.attributes["gcp.project_id"], resource.attributes["gcp.project.id"]) where resource.attributes["gcp.project.id"] != nil + - set(resource.attributes["gcp.project_id"], resource.attributes["cloud.account.id"]) where resource.attributes["gcp.project_id"] == nil and resource.attributes["cloud.account.id"] != nil + +exporters: + googlemanagedprometheus: + # Google Cloud's supported OTLP path for traces is the Telemetry API. + otlp: + endpoint: telemetry.googleapis.com:443 + compression: none + balancer_name: pick_first + auth: + authenticator: googleclientauth + +extensions: + # Cloud Run container dependencies require a startup probe. This endpoint is also used for the + # collector liveness probe in worker-pool.yaml. + health_check: + endpoint: 0.0.0.0:13133 + googleclientauth: + +service: + extensions: + - health_check + - googleclientauth + pipelines: + metrics/otlp: + receivers: [otlp] + processors: [memory_limiter, resourcedetection, transform/collision] + exporters: [googlemanagedprometheus] + traces: + receivers: [otlp] + processors: [memory_limiter, resourcedetection, transform/set_project_id, batch/traces] + exporters: [otlp] + # Feed collector self-metrics back through the metrics pipeline. + telemetry: + metrics: + readers: + - periodic: + exporter: + otlp: + protocol: grpc + endpoint: http://localhost:4317 + insecure: true +``` + + +On shutdown, stop the `WorkerFactory`, then run `telemetryPlugin.newFlushHook()` before the Cloud Run termination window ends. For a Collector configuration that exports traces to Google Cloud and metrics to Google Managed Service for Prometheus, see the [Java Cloud Run OpenTelemetry sample](https://github.com/temporalio/samples-java/pull/792). + +## Set a Worker identity {/* #worker-identity */} + +Use `WorkerIdPlugin` to identify each Worker instance as `@`. Fetch the Cloud Run metadata during process startup, then register the plugin on `WorkflowClientOptions`. Workers created from that Client inherit the identity. + + +[gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/CloudRunWorker.java](https://github.com/temporalio/samples-java/blob/main/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/CloudRunWorker.java) +```java +GoogleCloudRunMetadata metadata = GoogleCloudRunMetadata.fetch(); + +String address = envOrDefault(ADDRESS_ENV, DEFAULT_ADDRESS); +String namespace = envOrDefault(NAMESPACE_ENV, DEFAULT_NAMESPACE); +String taskQueue = envOrDefault(TASK_QUEUE_ENV, DEFAULT_TASK_QUEUE); + +// Plaintext connection to the Temporal Service. Configure TLS or an API key here for a secured +// Service such as Temporal Cloud. +WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs( + WorkflowServiceStubsOptions.newBuilder().setTarget(address).build()); + +// Register WorkerIdPlugin on the client. It sets the derived worker identity +// ({instanceId}@{revision}) on the client, and workers created from the client inherit it. +// Passing the already-fetched metadata avoids a second call to the Cloud Run metadata server. +WorkflowClient client = + WorkflowClient.newInstance( + service, + WorkflowClientOptions.newBuilder() + .setNamespace(namespace) + .setPlugins(new WorkerIdPlugin(metadata)) + .build()); +``` + + +Fetching the metadata fails when the Worker runs outside Cloud Run. For a complete example, see the [Java Cloud Run Worker Id sample](https://github.com/temporalio/samples-java/pull/795). diff --git a/docs/develop/python/workers/serverless-workers/cloud-run.mdx b/docs/develop/python/workers/serverless-workers/cloud-run.mdx index 22d20370c4..f5e1a5182c 100644 --- a/docs/develop/python/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/python/workers/serverless-workers/cloud-run.mdx @@ -23,7 +23,7 @@ import { ReleaseNoteHeader } from '@site/src/components'; On a [GCP Cloud Run worker pool](https://cloud.google.com/run/docs/resource-model#worker-pools), you run a standard long-lived Temporal Worker. Register Workflows and Activities the same way you would with any other Python Worker, and Temporal Cloud scales the pool up and down as work arrives and drains. -A Cloud Run Worker needs no Cloud Run-specific package. +A Cloud Run Worker needs no Cloud Run-specific runtime or handler. The one addition to a standard Worker is [Worker Versioning](/worker-versioning), which is required for Serverless Workers. For the end-to-end deployment guide covering the Worker Pool, IAM, and compute configuration, see [Deploy a Serverless Worker on GCP Cloud Run](/production-deployment/worker-deployments/serverless-workers/cloud-run). @@ -129,7 +129,120 @@ async def my_activity(items: list[str]) -> str: For how scale-in decisions are made, see [Serverless Workers on GCP Cloud Run](/serverless-workers/cloud-run#lifecycle). -## Add observability {/* #add-observability */} +## Configure OpenTelemetry {/* #opentelemetry */} + +Run an OpenTelemetry Collector as a sidecar in the Worker Pool. The Cloud Run OpenTelemetry plugin exports metrics and traces by OTLP gRPC to the Collector at `localhost:4317`. It configures the endpoint, service name, Core SDK metrics, and tracer provider from Cloud Run defaults. + +Create the plugin and pass it to `Client.connect`. The sample reads its connection settings from the environment: + + +[gcp/cloud_run/opentelemetry/worker.py](https://github.com/temporalio/samples-python/blob/gcp-cloud-run-otel/gcp/cloud_run/opentelemetry/worker.py) +```py +# Endpoint, service name, Core metrics, and tracer provider all use the GCP +# plugin defaults. The opt-in adds named Temporal operation spans. +plugin = OpenTelemetryPlugin(add_temporal_spans=True) +client = await Client.connect( + settings.address, + namespace=settings.namespace, + api_key=settings.api_key, + # TLS for Temporal Cloud (api key present); plaintext for a dev server. + tls=bool(settings.api_key), + plugins=[plugin], +) +``` + + +Configure the Collector sidecar to receive OTLP gRPC on `localhost:4317`, export traces to Google Cloud, and export metrics to Google Managed Service for Prometheus: + + +[gcp/cloud_run/opentelemetry/collector-config.yaml](https://github.com/temporalio/samples-python/blob/main/gcp/cloud_run/opentelemetry/collector-config.yaml) +```yaml +receivers: + otlp: + protocols: + grpc: + endpoint: localhost:4317 + +processors: + batch/traces: + send_batch_max_size: 200 + send_batch_size: 200 + timeout: 5s + memory_limiter: + check_interval: 1s + limit_percentage: 65 + spike_limit_percentage: 20 + resource_detection: + detectors: [gcp] + timeout: 10s + transform/collision: + metric_statements: + - context: datapoint + statements: + - set(attributes["exported_location"], attributes["location"]) + - delete_key(attributes, "location") + - set(attributes["exported_cluster"], attributes["cluster"]) + - delete_key(attributes, "cluster") + - set(attributes["exported_namespace"], attributes["namespace"]) + - delete_key(attributes, "namespace") + - set(attributes["exported_job"], attributes["job"]) + - delete_key(attributes, "job") + - set(attributes["exported_instance"], attributes["instance"]) + - delete_key(attributes, "instance") + - set(attributes["exported_project_id"], attributes["project_id"]) + - delete_key(attributes, "project_id") + transform/set_project_id: + error_mode: ignore + trace_statements: + - set(resource.attributes["gcp.project_id"], resource.attributes["gcp.project.id"]) where resource.attributes["gcp.project.id"] != nil + - set(resource.attributes["gcp.project_id"], resource.attributes["cloud.account.id"]) where resource.attributes["gcp.project_id"] == nil and resource.attributes["cloud.account.id"] != nil + +exporters: + googlemanagedprometheus: + otlp_grpc: + endpoint: telemetry.googleapis.com:443 + compression: none + balancer_name: pick_first + auth: + authenticator: googleclientauth + +extensions: + googleclientauth: + health_check: + endpoint: 0.0.0.0:13133 + +service: + extensions: [googleclientauth, health_check] + pipelines: + metrics: + receivers: [otlp] + processors: [memory_limiter, resource_detection, transform/collision] + exporters: [googlemanagedprometheus] + traces: + receivers: [otlp] + processors: + [memory_limiter, resource_detection, transform/set_project_id, batch/traces] + exporters: [otlp_grpc] +``` + + +Wait until the Collector accepts connections before starting the Worker. On shutdown, call `plugin.shutdown()` after the Worker stops so traces can flush. For a Collector configuration that exports traces to Google Cloud and metrics to Google Managed Service for Prometheus, see the [Python Cloud Run OpenTelemetry sample](https://github.com/temporalio/samples-python/pull/353). + +## Set a Worker identity {/* #worker-identity */} + +Use `WorkerIDPlugin` to identify each Worker instance as `@`. The plugin reads Cloud Run environment variables and instance metadata when the Client connects, then Workers created from that Client inherit the identity. + + +[gcp/cloud_run/worker_id/worker.py](https://github.com/temporalio/samples-python/blob/main/gcp/cloud_run/worker_id/worker.py) +```py +client = await Client.connect( + settings.address, + namespace=settings.namespace, + plugins=[WorkerIDPlugin()], + api_key=settings.api_key, + tls=settings.tls, +) +``` + -A Cloud Run Worker emits the same traces and metrics as a Worker anywhere else. -For how to configure metrics export and OpenTelemetry tracing interceptors, see [Observability - Python SDK](/develop/python/platform/observability) and the [SDK metrics reference](/references/sdk-metrics). +The plugin requires the Cloud Run metadata server, so it fails when the Worker runs outside Cloud Run. For a complete example, see the [Python Cloud Run Worker Id sample](https://github.com/temporalio/samples-python/pull/356). diff --git a/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx b/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx index 634db69e53..d8ddf7ae04 100644 --- a/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx +++ b/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx @@ -77,6 +77,7 @@ import os from temporalio.client import Client from temporalio.common import VersioningBehavior, WorkerDeploymentVersion +from temporalio.contrib.gcp.cloud_run.worker_id import WorkerIDPlugin from temporalio.worker import Worker, WorkerDeploymentConfig from my_workflows import MyWorkflow @@ -88,6 +89,7 @@ async def main() -> None: os.environ["TEMPORAL_ADDRESS"], namespace=os.environ["TEMPORAL_NAMESPACE"], api_key=os.environ.get("TEMPORAL_API_KEY"), + plugins=[WorkerIDPlugin()], tls=True, ) worker = Worker( @@ -127,8 +129,8 @@ class MyWorkflow: ... ``` -For more on the Python Worker setup, see -[Serverless Workers on GCP Cloud Run - Python SDK](/develop/python/workers/serverless-workers/cloud-run). +The example uses the Cloud Run Worker Id plugin to identify each Worker as `@`. For more on the +Python Worker setup, see [Serverless Workers on GCP Cloud Run - Python SDK](/develop/python/workers/serverless-workers/cloud-run). @@ -142,6 +144,7 @@ import ( "go.temporal.io/sdk/client" "go.temporal.io/sdk/contrib/envconfig" + "go.temporal.io/sdk/contrib/gcp/cloudrun/workerid" "go.temporal.io/sdk/worker" "go.temporal.io/sdk/workflow" @@ -149,7 +152,9 @@ import ( ) func main() { - c, err := client.Dial(envconfig.MustLoadDefaultClientOptions()) + clientOptions := envconfig.MustLoadDefaultClientOptions() + clientOptions.Plugins = append(clientOptions.Plugins, workerid.NewPlugin(workerid.PluginOptions{})) + c, err := client.Dial(clientOptions) if err != nil { log.Fatalln("Unable to create client", err) } @@ -192,8 +197,8 @@ w := worker.New(c, os.Getenv("TEMPORAL_TASK_QUEUE"), worker.Options{ If a Version is set and neither is specified, registration panics with `workflow type does not have a versioning behavior`. -For more on the Go Worker setup, see -[Serverless Workers on GCP Cloud Run - Go SDK](/develop/go/workers/serverless-workers/cloud-run). +The example uses the Cloud Run Worker Id plugin to identify each Worker as `@`. For more on the +Go Worker setup, see [Serverless Workers on GCP Cloud Run - Go SDK](/develop/go/workers/serverless-workers/cloud-run). @@ -257,6 +262,8 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowClientOptions; import io.temporal.common.VersioningBehavior; import io.temporal.common.WorkerDeploymentVersion; +import io.temporal.gcp.cloudrun.workerid.GoogleCloudRunMetadata; +import io.temporal.gcp.cloudrun.workerid.WorkerIdPlugin; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.serviceclient.WorkflowServiceStubsOptions; import io.temporal.worker.Worker; @@ -276,11 +283,13 @@ public class WorkerMain { .addApiKey(() -> apiKey) .build()); + GoogleCloudRunMetadata metadata = GoogleCloudRunMetadata.fetch(); WorkflowClient client = WorkflowClient.newInstance( service, WorkflowClientOptions.newBuilder() .setNamespace(System.getenv("TEMPORAL_NAMESPACE")) + .setPlugins(new WorkerIdPlugin(metadata)) .build()); WorkerFactory factory = WorkerFactory.newInstance(client); @@ -309,20 +318,22 @@ Each Workflow must have a [versioning behavior](/worker-versioning#versioning-be `AUTO_UPGRADE`. Set it per Workflow with the `@WorkflowVersioningBehavior` annotation, or set a Worker-level default with `setDefaultVersioningBehavior` as shown above. -For more on the Java Worker setup, see -[Serverless Workers on GCP Cloud Run - Java SDK](/develop/java/workers/serverless-workers/cloud-run). +The example uses the Cloud Run Worker Id plugin to identify each Worker as `@`. For more on the +Java Worker setup, see [Serverless Workers on GCP Cloud Run - Java SDK](/develop/java/workers/serverless-workers/cloud-run). ```csharp using Temporalio.Client; +using Temporalio.Extensions.Gcp.CloudRun.WorkerId; using Temporalio.Worker; var client = await TemporalClient.ConnectAsync(new(Environment.GetEnvironmentVariable("TEMPORAL_ADDRESS")!) { Namespace = Environment.GetEnvironmentVariable("TEMPORAL_NAMESPACE")!, ApiKey = Environment.GetEnvironmentVariable("TEMPORAL_API_KEY"), + Plugins = new[] { new WorkerIdPlugin() }, Tls = new(), }); @@ -344,8 +355,8 @@ Each Workflow must have a [versioning behavior](/worker-versioning#versioning-be `AutoUpgrade`. Set it per Workflow with `[Workflow(VersioningBehavior = ...)]`, or set a Worker-level default with `DefaultVersioningBehavior` as shown above. -For more on the .NET Worker setup, see -[Serverless Workers on GCP Cloud Run - .NET SDK](/develop/dotnet/workers/serverless-workers/cloud-run). +The example uses the Cloud Run Worker Id plugin to identify each Worker as `@`. For more on the +.NET Worker setup, see [Serverless Workers on GCP Cloud Run - .NET SDK](/develop/dotnet/workers/serverless-workers/cloud-run). @@ -448,16 +459,6 @@ For more on the Rust Worker setup, see -:::tip - -Workers on Cloud Run use the same code as a traditional long-lived Worker, so the SDK defaults the -[Worker Identity](/workers#worker-identity) to the process ID and hostname. On Cloud Run that resolves to -`1@localhost`, which makes a Worker harder to identify in the Temporal UI. Set your own Worker Identity, built from the -[Cloud Run environment variables](https://cloud.google.com/run/docs/container-contract#worker-pools-env-vars), to help -identify your Serverless Workers. - -::: - ## 2. Deploy to a Cloud Run Worker Pool {/* #deploy-worker-pool */} Containerize the Worker, push the image to Artifact Registry, and create the Worker Pool. From 6370d8cf36b8e79e6a72afa406ea012d13c61e85 Mon Sep 17 00:00:00 2001 From: "Lenny (Temporal)" Date: Tue, 29 Sep 2026 11:58:25 -0700 Subject: [PATCH 02/12] Sync Cloud Run docs with sample PR branches --- .../workers/serverless-workers/cloud-run.mdx | 23 ++++------ .../workers/serverless-workers/cloud-run.mdx | 42 ++++++++----------- .../workers/serverless-workers/cloud-run.mdx | 21 ++++------ .../workers/serverless-workers/cloud-run.mdx | 19 ++++----- .../serverless-workers/cloud-run/index.mdx | 26 ++++++------ 5 files changed, 52 insertions(+), 79 deletions(-) diff --git a/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx b/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx index b7114211de..eb315e553c 100644 --- a/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx @@ -202,10 +202,10 @@ The [OpenTelemetry sample](https://github.com/temporalio/samples-dotnet/tree/mai ## Set a Worker identity {/* #worker-identity */} -Use `WorkerIdPlugin` to identify each Worker instance as `@`. The plugin reads Cloud Run environment variables and instance metadata when the Client connects, then Workers created from that Client inherit the identity. +Use `CloudRunIdPlugin` to identify each Worker instance as `@`. The plugin reads Cloud Run environment variables and instance metadata when the Client connects, then Workers created from that Client inherit the identity. - -[src/Gcp/CloudRun/WorkerId/Program.cs](https://github.com/temporalio/samples-dotnet/blob/main/src/Gcp/CloudRun/WorkerId/Program.cs) + +[src/Gcp/CloudRun/Id/Program.cs](https://github.com/temporalio/samples-dotnet/blob/main/src/Gcp/CloudRun/Id/Program.cs) ```cs var address = GetEnvironmentVariable("TEMPORAL_ADDRESS") ?? "localhost:7233"; var temporalNamespace = GetEnvironmentVariable("TEMPORAL_NAMESPACE") ?? "default"; @@ -214,25 +214,18 @@ var taskQueue = GetEnvironmentVariable("TEMPORAL_TASK_QUEUE") ?? "cloud-run-work using var loggerFactory = LoggerFactory.Create(builder => builder. AddSimpleConsole(options => options.TimestampFormat = "[HH:mm:ss] "). SetMinimumLevel(LogLevel.Information)); -var logger = loggerFactory.CreateLogger("CloudRunWorkerId"); - -// Register the Cloud Run plugin once on the client. At connect time it reads the Cloud Run instance -// id from the metadata server, and the worker pool / service name and revision from the environment, -// then sets the client Identity to the worker identity "{instanceId}@{revision}" (unless one was -// already configured). Every worker created from this client inherits that identity. The plugin only -// sets the worker identity; it does not configure anything else. -// -// NOTE: this requires the process to be running on a Cloud Run worker pool or service. Running it -// elsewhere throws at connect time because the metadata server is unreachable. +var logger = loggerFactory.CreateLogger("CloudRunId"); + +// Derives the client identity "{instanceId}@{revision}" from Cloud Run metadata at connect time. var clientOptions = new TemporalClientConnectOptions(address) { Namespace = temporalNamespace, LoggerFactory = loggerFactory, - Plugins = new[] { new WorkerIdPlugin() }, + Plugins = new[] { new CloudRunIdPlugin() }, }; var client = await TemporalClient.ConnectAsync(clientOptions); ``` -The plugin requires the Cloud Run metadata server, so it fails when the Worker runs outside Cloud Run. For a complete example, see the [.NET Cloud Run Worker Id sample](https://github.com/temporalio/samples-dotnet/pull/219). +The plugin requires the Cloud Run metadata server, so it fails when the Worker runs outside Cloud Run. For a complete example, see the [.NET Cloud Run Id sample](https://github.com/temporalio/samples-dotnet/pull/219). diff --git a/docs/develop/go/workers/serverless-workers/cloud-run.mdx b/docs/develop/go/workers/serverless-workers/cloud-run.mdx index 34e1f705c3..f0151399f1 100644 --- a/docs/develop/go/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/go/workers/serverless-workers/cloud-run.mdx @@ -118,8 +118,8 @@ Run an OpenTelemetry Collector as a sidecar in the Worker Pool. The Cloud Run Op Create the plugin before connecting, then add it to the Client options. Client plugins that implement `worker.Plugin` also apply to Workers created from that Client: - -[gcp/cloudrun/otel/worker/main.go](https://github.com/temporalio/samples-go/blob/gcp-cloud-run-otel/gcp/cloudrun/otel/worker/main.go) + +[gcp/cloudrun/otel/worker/main.go](https://github.com/temporalio/samples-go/blob/main/gcp/cloudrun/otel/worker/main.go) ```go // ... otelPlugin, err := otel.NewPlugin(ctx, otel.PluginOptions{}) @@ -127,9 +127,7 @@ Create the plugin before connecting, then add it to the Client options. Client p log.Fatalln("Unable to create OpenTelemetry plugin", err) } - // Load the Temporal connection from the environment (see temporal.toml or the - // TEMPORAL_* environment variables) and install the plugin. Client plugins - // that also implement worker.Plugin are applied to workers automatically. + // A client plugin that also implements worker.Plugin is applied to workers automatically. clientOptions, err := envconfig.LoadDefaultClientOptions() if err != nil { log.Fatalln("Unable to load Temporal client options", err) @@ -148,14 +146,10 @@ Configure the Collector sidecar to receive OTLP gRPC on `localhost:4317`, export [gcp/cloudrun/otel/otel-collector-config.yaml](https://github.com/temporalio/samples-go/blob/main/gcp/cloudrun/otel/otel-collector-config.yaml) ```yaml -# Google-Built OpenTelemetry Collector configuration for a Cloud Run worker pool -# sidecar. The Temporal worker exports OTLP gRPC to localhost:4317; this collector -# adds GCP resource attributes and exports to Google Cloud. -# -# Metrics use googlemanagedprometheus with NO batch processor: batching can merge -# periodic and forced-shutdown snapshots of the same cumulative series into a -# single Google Monitoring write, which Managed Service for Prometheus rejects as -# duplicate data. Traces may be batched independently. +# Collector sidecar: receives OTLP from the worker, adds GCP resource attributes, exports to Google Cloud. +# Metrics use googlemanagedprometheus with NO batch processor: batching can merge periodic and +# forced-shutdown snapshots of the same cumulative series into one Monitoring write, which Managed +# Service for Prometheus rejects as duplicate data. Traces may be batched independently. receivers: otlp: protocols: @@ -183,8 +177,7 @@ exporters: googlecloud: extensions: - # Health check used as the container startup probe. Bind on all interfaces - # so the Cloud Run startup probe can reach it. + # Startup probe; bind on all interfaces so Cloud Run can reach it. health_check: endpoint: 0.0.0.0:13133 @@ -210,24 +203,23 @@ On shutdown, stop the Worker and call `otelPlugin.Shutdown` with a deadline shor ## Set a Worker identity {/* #worker-identity */} -Use the Cloud Run Worker Id plugin to identify each Worker instance as `@`. The plugin reads Cloud Run environment variables and instance metadata once when the Client connects, then Workers created from that Client inherit the identity. +Use the Cloud Run Id plugin to identify each Worker instance as `@`. The plugin reads Cloud Run environment variables and instance metadata once when the Client connects, then Workers created from that Client inherit the identity. - -[gcp/cloudrun/workerid/worker/main.go](https://github.com/temporalio/samples-go/blob/main/gcp/cloudrun/workerid/worker/main.go) + +[gcp/cloudrun/id/worker/main.go](https://github.com/temporalio/samples-go/blob/main/gcp/cloudrun/id/worker/main.go) ```go // ... - plugin := workerid.NewPlugin(workerid.PluginOptions{}) - clientOptions := client.Options{ + plugin := id.NewCloudRunIDPlugin() + c, err := client.Dial(client.Options{ HostPort: getenv("TEMPORAL_ADDRESS", client.DefaultHostPort), Namespace: getenv("TEMPORAL_NAMESPACE", client.DefaultNamespace), Plugins: []client.Plugin{plugin}, - } - - c, err := client.Dial(clientOptions) + }) if err != nil { - log.Fatalf("Unable to create Temporal client (is this running on a Cloud Run worker pool or service?): %v", err) + log.Fatalf("Unable to create Temporal client (is this running on Cloud Run?): %v", err) } + defer c.Close() ``` -The plugin requires the Cloud Run metadata server, so it fails when the Worker runs outside Cloud Run. For a complete example, see the [Go Cloud Run Worker Id sample](https://github.com/temporalio/samples-go/pull/531). +The plugin requires the Cloud Run metadata server, so it fails when the Worker runs outside Cloud Run. For a complete example, see the [Go Cloud Run Id sample](https://github.com/temporalio/samples-go/pull/531). diff --git a/docs/develop/java/workers/serverless-workers/cloud-run.mdx b/docs/develop/java/workers/serverless-workers/cloud-run.mdx index 54905a107a..93a4f2bf3f 100644 --- a/docs/develop/java/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/java/workers/serverless-workers/cloud-run.mdx @@ -156,7 +156,7 @@ Run an OpenTelemetry Collector as a sidecar in the Worker Pool. The Cloud Run Op Create the plugin and register it on `WorkflowServiceStubsOptions` before you create the Client: -[gcp/cloud-run/opentelemetry/src/main/java/io/temporal/samples/gcp/cloudrun/CloudRunWorker.java](https://github.com/temporalio/samples-java/blob/gcp-cloud-run-otel/gcp/cloud-run/opentelemetry/src/main/java/io/temporal/samples/gcp/cloudrun/CloudRunWorker.java) +[gcp/cloud-run/opentelemetry/src/main/java/io/temporal/samples/gcp/cloudrun/opentelemetry/CloudRunWorker.java](https://github.com/temporalio/samples-java/blob/main/gcp/cloud-run/opentelemetry/src/main/java/io/temporal/samples/gcp/cloudrun/opentelemetry/CloudRunWorker.java) ```java ClientConfigProfile profile = ClientConfigProfile.load(); CloudRunOpenTelemetryPlugin telemetryPlugin = CloudRunOpenTelemetryPlugin.newBuilder().build(); @@ -266,34 +266,27 @@ On shutdown, stop the `WorkerFactory`, then run `telemetryPlugin.newFlushHook()` ## Set a Worker identity {/* #worker-identity */} -Use `WorkerIdPlugin` to identify each Worker instance as `@`. Fetch the Cloud Run metadata during process startup, then register the plugin on `WorkflowClientOptions`. Workers created from that Client inherit the identity. +Use `CloudRunIdPlugin` to identify each Worker instance as `@`. Register the plugin on `WorkflowClientOptions` before creating the Client. Workers created from that Client inherit the identity. - -[gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/CloudRunWorker.java](https://github.com/temporalio/samples-java/blob/main/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/CloudRunWorker.java) +[gcp/cloud-run/id/src/main/java/io/temporal/samples/gcp/cloudrun/id/CloudRunWorker.java](https://github.com/temporalio/samples-java/blob/main/gcp/cloud-run/id/src/main/java/io/temporal/samples/gcp/cloudrun/id/CloudRunWorker.java) ```java -GoogleCloudRunMetadata metadata = GoogleCloudRunMetadata.fetch(); - String address = envOrDefault(ADDRESS_ENV, DEFAULT_ADDRESS); String namespace = envOrDefault(NAMESPACE_ENV, DEFAULT_NAMESPACE); String taskQueue = envOrDefault(TASK_QUEUE_ENV, DEFAULT_TASK_QUEUE); -// Plaintext connection to the Temporal Service. Configure TLS or an API key here for a secured -// Service such as Temporal Cloud. +// Plaintext connection; add TLS or an API key here for Temporal Cloud. WorkflowServiceStubs service = WorkflowServiceStubs.newServiceStubs( WorkflowServiceStubsOptions.newBuilder().setTarget(address).build()); -// Register WorkerIdPlugin on the client. It sets the derived worker identity -// ({instanceId}@{revision}) on the client, and workers created from the client inherit it. -// Passing the already-fetched metadata avoids a second call to the Cloud Run metadata server. +// CloudRunIdPlugin sets the client identity to {instanceId}@{revision} from metadata. WorkflowClient client = WorkflowClient.newInstance( service, WorkflowClientOptions.newBuilder() .setNamespace(namespace) - .setPlugins(new WorkerIdPlugin(metadata)) + .setPlugins(new CloudRunIdPlugin()) .build()); ``` - -Fetching the metadata fails when the Worker runs outside Cloud Run. For a complete example, see the [Java Cloud Run Worker Id sample](https://github.com/temporalio/samples-java/pull/795). +The plugin requires Cloud Run metadata, so Client creation fails when the Worker runs outside Cloud Run. For a complete example, see the [Java Cloud Run Id sample](https://github.com/temporalio/samples-java/pull/795). diff --git a/docs/develop/python/workers/serverless-workers/cloud-run.mdx b/docs/develop/python/workers/serverless-workers/cloud-run.mdx index f5e1a5182c..1a79ce35e5 100644 --- a/docs/develop/python/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/python/workers/serverless-workers/cloud-run.mdx @@ -135,18 +135,15 @@ Run an OpenTelemetry Collector as a sidecar in the Worker Pool. The Cloud Run Op Create the plugin and pass it to `Client.connect`. The sample reads its connection settings from the environment: - -[gcp/cloud_run/opentelemetry/worker.py](https://github.com/temporalio/samples-python/blob/gcp-cloud-run-otel/gcp/cloud_run/opentelemetry/worker.py) + +[gcp/cloud_run/opentelemetry/worker.py](https://github.com/temporalio/samples-python/blob/main/gcp/cloud_run/opentelemetry/worker.py) ```py -# Endpoint, service name, Core metrics, and tracer provider all use the GCP -# plugin defaults. The opt-in adds named Temporal operation spans. plugin = OpenTelemetryPlugin(add_temporal_spans=True) client = await Client.connect( settings.address, namespace=settings.namespace, api_key=settings.api_key, - # TLS for Temporal Cloud (api key present); plaintext for a dev server. - tls=bool(settings.api_key), + tls=settings.tls, plugins=[plugin], ) ``` @@ -230,19 +227,19 @@ Wait until the Collector accepts connections before starting the Worker. On shut ## Set a Worker identity {/* #worker-identity */} -Use `WorkerIDPlugin` to identify each Worker instance as `@`. The plugin reads Cloud Run environment variables and instance metadata when the Client connects, then Workers created from that Client inherit the identity. +Use `CloudRunIdPlugin` to identify each Worker instance as `@`. The plugin reads Cloud Run environment variables and instance metadata when the Client connects, then Workers created from that Client inherit the identity. - -[gcp/cloud_run/worker_id/worker.py](https://github.com/temporalio/samples-python/blob/main/gcp/cloud_run/worker_id/worker.py) + +[gcp/cloud_run/id/worker.py](https://github.com/temporalio/samples-python/blob/main/gcp/cloud_run/id/worker.py) ```py client = await Client.connect( settings.address, namespace=settings.namespace, - plugins=[WorkerIDPlugin()], + plugins=[CloudRunIdPlugin()], api_key=settings.api_key, tls=settings.tls, ) ``` -The plugin requires the Cloud Run metadata server, so it fails when the Worker runs outside Cloud Run. For a complete example, see the [Python Cloud Run Worker Id sample](https://github.com/temporalio/samples-python/pull/356). +The plugin requires the Cloud Run metadata server, so it fails when the Worker runs outside Cloud Run. For a complete example, see the [Python Cloud Run Id sample](https://github.com/temporalio/samples-python/pull/356). diff --git a/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx b/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx index d8ddf7ae04..322fdcd6e4 100644 --- a/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx +++ b/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx @@ -77,7 +77,7 @@ import os from temporalio.client import Client from temporalio.common import VersioningBehavior, WorkerDeploymentVersion -from temporalio.contrib.gcp.cloud_run.worker_id import WorkerIDPlugin +from temporalio.contrib.gcp.cloud_run.id import CloudRunIdPlugin from temporalio.worker import Worker, WorkerDeploymentConfig from my_workflows import MyWorkflow @@ -89,7 +89,7 @@ async def main() -> None: os.environ["TEMPORAL_ADDRESS"], namespace=os.environ["TEMPORAL_NAMESPACE"], api_key=os.environ.get("TEMPORAL_API_KEY"), - plugins=[WorkerIDPlugin()], + plugins=[CloudRunIdPlugin()], tls=True, ) worker = Worker( @@ -129,7 +129,7 @@ class MyWorkflow: ... ``` -The example uses the Cloud Run Worker Id plugin to identify each Worker as `@`. For more on the +The example uses the Cloud Run Id plugin to identify each Worker as `@`. For more on the Python Worker setup, see [Serverless Workers on GCP Cloud Run - Python SDK](/develop/python/workers/serverless-workers/cloud-run). @@ -144,7 +144,7 @@ import ( "go.temporal.io/sdk/client" "go.temporal.io/sdk/contrib/envconfig" - "go.temporal.io/sdk/contrib/gcp/cloudrun/workerid" + "go.temporal.io/sdk/contrib/gcp/cloudrun/id" "go.temporal.io/sdk/worker" "go.temporal.io/sdk/workflow" @@ -153,7 +153,7 @@ import ( func main() { clientOptions := envconfig.MustLoadDefaultClientOptions() - clientOptions.Plugins = append(clientOptions.Plugins, workerid.NewPlugin(workerid.PluginOptions{})) + clientOptions.Plugins = append(clientOptions.Plugins, id.NewCloudRunIDPlugin()) c, err := client.Dial(clientOptions) if err != nil { log.Fatalln("Unable to create client", err) @@ -197,7 +197,7 @@ w := worker.New(c, os.Getenv("TEMPORAL_TASK_QUEUE"), worker.Options{ If a Version is set and neither is specified, registration panics with `workflow type does not have a versioning behavior`. -The example uses the Cloud Run Worker Id plugin to identify each Worker as `@`. For more on the +The example uses the Cloud Run Id plugin to identify each Worker as `@`. For more on the Go Worker setup, see [Serverless Workers on GCP Cloud Run - Go SDK](/develop/go/workers/serverless-workers/cloud-run). @@ -262,8 +262,7 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowClientOptions; import io.temporal.common.VersioningBehavior; import io.temporal.common.WorkerDeploymentVersion; -import io.temporal.gcp.cloudrun.workerid.GoogleCloudRunMetadata; -import io.temporal.gcp.cloudrun.workerid.WorkerIdPlugin; +import io.temporal.gcp.cloudrun.id.CloudRunIdPlugin; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.serviceclient.WorkflowServiceStubsOptions; import io.temporal.worker.Worker; @@ -283,13 +282,12 @@ public class WorkerMain { .addApiKey(() -> apiKey) .build()); - GoogleCloudRunMetadata metadata = GoogleCloudRunMetadata.fetch(); WorkflowClient client = WorkflowClient.newInstance( service, WorkflowClientOptions.newBuilder() .setNamespace(System.getenv("TEMPORAL_NAMESPACE")) - .setPlugins(new WorkerIdPlugin(metadata)) + .setPlugins(new CloudRunIdPlugin()) .build()); WorkerFactory factory = WorkerFactory.newInstance(client); @@ -318,7 +316,7 @@ Each Workflow must have a [versioning behavior](/worker-versioning#versioning-be `AUTO_UPGRADE`. Set it per Workflow with the `@WorkflowVersioningBehavior` annotation, or set a Worker-level default with `setDefaultVersioningBehavior` as shown above. -The example uses the Cloud Run Worker Id plugin to identify each Worker as `@`. For more on the +The example uses the Cloud Run Id plugin to identify each Worker as `@`. For more on the Java Worker setup, see [Serverless Workers on GCP Cloud Run - Java SDK](/develop/java/workers/serverless-workers/cloud-run). @@ -326,14 +324,14 @@ Java Worker setup, see [Serverless Workers on GCP Cloud Run - Java SDK](/develop ```csharp using Temporalio.Client; -using Temporalio.Extensions.Gcp.CloudRun.WorkerId; +using Temporalio.Extensions.Gcp.CloudRun.Id; using Temporalio.Worker; var client = await TemporalClient.ConnectAsync(new(Environment.GetEnvironmentVariable("TEMPORAL_ADDRESS")!) { Namespace = Environment.GetEnvironmentVariable("TEMPORAL_NAMESPACE")!, ApiKey = Environment.GetEnvironmentVariable("TEMPORAL_API_KEY"), - Plugins = new[] { new WorkerIdPlugin() }, + Plugins = new[] { new CloudRunIdPlugin() }, Tls = new(), }); @@ -355,7 +353,7 @@ Each Workflow must have a [versioning behavior](/worker-versioning#versioning-be `AutoUpgrade`. Set it per Workflow with `[Workflow(VersioningBehavior = ...)]`, or set a Worker-level default with `DefaultVersioningBehavior` as shown above. -The example uses the Cloud Run Worker Id plugin to identify each Worker as `@`. For more on the +The example uses the Cloud Run Id plugin to identify each Worker as `@`. For more on the .NET Worker setup, see [Serverless Workers on GCP Cloud Run - .NET SDK](/develop/dotnet/workers/serverless-workers/cloud-run). From 4a63ef994cce920d9221e1a35d32903880b21769 Mon Sep 17 00:00:00 2001 From: "Lenny (Temporal)" Date: Tue, 29 Sep 2026 13:38:15 -0700 Subject: [PATCH 03/12] Clarify Go Cloud Run identity connection options --- .../serverless-workers/cloud-run/index.mdx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx b/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx index ddd9f16e50..f611f0622d 100644 --- a/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx +++ b/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx @@ -197,8 +197,10 @@ w := worker.New(c, os.Getenv("TEMPORAL_TASK_QUEUE"), worker.Options{ If a Version is set and neither is specified, registration panics with `workflow type does not have a versioning behavior`. -The example uses the Cloud Run Id plugin to identify each Worker as `@`. For more on the -Go Worker setup, see [Serverless Workers on GCP Cloud Run - Go SDK](/develop/go/workers/serverless-workers/cloud-run). +This example loads the Temporal Cloud connection settings with `envconfig`, then adds the Cloud Run Id plugin to identify +each Worker as `@`. The [Go Cloud Run Id sample](https://github.com/temporalio/samples-go/pull/531) +constructs `client.Options` directly for a plaintext connection. For more on the Go Worker setup, see +[Serverless Workers on GCP Cloud Run - Go SDK](/develop/go/workers/serverless-workers/cloud-run). From a512eeb9445b04a41bd0f9ecd43ac14e9ebbcd7d Mon Sep 17 00:00:00 2001 From: "Lenny (Temporal)" Date: Tue, 29 Sep 2026 13:42:56 -0700 Subject: [PATCH 04/12] Use direct Go client options in Cloud Run deploy guide --- .../serverless-workers/cloud-run/index.mdx | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx b/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx index f611f0622d..f525b4d249 100644 --- a/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx +++ b/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx @@ -139,11 +139,11 @@ Python Worker setup, see [Serverless Workers on GCP Cloud Run - Python SDK](/dev package main import ( + "crypto/tls" "log" "os" "go.temporal.io/sdk/client" - "go.temporal.io/sdk/contrib/envconfig" "go.temporal.io/sdk/contrib/gcp/cloudrun/id" "go.temporal.io/sdk/worker" "go.temporal.io/sdk/workflow" @@ -152,9 +152,13 @@ import ( ) func main() { - clientOptions := envconfig.MustLoadDefaultClientOptions() - clientOptions.Plugins = append(clientOptions.Plugins, id.NewCloudRunIDPlugin()) - c, err := client.Dial(clientOptions) + c, err := client.Dial(client.Options{ + HostPort: os.Getenv("TEMPORAL_ADDRESS"), + Namespace: os.Getenv("TEMPORAL_NAMESPACE"), + ConnectionOptions: client.ConnectionOptions{TLS: &tls.Config{}}, + Credentials: client.NewAPIKeyStaticCredentials(os.Getenv("TEMPORAL_API_KEY")), + Plugins: []client.Plugin{id.NewCloudRunIDPlugin()}, + }) if err != nil { log.Fatalln("Unable to create client", err) } @@ -197,10 +201,8 @@ w := worker.New(c, os.Getenv("TEMPORAL_TASK_QUEUE"), worker.Options{ If a Version is set and neither is specified, registration panics with `workflow type does not have a versioning behavior`. -This example loads the Temporal Cloud connection settings with `envconfig`, then adds the Cloud Run Id plugin to identify -each Worker as `@`. The [Go Cloud Run Id sample](https://github.com/temporalio/samples-go/pull/531) -constructs `client.Options` directly for a plaintext connection. For more on the Go Worker setup, see -[Serverless Workers on GCP Cloud Run - Go SDK](/develop/go/workers/serverless-workers/cloud-run). +The example uses the Cloud Run Id plugin to identify each Worker as `@`. For more on the +Go Worker setup, see [Serverless Workers on GCP Cloud Run - Go SDK](/develop/go/workers/serverless-workers/cloud-run). @@ -696,8 +698,7 @@ gcloud run worker-pools deploy my-temporal-worker-pool-build-1 \ | `--set-env-vars` | Non-secret Worker configuration. See [Environment configuration](/develop/environment-configuration). | | `--set-secrets` | Maps a Secret Manager secret to an environment variable. Use for `TEMPORAL_API_KEY` or TLS client cert/key material. | -The environment configuration package reads environment variables and configuration files at startup. For the -full list of supported environment variables, config file format, and profiles, see +For the full list of supported environment variables, config file format, and profiles, see [Environment configuration](/develop/environment-configuration). ## 3. Grant Temporal permission to manage the Worker Pool (Cloud only) {/* #configure-iam */} From 7c64ce920f493a69e19cf42ea2f147388d38bb8e Mon Sep 17 00:00:00 2001 From: "Lenny (Temporal)" Date: Tue, 29 Sep 2026 13:48:18 -0700 Subject: [PATCH 05/12] Sync Python Cloud Run docs with combined sample --- .../workers/serverless-workers/cloud-run.mdx | 37 ++++++++----------- .../serverless-workers/cloud-run/index.mdx | 2 +- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/docs/develop/python/workers/serverless-workers/cloud-run.mdx b/docs/develop/python/workers/serverless-workers/cloud-run.mdx index 4f03f6b766..9d5bb64332 100644 --- a/docs/develop/python/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/python/workers/serverless-workers/cloud-run.mdx @@ -133,26 +133,29 @@ For how scale-in decisions are made, see [Serverless Workers on GCP Cloud Run](/ Run an OpenTelemetry Collector as a sidecar in the Worker Pool. The Cloud Run OpenTelemetry plugin exports metrics and traces by OTLP gRPC to the Collector at `localhost:4317`. It configures the endpoint, service name, Core SDK metrics, and tracer provider from Cloud Run defaults. -Create the plugin and pass it to `Client.connect`. The sample reads its connection settings from the environment: +Create the plugin and pass it to `Client.connect`. The sample also registers `CloudRunIdPlugin` on the same Client and +reads its connection settings from the environment: - -[gcp/cloud_run/opentelemetry/worker.py](https://github.com/temporalio/samples-python/blob/main/gcp/cloud_run/opentelemetry/worker.py) + +[gcp/cloud_run/worker.py](https://github.com/temporalio/samples-python/blob/main/gcp/cloud_run/worker.py) ```py +# OpenTelemetryPlugin exports Core metrics and traces to the collector +# sidecar; CloudRunIdPlugin sets the client identity from instance metadata. plugin = OpenTelemetryPlugin(add_temporal_spans=True) client = await Client.connect( settings.address, namespace=settings.namespace, api_key=settings.api_key, tls=settings.tls, - plugins=[plugin], + plugins=[plugin, CloudRunIdPlugin()], ) ``` Configure the Collector sidecar to receive OTLP gRPC on `localhost:4317`, export traces to Google Cloud, and export metrics to Google Managed Service for Prometheus: - -[gcp/cloud_run/opentelemetry/collector-config.yaml](https://github.com/temporalio/samples-python/blob/main/gcp/cloud_run/opentelemetry/collector-config.yaml) + +[gcp/cloud_run/collector-config.yaml](https://github.com/temporalio/samples-python/blob/main/gcp/cloud_run/collector-config.yaml) ```yaml receivers: otlp: @@ -223,23 +226,13 @@ service: ``` -Wait until the Collector accepts connections before starting the Worker. On shutdown, call `plugin.shutdown()` after the Worker stops so traces can flush. For a Collector configuration that exports traces to Google Cloud and metrics to Google Managed Service for Prometheus, see the [Python Cloud Run OpenTelemetry sample](https://github.com/temporalio/samples-python/pull/353). +Wait until the Collector accepts connections before starting the Worker. On shutdown, call `plugin.shutdown()` after the Worker stops so traces can flush. For a Collector configuration that exports traces to Google Cloud and metrics to Google Managed Service for Prometheus, see the [Python Cloud Run sample](https://github.com/temporalio/samples-python/pull/376). ## Set a Worker identity {/* #worker-identity */} -Use `CloudRunIdPlugin` to identify each Worker instance as `@`. The plugin reads Cloud Run environment variables and instance metadata when the Client connects, then Workers created from that Client inherit the identity. +Use `CloudRunIdPlugin` to identify each Worker instance as `@`. The preceding example registers it +on the Client alongside the OpenTelemetry plugin. It reads Cloud Run environment variables and instance metadata when +the Client connects, then Workers created from that Client inherit the identity. - -[gcp/cloud_run/id/worker.py](https://github.com/temporalio/samples-python/blob/main/gcp/cloud_run/id/worker.py) -```py -client = await Client.connect( - settings.address, - namespace=settings.namespace, - plugins=[CloudRunIdPlugin()], - api_key=settings.api_key, - tls=settings.tls, -) -``` - - -The plugin requires the Cloud Run metadata server, so it fails when the Worker runs outside Cloud Run. For a complete example, see the [Python Cloud Run Id sample](https://github.com/temporalio/samples-python/pull/356). +The Id plugin requires the Cloud Run metadata server, so it fails when the Worker runs outside Cloud Run. For a complete +example, see the [Python Cloud Run sample](https://github.com/temporalio/samples-python/pull/376). diff --git a/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx b/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx index f525b4d249..05da0694d5 100644 --- a/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx +++ b/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx @@ -88,7 +88,7 @@ async def main() -> None: client = await Client.connect( os.environ["TEMPORAL_ADDRESS"], namespace=os.environ["TEMPORAL_NAMESPACE"], - api_key=os.environ.get("TEMPORAL_API_KEY"), + api_key=os.environ["TEMPORAL_API_KEY"].strip(), plugins=[CloudRunIdPlugin()], tls=True, ) From ccb06bb29ba07808e3a03608cbd6b3a01252edca Mon Sep 17 00:00:00 2001 From: "Lenny (Temporal)" Date: Tue, 29 Sep 2026 13:57:40 -0700 Subject: [PATCH 06/12] Address Cloud Run docs review feedback --- .../workers/serverless-workers/cloud-run.mdx | 1 - .../serverless-workers/cloud-run/index.mdx | 18 +++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/docs/develop/java/workers/serverless-workers/cloud-run.mdx b/docs/develop/java/workers/serverless-workers/cloud-run.mdx index 2dca070a5b..713cffa5e4 100644 --- a/docs/develop/java/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/java/workers/serverless-workers/cloud-run.mdx @@ -272,7 +272,6 @@ Use `CloudRunIdPlugin` to identify each Worker instance as `@ +The Cloud Run Id plugins in the Go, Python, Java, and .NET examples require the Cloud Run metadata server. To run these +Workers outside Cloud Run, omit the plugin registration and add it back before deploying. + +:::tip + +The TypeScript, Ruby, and Rust examples use the SDK's default [Worker Identity](/workers#worker-identity). On Cloud Run, +it can resolve to `1@localhost`, which does not distinguish Worker instances in the Temporal UI. Set a unique Worker +Identity using [Cloud Run environment variables](https://cloud.google.com/run/docs/container-contract#worker-pools-env-vars) +and instance metadata. + +::: + ## 2. Deploy to a Cloud Run Worker Pool {/* #deploy-worker-pool */} Containerize the Worker, push the image to Artifact Registry, and create the Worker Pool. From 5d7a4d75510e8e40e92cbcb286ed6780147e6ec1 Mon Sep 17 00:00:00 2001 From: "Lenny (Temporal)" Date: Wed, 30 Sep 2026 12:42:22 -0700 Subject: [PATCH 07/12] Sync combined Cloud Run samples and mark Public Preview --- .../workers/serverless-workers/cloud-run.mdx | 103 ++++-------------- .../workers/serverless-workers/index.mdx | 5 +- .../workers/serverless-workers/cloud-run.mdx | 99 +++++++++-------- .../go/workers/serverless-workers/index.mdx | 5 +- .../workers/serverless-workers/cloud-run.mdx | 46 +++----- .../java/workers/serverless-workers/index.mdx | 5 +- .../workers/serverless-workers/cloud-run.mdx | 14 +-- .../workers/serverless-workers/index.mdx | 4 +- .../workers/serverless-workers/cloud-run.mdx | 4 +- .../ruby/workers/serverless-workers/index.mdx | 4 +- .../workers/serverless-workers/cloud-run.mdx | 4 +- .../rust/workers/serverless-workers/index.mdx | 4 +- .../workers/serverless-workers/cloud-run.mdx | 4 +- .../workers/serverless-workers/index.mdx | 5 +- .../activities/standalone-activity.mdx | 2 +- .../workers/serverless-workers/cloud-run.mdx | 4 +- .../workers/serverless-workers/index.mdx | 4 +- .../features/serverless-workers/index.mdx | 4 +- .../serverless-workers/cloud-run/index.mdx | 49 +++------ .../cloud-run/self-hosted-setup.mdx | 2 +- .../serverless-workers/index.mdx | 4 +- .../serverless-workers/cloud-run.mdx | 4 +- .../serverless-workers/index.mdx | 5 +- src/constants/featureReleaseTypes.js | 2 +- 24 files changed, 136 insertions(+), 250 deletions(-) diff --git a/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx b/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx index 87a6dc3d2e..b0b881c612 100644 --- a/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx @@ -15,9 +15,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - Cloud Run support is in Pre-release, and its APIs may change in backwards-incompatible ways. - Create a [support ticket](/evaluate/cloud/support#support-ticket) or contact your account team for access, and - [sign up for updates](https://temporal.io/pages/serverless-workers-updates) to hear when Cloud Run reaches Public Preview. + Cloud Run support is in Public Preview. On a [GCP Cloud Run worker pool](https://cloud.google.com/run/docs/resource-model#worker-pools), you run a standard long-lived Temporal Worker. @@ -137,95 +135,34 @@ For how scale-in decisions are made, see [Serverless Workers on GCP Cloud Run](/ ## Configure OpenTelemetry {/* #opentelemetry */} -Configure the .NET OpenTelemetry exporter and the Temporal Runtime to send telemetry by OTLP to `localhost:4317`. The following code sample configures the Worker only. You must separately run an OTLP-compatible receiver at that address. In a Cloud Run Worker Pool, run that receiver as a sidecar. +Run an OpenTelemetry Collector as a sidecar in the Worker Pool. Call `ApplyGoogleCloudRunOpenTelemetryDefaults()` +to configure tracing and Temporal Core metrics for OTLP export to the Collector at `localhost:4317`. Load the Client +connection settings with `ClientEnvConfig.LoadClientConnectOptions()`, then configure both plugins before connecting: - -[src/OpenTelemetry/CoreSdkForwarding/Program.cs](https://github.com/temporalio/samples-dotnet/blob/main/src/OpenTelemetry/CoreSdkForwarding/Program.cs) + +[src/Gcp/CloudRun/Program.cs](https://github.com/temporalio/samples-dotnet/blob/gcp-cloud-run/src/Gcp/CloudRun/Program.cs) ```cs -var resourceBuilder = ResourceBuilder. - CreateDefault(). - AddService("TemporalioSamples.OpenTelemetry", serviceInstanceId: instanceId); - -using var tracerProvider = Sdk. - CreateTracerProviderBuilder(). - SetResourceBuilder(resourceBuilder). - AddSource(TracingInterceptor.ClientSource.Name, TracingInterceptor.WorkflowsSource.Name, TracingInterceptor.ActivitiesSource.Name). - AddOtlpExporter(). - Build(); - -// Shared by the client and by Core SDK log forwarding below. The OpenTelemetry provider exports -// logs to the dashboard alongside the traces and metrics. -using var loggerFactory = LoggerFactory.Create(builder => - builder. - AddSimpleConsole(options => options.TimestampFormat = "[HH:mm:ss] "). - AddOpenTelemetry(options => - { - options.SetResourceBuilder(resourceBuilder); - options.IncludeFormattedMessage = true; - options.IncludeScopes = true; - options.AddOtlpExporter(); - }). - SetMinimumLevel(LogLevel.Information)); - -// Create a client to localhost on default namespace -var connectOptions = ClientEnvConfig.LoadClientConnectOptions(); -connectOptions.TargetHost ??= "localhost:7233"; -connectOptions.LoggerFactory = loggerFactory; -connectOptions.Interceptors = new[] { new TracingInterceptor() }; -connectOptions.Runtime = new TemporalRuntime(new TemporalRuntimeOptions() -{ - Telemetry = new TelemetryOptions() - { - Metrics = new MetricsOptions() - { - OpenTelemetry = new OpenTelemetryOptions() - { - Url = new Uri("http://localhost:4317"), - }, - }, - Logging = new LoggingOptions() - { - // Core SDK logs default to WARN; lowered here so there is more to see. - Filter = new TelemetryFilterOptions(core: TelemetryFilterOptions.Level.Info), - - // The Core SDK writes its logs to the console itself unless Forwarding is set, in - // which case they go to this ILogger instead. - Forwarding = new LogForwardingOptions(loggerFactory.CreateLogger("Temporalio.Core")), - }, - }, -}); +// The Cloud Run Id plugin sets the client identity to "{instanceId}@{revision}" from Cloud Run +// metadata at connect time; every Worker created from the client inherits it. +connectOptions.Plugins = new ITemporalClientPlugin[] { new CloudRunIdPlugin() }; + +// ApplyGoogleCloudRunOpenTelemetryDefaults adds the tracing interceptor and a runtime exporting Core +// metrics + traces over OTLP to the collector sidecar; the returned handle owns the tracer provider. +// Both plugins configure the same connect options. +using var telemetry = connectOptions.ApplyGoogleCloudRunOpenTelemetryDefaults(); + var client = await TemporalClient.ConnectAsync(connectOptions); ``` -The [OpenTelemetry sample](https://github.com/temporalio/samples-dotnet/tree/main/src/OpenTelemetry) shows the tracing, metrics, and log-export configuration. Its Docker Compose file runs the .NET Aspire Dashboard locally and exposes its OTLP endpoint on port `4317`; it does not define a Cloud Run sidecar. Configure your Cloud Run sidecar to export the received telemetry to your backend. +After the Worker stops, call `telemetry.FlushAsync(TimeSpan.FromSeconds(2))` to flush traces within the Cloud Run +termination window. For the Collector sidecar configuration and deployment steps, see the +[.NET Cloud Run sample](https://github.com/temporalio/samples-dotnet/tree/gcp-cloud-run/src/Gcp/CloudRun). ## Set a Worker identity {/* #worker-identity */} Use `CloudRunIdPlugin` to identify each Worker instance as `@`. The plugin reads Cloud Run environment variables and instance metadata when the Client connects, then Workers created from that Client inherit the identity. - -[src/Gcp/CloudRun/Id/Program.cs](https://github.com/temporalio/samples-dotnet/blob/main/src/Gcp/CloudRun/Id/Program.cs) -```cs -var address = GetEnvironmentVariable("TEMPORAL_ADDRESS") ?? "localhost:7233"; -var temporalNamespace = GetEnvironmentVariable("TEMPORAL_NAMESPACE") ?? "default"; -var taskQueue = GetEnvironmentVariable("TEMPORAL_TASK_QUEUE") ?? "cloud-run-worker-sample"; - -using var loggerFactory = LoggerFactory.Create(builder => builder. - AddSimpleConsole(options => options.TimestampFormat = "[HH:mm:ss] "). - SetMinimumLevel(LogLevel.Information)); -var logger = loggerFactory.CreateLogger("CloudRunId"); - -// Derives the client identity "{instanceId}@{revision}" from Cloud Run metadata at connect time. -var clientOptions = new TemporalClientConnectOptions(address) -{ - Namespace = temporalNamespace, - LoggerFactory = loggerFactory, - Plugins = new[] { new CloudRunIdPlugin() }, -}; - -var client = await TemporalClient.ConnectAsync(clientOptions); -``` - +The preceding example registers `CloudRunIdPlugin` alongside the OpenTelemetry defaults. -The plugin requires the Cloud Run metadata server, so it fails when the Worker runs outside Cloud Run. For a complete example, see the [.NET Cloud Run Id sample](https://github.com/temporalio/samples-dotnet/pull/219). +The plugin requires the Cloud Run metadata server, so it fails when the Worker runs outside Cloud Run. For a complete example, see the [.NET Cloud Run sample](https://github.com/temporalio/samples-dotnet/tree/gcp-cloud-run/src/Gcp/CloudRun). diff --git a/docs/develop/dotnet/workers/serverless-workers/index.mdx b/docs/develop/dotnet/workers/serverless-workers/index.mdx index 5c880df30b..edbcb3a5e8 100644 --- a/docs/develop/dotnet/workers/serverless-workers/index.mdx +++ b/docs/develop/dotnet/workers/serverless-workers/index.mdx @@ -14,10 +14,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - AWS Lambda support is in Public Preview. GCP Cloud Run support is in Pre-release, and its APIs may change in - backwards-incompatible ways. To request Cloud Run access, create a [support ticket](/evaluate/cloud/support#support-ticket) or - contact your account team, and [sign up for updates](https://temporal.io/pages/serverless-workers-updates) to hear - when Cloud Run reaches Public Preview. + AWS Lambda and GCP Cloud Run support are in Public Preview. Serverless Workers run on ephemeral, on-demand compute rather than long-lived processes. diff --git a/docs/develop/go/workers/serverless-workers/cloud-run.mdx b/docs/develop/go/workers/serverless-workers/cloud-run.mdx index 3daace3211..d9154d8f08 100644 --- a/docs/develop/go/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/go/workers/serverless-workers/cloud-run.mdx @@ -15,9 +15,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - Cloud Run support is in Pre-release, and its APIs may change in backwards-incompatible ways. - Create a [support ticket](/evaluate/cloud/support#support-ticket) or contact your account team for access, and - [sign up for updates](https://temporal.io/pages/serverless-workers-updates) to hear when Cloud Run reaches Public Preview. + Cloud Run support is in Public Preview. On a [GCP Cloud Run worker pool](https://cloud.google.com/run/docs/resource-model#worker-pools), you run a standard long-lived Temporal Worker. @@ -116,40 +114,43 @@ For how scale-in decisions are made, see [Serverless Workers on GCP Cloud Run](/ Run an OpenTelemetry Collector as a sidecar in the Worker Pool. The Cloud Run OpenTelemetry plugin exports metrics and traces by OTLP gRPC to the Collector at `localhost:4317`. By default, it derives the service name from `OTEL_SERVICE_NAME`, `CLOUD_RUN_WORKER_POOL`, or `K_SERVICE`. -Create the plugin before connecting, then add it to the Client options. Client plugins that implement `worker.Plugin` also apply to Workers created from that Client: +Create both Cloud Run plugins before connecting, then add them to the Client options. Client plugins that implement +`worker.Plugin` also apply to Workers created from that Client: - -[gcp/cloudrun/otel/worker/main.go](https://github.com/temporalio/samples-go/blob/main/gcp/cloudrun/otel/worker/main.go) + +[gcp/cloudrun/worker/main.go](https://github.com/temporalio/samples-go/blob/gcp-cloud-run/gcp/cloudrun/worker/main.go) ```go // ... + // Exports OTLP metrics and traces to the collector sidecar (defaults to localhost:4317). otelPlugin, err := otel.NewPlugin(ctx, otel.PluginOptions{}) if err != nil { log.Fatalln("Unable to create OpenTelemetry plugin", err) } + // Sets the client identity to "@" from Cloud Run instance metadata. + idPlugin := id.NewCloudRunIDPlugin() // A client plugin that also implements worker.Plugin is applied to workers automatically. clientOptions, err := envconfig.LoadDefaultClientOptions() if err != nil { log.Fatalln("Unable to load Temporal client options", err) } - clientOptions.Plugins = append(clientOptions.Plugins, otelPlugin) + clientOptions.Plugins = append(clientOptions.Plugins, otelPlugin, idPlugin) c, err := client.Dial(clientOptions) if err != nil { log.Fatalln("Unable to create Temporal client", err) } + log.Println("Client identity:", idPlugin.Metadata().Identity()) ``` Configure the Collector sidecar to receive OTLP gRPC on `localhost:4317`, export traces to Google Cloud, and export metrics to Google Managed Service for Prometheus: - -[gcp/cloudrun/otel/otel-collector-config.yaml](https://github.com/temporalio/samples-go/blob/main/gcp/cloudrun/otel/otel-collector-config.yaml) + +[gcp/cloudrun/otel-collector-config.yaml](https://github.com/temporalio/samples-go/blob/gcp-cloud-run/gcp/cloudrun/otel-collector-config.yaml) ```yaml -# Collector sidecar: receives OTLP from the worker, adds GCP resource attributes, exports to Google Cloud. -# Metrics use googlemanagedprometheus with NO batch processor: batching can merge periodic and -# forced-shutdown snapshots of the same cumulative series into one Monitoring write, which Managed -# Service for Prometheus rejects as duplicate data. Traces may be batched independently. +# Google-Built OpenTelemetry Collector sidecar: metrics -> Managed Service for Prometheus, traces -> Cloud Trace. +# Auth uses the worker-pool service account (ADC). receivers: otlp: protocols: @@ -157,69 +158,79 @@ receivers: endpoint: localhost:4317 processors: - # Guard the sidecar against unbounded memory growth. memory_limiter: check_interval: 1s limit_percentage: 65 spike_limit_percentage: 20 - # Detect Google Cloud resource attributes (project, region, revision, ...). resourcedetection: detectors: [gcp] timeout: 10s - # Batch is used ONLY for traces. - batch: + # Batch traces for throughput. Do NOT batch the cumulative-metrics pipeline: a shutdown flush + # could be merged with a recent periodic export of the same series and rejected as a duplicate. + batch/traces: send_batch_size: 200 timeout: 5s + # Rename Temporal datapoint labels that collide with the target labels Managed Service for Prometheus injects (e.g. namespace). + transform/collision: + metric_statements: + - context: datapoint + statements: + - set(attributes["exported_location"], attributes["location"]) + - delete_key(attributes, "location") + - set(attributes["exported_cluster"], attributes["cluster"]) + - delete_key(attributes, "cluster") + - set(attributes["exported_namespace"], attributes["namespace"]) + - delete_key(attributes, "namespace") + - set(attributes["exported_job"], attributes["job"]) + - delete_key(attributes, "job") + - set(attributes["exported_instance"], attributes["instance"]) + - delete_key(attributes, "instance") + - set(attributes["exported_project_id"], attributes["project_id"]) + - delete_key(attributes, "project_id") + # The Telemetry API expects the Google Cloud project in gcp.project_id. + transform/set_project_id: + error_mode: ignore + trace_statements: + - set(resource.attributes["gcp.project_id"], resource.attributes["gcp.project.id"]) where resource.attributes["gcp.project.id"] != nil + - set(resource.attributes["gcp.project_id"], resource.attributes["cloud.account.id"]) where resource.attributes["gcp.project_id"] == nil and resource.attributes["cloud.account.id"] != nil exporters: - debug: googlemanagedprometheus: - googlecloud: + otlp_grpc: + endpoint: telemetry.googleapis.com:443 + compression: none + balancer_name: pick_first + auth: + authenticator: googleclientauth extensions: - # Startup probe; bind on all interfaces so Cloud Run can reach it. + googleclientauth: health_check: endpoint: 0.0.0.0:13133 service: - extensions: [health_check] + extensions: [googleclientauth, health_check] pipelines: - # No batch processor in the metrics pipeline. metrics: receivers: [otlp] - processors: [memory_limiter, resourcedetection] - exporters: [googlemanagedprometheus, debug] + processors: [memory_limiter, resourcedetection, transform/collision] + exporters: [googlemanagedprometheus] traces: receivers: [otlp] - processors: [memory_limiter, resourcedetection, batch] - exporters: [googlecloud, debug] + processors: [memory_limiter, resourcedetection, transform/set_project_id, batch/traces] + exporters: [otlp_grpc] telemetry: logs: level: info ``` -On shutdown, stop the Worker and call `otelPlugin.Shutdown` with a deadline shorter than Cloud Run's termination window so telemetry can flush. For a Collector configuration that exports traces to Google Cloud and metrics to Google Managed Service for Prometheus, see the [Go Cloud Run OpenTelemetry sample](https://github.com/temporalio/samples-go/pull/528). +On shutdown, stop the Worker and call `otelPlugin.Shutdown` with a deadline shorter than Cloud Run's termination window so telemetry can flush. For a Collector configuration that exports traces to Google Cloud and metrics to Google Managed Service for Prometheus, see the [Go Cloud Run sample](https://github.com/temporalio/samples-go/tree/gcp-cloud-run/gcp/cloudrun). ## Set a Worker identity {/* #worker-identity */} Use the Cloud Run Id plugin to identify each Worker instance as `@`. The plugin reads Cloud Run environment variables and instance metadata once when the Client connects, then Workers created from that Client inherit the identity. - -[gcp/cloudrun/id/worker/main.go](https://github.com/temporalio/samples-go/blob/main/gcp/cloudrun/id/worker/main.go) -```go -// ... - plugin := id.NewCloudRunIDPlugin() - c, err := client.Dial(client.Options{ - HostPort: getenv("TEMPORAL_ADDRESS", client.DefaultHostPort), - Namespace: getenv("TEMPORAL_NAMESPACE", client.DefaultNamespace), - Plugins: []client.Plugin{plugin}, - }) - if err != nil { - log.Fatalf("Unable to create Temporal client (is this running on Cloud Run?): %v", err) - } - defer c.Close() -``` - +The preceding example registers `id.NewCloudRunIDPlugin()` alongside the OpenTelemetry plugin. -The plugin requires the Cloud Run metadata server, so it fails when the Worker runs outside Cloud Run. For a complete example, see the [Go Cloud Run Id sample](https://github.com/temporalio/samples-go/pull/531). +The plugin requires the Cloud Run metadata server, so it fails when the Worker runs outside Cloud Run. For a complete example, see the [Go Cloud Run sample](https://github.com/temporalio/samples-go/tree/gcp-cloud-run/gcp/cloudrun). diff --git a/docs/develop/go/workers/serverless-workers/index.mdx b/docs/develop/go/workers/serverless-workers/index.mdx index a1c7a989df..1e8c774db3 100644 --- a/docs/develop/go/workers/serverless-workers/index.mdx +++ b/docs/develop/go/workers/serverless-workers/index.mdx @@ -14,10 +14,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - AWS Lambda support is in Public Preview. GCP Cloud Run support is in Pre-release, and its APIs may change in - backwards-incompatible ways. To request Cloud Run access, create a [support ticket](/evaluate/cloud/support#support-ticket) or - contact your account team, and [sign up for updates](https://temporal.io/pages/serverless-workers-updates) to hear - when Cloud Run reaches Public Preview. + AWS Lambda and GCP Cloud Run support are in Public Preview. Serverless Workers run on ephemeral, on-demand compute rather than long-lived processes. diff --git a/docs/develop/java/workers/serverless-workers/cloud-run.mdx b/docs/develop/java/workers/serverless-workers/cloud-run.mdx index 713cffa5e4..66ac030775 100644 --- a/docs/develop/java/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/java/workers/serverless-workers/cloud-run.mdx @@ -15,9 +15,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - Cloud Run support is in Pre-release, and its APIs may change in backwards-incompatible ways. - Create a [support ticket](/evaluate/cloud/support#support-ticket) or contact your account team for access, and - [sign up for updates](https://temporal.io/pages/serverless-workers-updates) to hear when Cloud Run reaches Public Preview. + Cloud Run support is in Public Preview. On a [GCP Cloud Run worker pool](https://cloud.google.com/run/docs/resource-model#worker-pools), you run a standard long-lived Temporal Worker. @@ -153,17 +151,18 @@ For how scale-in decisions are made, see [Serverless Workers on GCP Cloud Run](/ Run an OpenTelemetry Collector as a sidecar in the Worker Pool. The Cloud Run OpenTelemetry plugin exports metrics and traces by OTLP gRPC to the Collector at `localhost:4317`. It configures the endpoint and service name from Cloud Run defaults. -Create the plugin and register it on `WorkflowServiceStubsOptions` before you create the Client: +Create both Cloud Run plugins and register them on `WorkflowServiceStubsOptions` before you create the Client: - -[gcp/cloud-run/opentelemetry/src/main/java/io/temporal/samples/gcp/cloudrun/opentelemetry/CloudRunWorker.java](https://github.com/temporalio/samples-java/blob/main/gcp/cloud-run/opentelemetry/src/main/java/io/temporal/samples/gcp/cloudrun/opentelemetry/CloudRunWorker.java) + +[gcp/cloud-run/src/main/java/io/temporal/samples/gcp/cloudrun/CloudRunWorker.java](https://github.com/temporalio/samples-java/blob/gcp-cloud-run/gcp/cloud-run/src/main/java/io/temporal/samples/gcp/cloudrun/CloudRunWorker.java) ```java ClientConfigProfile profile = ClientConfigProfile.load(); -CloudRunOpenTelemetryPlugin telemetryPlugin = CloudRunOpenTelemetryPlugin.newBuilder().build(); +CloudRunOpenTelemetryPlugin otelPlugin = CloudRunOpenTelemetryPlugin.newBuilder().build(); +CloudRunIdPlugin idPlugin = new CloudRunIdPlugin(); WorkflowServiceStubsOptions serviceOptions = WorkflowServiceStubsOptions.newBuilder(profile.toWorkflowServiceStubsOptions()) - .setPlugins(telemetryPlugin) + .setPlugins(otelPlugin, idPlugin) .build(); WorkflowServiceStubs service = WorkflowServiceStubs.newServiceStubs(serviceOptions); ``` @@ -171,8 +170,8 @@ WorkflowServiceStubs service = WorkflowServiceStubs.newServiceStubs(serviceOptio Configure the Collector sidecar to receive OTLP gRPC on `localhost:4317`, export traces to Google Cloud, and export metrics to Google Managed Service for Prometheus: - -[gcp/cloud-run/opentelemetry/collector-config.yaml](https://github.com/temporalio/samples-java/blob/main/gcp/cloud-run/opentelemetry/collector-config.yaml) + +[gcp/cloud-run/collector-config.yaml](https://github.com/temporalio/samples-java/blob/gcp-cloud-run/gcp/cloud-run/collector-config.yaml) ```yaml receivers: otlp: @@ -262,30 +261,11 @@ service: ``` -On shutdown, stop the `WorkerFactory`, then run `telemetryPlugin.newFlushHook()` before the Cloud Run termination window ends. For a Collector configuration that exports traces to Google Cloud and metrics to Google Managed Service for Prometheus, see the [Java Cloud Run OpenTelemetry sample](https://github.com/temporalio/samples-java/pull/792). +On shutdown, stop the `WorkerFactory`, then run `otelPlugin.newFlushHook()` before the Cloud Run termination window ends. For a Collector configuration that exports traces to Google Cloud and metrics to Google Managed Service for Prometheus, see the [Java Cloud Run sample](https://github.com/temporalio/samples-java/tree/gcp-cloud-run/gcp/cloud-run). ## Set a Worker identity {/* #worker-identity */} -Use `CloudRunIdPlugin` to identify each Worker instance as `@`. Register the plugin on `WorkflowClientOptions` before creating the Client. Workers created from that Client inherit the identity. +Use `CloudRunIdPlugin` to identify each Worker instance as `@`. The preceding example registers the plugin on `WorkflowServiceStubsOptions` alongside the OpenTelemetry plugin. +Clients and Workers created from those service stubs inherit the identity. -[gcp/cloud-run/id/src/main/java/io/temporal/samples/gcp/cloudrun/id/CloudRunWorker.java](https://github.com/temporalio/samples-java/blob/main/gcp/cloud-run/id/src/main/java/io/temporal/samples/gcp/cloudrun/id/CloudRunWorker.java) -```java -String address = envOrDefault(ADDRESS_ENV, DEFAULT_ADDRESS); -String namespace = envOrDefault(NAMESPACE_ENV, DEFAULT_NAMESPACE); - -// Plaintext connection; add TLS or an API key here for Temporal Cloud. -WorkflowServiceStubs service = - WorkflowServiceStubs.newServiceStubs( - WorkflowServiceStubsOptions.newBuilder().setTarget(address).build()); - -// CloudRunIdPlugin sets the client identity to {instanceId}@{revision} from metadata. -WorkflowClient client = - WorkflowClient.newInstance( - service, - WorkflowClientOptions.newBuilder() - .setNamespace(namespace) - .setPlugins(new CloudRunIdPlugin()) - .build()); -``` - -The plugin requires Cloud Run metadata, so Client creation fails when the Worker runs outside Cloud Run. For a complete example, see the [Java Cloud Run Id sample](https://github.com/temporalio/samples-java/pull/795). +The plugin requires Cloud Run metadata, so Client creation fails when the Worker runs outside Cloud Run. For a complete example, see the [Java Cloud Run sample](https://github.com/temporalio/samples-java/tree/gcp-cloud-run/gcp/cloud-run). diff --git a/docs/develop/java/workers/serverless-workers/index.mdx b/docs/develop/java/workers/serverless-workers/index.mdx index df69936b3e..bf467aaf8a 100644 --- a/docs/develop/java/workers/serverless-workers/index.mdx +++ b/docs/develop/java/workers/serverless-workers/index.mdx @@ -14,10 +14,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - AWS Lambda support is in Public Preview. GCP Cloud Run support is in Pre-release, and its APIs may change in - backwards-incompatible ways. To request Cloud Run access, create a [support ticket](/evaluate/cloud/support#support-ticket) or - contact your account team, and [sign up for updates](https://temporal.io/pages/serverless-workers-updates) to hear - when Cloud Run reaches Public Preview. + AWS Lambda and GCP Cloud Run support are in Public Preview. Serverless Workers run on ephemeral, on-demand compute rather than long-lived processes. diff --git a/docs/develop/python/workers/serverless-workers/cloud-run.mdx b/docs/develop/python/workers/serverless-workers/cloud-run.mdx index 9d5bb64332..ca10502bc2 100644 --- a/docs/develop/python/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/python/workers/serverless-workers/cloud-run.mdx @@ -15,9 +15,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - Cloud Run support is in Pre-release, and its APIs may change in backwards-incompatible ways. - Create a [support ticket](/evaluate/cloud/support#support-ticket) or contact your account team for access, and - [sign up for updates](https://temporal.io/pages/serverless-workers-updates) to hear when Cloud Run reaches Public Preview. + Cloud Run support is in Public Preview. On a [GCP Cloud Run worker pool](https://cloud.google.com/run/docs/resource-model#worker-pools), you run a standard long-lived Temporal Worker. @@ -137,7 +135,7 @@ Create the plugin and pass it to `Client.connect`. The sample also registers `Cl reads its connection settings from the environment: -[gcp/cloud_run/worker.py](https://github.com/temporalio/samples-python/blob/main/gcp/cloud_run/worker.py) +[gcp/cloud_run/worker.py](https://github.com/temporalio/samples-python/blob/gcp-cloud-run/gcp/cloud_run/worker.py) ```py # OpenTelemetryPlugin exports Core metrics and traces to the collector # sidecar; CloudRunIdPlugin sets the client identity from instance metadata. @@ -155,7 +153,7 @@ client = await Client.connect( Configure the Collector sidecar to receive OTLP gRPC on `localhost:4317`, export traces to Google Cloud, and export metrics to Google Managed Service for Prometheus: -[gcp/cloud_run/collector-config.yaml](https://github.com/temporalio/samples-python/blob/main/gcp/cloud_run/collector-config.yaml) +[gcp/cloud_run/collector-config.yaml](https://github.com/temporalio/samples-python/blob/gcp-cloud-run/gcp/cloud_run/collector-config.yaml) ```yaml receivers: otlp: @@ -175,6 +173,7 @@ processors: resource_detection: detectors: [gcp] timeout: 10s + # Rename Temporal datapoint labels that collide with the target labels Managed Service for Prometheus injects (e.g. namespace). transform/collision: metric_statements: - context: datapoint @@ -191,6 +190,7 @@ processors: - delete_key(attributes, "instance") - set(attributes["exported_project_id"], attributes["project_id"]) - delete_key(attributes, "project_id") + # The Telemetry API expects the Google Cloud project in gcp.project_id. transform/set_project_id: error_mode: ignore trace_statements: @@ -226,7 +226,7 @@ service: ``` -Wait until the Collector accepts connections before starting the Worker. On shutdown, call `plugin.shutdown()` after the Worker stops so traces can flush. For a Collector configuration that exports traces to Google Cloud and metrics to Google Managed Service for Prometheus, see the [Python Cloud Run sample](https://github.com/temporalio/samples-python/pull/376). +Wait until the Collector accepts connections before starting the Worker. On shutdown, call `plugin.shutdown()` after the Worker stops so traces can flush. For a Collector configuration that exports traces to Google Cloud and metrics to Google Managed Service for Prometheus, see the [Python Cloud Run sample](https://github.com/temporalio/samples-python/tree/gcp-cloud-run/gcp/cloud_run). ## Set a Worker identity {/* #worker-identity */} @@ -235,4 +235,4 @@ on the Client alongside the OpenTelemetry plugin. It reads Cloud Run environment the Client connects, then Workers created from that Client inherit the identity. The Id plugin requires the Cloud Run metadata server, so it fails when the Worker runs outside Cloud Run. For a complete -example, see the [Python Cloud Run sample](https://github.com/temporalio/samples-python/pull/376). +example, see the [Python Cloud Run sample](https://github.com/temporalio/samples-python/tree/gcp-cloud-run/gcp/cloud_run). diff --git a/docs/develop/python/workers/serverless-workers/index.mdx b/docs/develop/python/workers/serverless-workers/index.mdx index 15ffdf5e8a..350b0ed3a6 100644 --- a/docs/develop/python/workers/serverless-workers/index.mdx +++ b/docs/develop/python/workers/serverless-workers/index.mdx @@ -14,8 +14,8 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - AWS Lambda support is in Public Preview. Support for GCP Cloud Run and Amazon Bedrock AgentCore Runtime is in - Pre-release. To request access to Pre-release compute providers on Temporal Cloud, create a + AWS Lambda and GCP Cloud Run support are in Public Preview. Amazon Bedrock AgentCore Runtime support is in + Pre-release. To request AgentCore Runtime access on Temporal Cloud, create a [support ticket](/evaluate/cloud/support#support-ticket) or contact your account team. You can also [sign up for updates](https://temporal.io/pages/serverless-workers-updates) or try them through self-hosting. diff --git a/docs/develop/ruby/workers/serverless-workers/cloud-run.mdx b/docs/develop/ruby/workers/serverless-workers/cloud-run.mdx index aea538d518..31529e39c5 100644 --- a/docs/develop/ruby/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/ruby/workers/serverless-workers/cloud-run.mdx @@ -15,9 +15,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - Cloud Run support is in Pre-release, and its APIs may change in backwards-incompatible ways. - Create a [support ticket](/evaluate/cloud/support#support-ticket) or contact your account team for access, and - [sign up for updates](https://temporal.io/pages/serverless-workers-updates) to hear when Cloud Run reaches Public Preview. + Cloud Run support is in Public Preview. On a [GCP Cloud Run worker pool](https://cloud.google.com/run/docs/resource-model#worker-pools), you run a standard long-lived Temporal Worker. diff --git a/docs/develop/ruby/workers/serverless-workers/index.mdx b/docs/develop/ruby/workers/serverless-workers/index.mdx index ae80911d2b..b30308e7af 100644 --- a/docs/develop/ruby/workers/serverless-workers/index.mdx +++ b/docs/develop/ruby/workers/serverless-workers/index.mdx @@ -14,9 +14,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - Cloud Run support is in Pre-release, and its APIs may change in backwards-incompatible ways. - Create a [support ticket](/evaluate/cloud/support#support-ticket) or contact your account team for access, and - [sign up for updates](https://temporal.io/pages/serverless-workers-updates) to hear when Cloud Run reaches Public Preview. + Cloud Run support is in Public Preview. Serverless Workers run on compute that Temporal starts and stops for you, rather than on long-lived processes you operate. diff --git a/docs/develop/rust/workers/serverless-workers/cloud-run.mdx b/docs/develop/rust/workers/serverless-workers/cloud-run.mdx index 1b4460b782..3687d3e21a 100644 --- a/docs/develop/rust/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/rust/workers/serverless-workers/cloud-run.mdx @@ -15,9 +15,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - Cloud Run support is in Pre-release, and its APIs may change in backwards-incompatible ways. - Create a [support ticket](/evaluate/cloud/support#support-ticket) or contact your account team for access, and - [sign up for updates](https://temporal.io/pages/serverless-workers-updates) to hear when Cloud Run reaches Public Preview. + Cloud Run support is in Public Preview. The code on this page is written against `temporalio-sdk` 1.0.0. diff --git a/docs/develop/rust/workers/serverless-workers/index.mdx b/docs/develop/rust/workers/serverless-workers/index.mdx index d8537d7288..9df7d7e368 100644 --- a/docs/develop/rust/workers/serverless-workers/index.mdx +++ b/docs/develop/rust/workers/serverless-workers/index.mdx @@ -14,9 +14,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - Cloud Run support is in Pre-release, and its APIs may change in backwards-incompatible ways. - Create a [support ticket](/evaluate/cloud/support#support-ticket) or contact your account team for access, and - [sign up for updates](https://temporal.io/pages/serverless-workers-updates) to hear when Cloud Run reaches Public Preview. + Cloud Run support is in Public Preview. Serverless Workers run on compute that Temporal starts and stops for you, rather than on long-lived processes you operate. diff --git a/docs/develop/typescript/workers/serverless-workers/cloud-run.mdx b/docs/develop/typescript/workers/serverless-workers/cloud-run.mdx index 73f172ec58..41170f7a1e 100644 --- a/docs/develop/typescript/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/typescript/workers/serverless-workers/cloud-run.mdx @@ -23,9 +23,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - Cloud Run support is in Pre-release, and its APIs may change in backwards-incompatible ways. - Create a [support ticket](/evaluate/cloud/support#support-ticket) or contact your account team for access, and - [sign up for updates](https://temporal.io/pages/serverless-workers-updates) to hear when Cloud Run reaches Public Preview. + Cloud Run support is in Public Preview. On a [GCP Cloud Run worker pool](https://cloud.google.com/run/docs/resource-model#worker-pools), you run a standard long-lived Temporal Worker. diff --git a/docs/develop/typescript/workers/serverless-workers/index.mdx b/docs/develop/typescript/workers/serverless-workers/index.mdx index 58f0b5af19..5c5907618e 100644 --- a/docs/develop/typescript/workers/serverless-workers/index.mdx +++ b/docs/develop/typescript/workers/serverless-workers/index.mdx @@ -14,10 +14,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - AWS Lambda support is in Public Preview. GCP Cloud Run support is in Pre-release, and its APIs may change in - backwards-incompatible ways. To request Cloud Run access, create a [support ticket](/evaluate/cloud/support#support-ticket) or - contact your account team, and [sign up for updates](https://temporal.io/pages/serverless-workers-updates) to hear - when Cloud Run reaches Public Preview. + AWS Lambda and GCP Cloud Run support are in Public Preview. Serverless Workers run on ephemeral, on-demand compute rather than long-lived processes. diff --git a/docs/encyclopedia/activities/standalone-activity.mdx b/docs/encyclopedia/activities/standalone-activity.mdx index 952b2ec1d9..298d2c897a 100644 --- a/docs/encyclopedia/activities/standalone-activity.mdx +++ b/docs/encyclopedia/activities/standalone-activity.mdx @@ -316,7 +316,7 @@ Your Activity code and Worker registration are unchanged. The Worker must belong Temporal knows what to invoke. AWS Lambda support is in [Public Preview](/evaluate/product-release-stages#public-preview) and -GCP Cloud Run is in [Pre-release](/evaluate/product-release-stages#pre-release). See +GCP Cloud Run is in [Public Preview](/evaluate/product-release-stages#public-preview). See [Deploy a Serverless Worker](/production-deployment/worker-deployments/serverless-workers). ## Standalone Activity versus Workflow Activity diff --git a/docs/encyclopedia/workers/serverless-workers/cloud-run.mdx b/docs/encyclopedia/workers/serverless-workers/cloud-run.mdx index e91551350b..3ba22b5a74 100644 --- a/docs/encyclopedia/workers/serverless-workers/cloud-run.mdx +++ b/docs/encyclopedia/workers/serverless-workers/cloud-run.mdx @@ -17,9 +17,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - Cloud Run support is in Pre-release, and its APIs may change in backwards-incompatible ways. - Create a [support ticket](/evaluate/cloud/support#support-ticket) or contact your account team for access, and - [sign up for updates](https://temporal.io/pages/serverless-workers-updates) to hear when Cloud Run reaches Public Preview. + Cloud Run support is in Public Preview. This page covers how Serverless Workers work on GCP Cloud Run, including the instance lifecycle, autoscaling behavior, and how Worker Versioning maps to Cloud Run Worker Pools. diff --git a/docs/encyclopedia/workers/serverless-workers/index.mdx b/docs/encyclopedia/workers/serverless-workers/index.mdx index f8b6dcf0d5..03ba412d13 100644 --- a/docs/encyclopedia/workers/serverless-workers/index.mdx +++ b/docs/encyclopedia/workers/serverless-workers/index.mdx @@ -14,8 +14,8 @@ tags: import { CaptionedImage, ReleaseNoteHeader } from '@site/src/components'; - AWS Lambda support is in Public Preview. Support for GCP Cloud Run and Amazon Bedrock AgentCore Runtime is in - Pre-release. To request access to Pre-release compute providers on Temporal Cloud, create a + AWS Lambda and GCP Cloud Run support are in Public Preview. Amazon Bedrock AgentCore Runtime support is in + Pre-release. To request AgentCore Runtime access on Temporal Cloud, create a [support ticket](/evaluate/cloud/support#support-ticket) or contact your account team. You can also [sign up for updates](https://temporal.io/pages/serverless-workers-updates) or try them through self-hosting. diff --git a/docs/evaluate/features/serverless-workers/index.mdx b/docs/evaluate/features/serverless-workers/index.mdx index 4931ff7c07..5fa150e213 100644 --- a/docs/evaluate/features/serverless-workers/index.mdx +++ b/docs/evaluate/features/serverless-workers/index.mdx @@ -13,8 +13,8 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - AWS Lambda support is in Public Preview. Support for GCP Cloud Run and Amazon Bedrock AgentCore Runtime is in - Pre-release. To request access to Pre-release compute providers on Temporal Cloud, create a + AWS Lambda and GCP Cloud Run support are in Public Preview. Amazon Bedrock AgentCore Runtime support is in + Pre-release. To request AgentCore Runtime access on Temporal Cloud, create a [support ticket](/evaluate/cloud/support#support-ticket) or contact your account team. You can also [sign up for updates](https://temporal.io/pages/serverless-workers-updates) or try them through self-hosting. diff --git a/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx b/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx index 63b4ebf918..3eeb55afb7 100644 --- a/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx +++ b/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx @@ -17,9 +17,7 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; - Cloud Run support is in Pre-release, and its APIs may change in backwards-incompatible ways. - Create a [support ticket](/evaluate/cloud/support#support-ticket) or contact your account team for access, and - [sign up for updates](https://temporal.io/pages/serverless-workers-updates) to hear when Cloud Run reaches Public Preview. + Cloud Run support is in Public Preview. This guide walks through deploying a Temporal [Serverless Worker](/serverless-workers) to a GCP Cloud Run Worker Pool. @@ -139,11 +137,11 @@ Python Worker setup, see [Serverless Workers on GCP Cloud Run - Python SDK](/dev package main import ( - "crypto/tls" "log" "os" "go.temporal.io/sdk/client" + "go.temporal.io/sdk/contrib/envconfig" "go.temporal.io/sdk/contrib/gcp/cloudrun/id" "go.temporal.io/sdk/worker" "go.temporal.io/sdk/workflow" @@ -152,13 +150,12 @@ import ( ) func main() { - c, err := client.Dial(client.Options{ - HostPort: os.Getenv("TEMPORAL_ADDRESS"), - Namespace: os.Getenv("TEMPORAL_NAMESPACE"), - ConnectionOptions: client.ConnectionOptions{TLS: &tls.Config{}}, - Credentials: client.NewAPIKeyStaticCredentials(os.Getenv("TEMPORAL_API_KEY")), - Plugins: []client.Plugin{id.NewCloudRunIDPlugin()}, - }) + clientOptions, err := envconfig.LoadDefaultClientOptions() + if err != nil { + log.Fatalln("Unable to load Temporal client options", err) + } + clientOptions.Plugins = append(clientOptions.Plugins, id.NewCloudRunIDPlugin()) + c, err := client.Dial(clientOptions) if err != nil { log.Fatalln("Unable to create client", err) } @@ -263,9 +260,9 @@ For more on the TypeScript Worker setup, see package example; import io.temporal.client.WorkflowClient; -import io.temporal.client.WorkflowClientOptions; import io.temporal.common.VersioningBehavior; import io.temporal.common.WorkerDeploymentVersion; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.gcp.cloudrun.id.CloudRunIdPlugin; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.serviceclient.WorkflowServiceStubsOptions; @@ -275,24 +272,17 @@ import io.temporal.worker.WorkerFactory; import io.temporal.worker.WorkerOptions; public class WorkerMain { - public static void main(String[] args) { - String apiKey = System.getenv("TEMPORAL_API_KEY"); + public static void main(String[] args) throws java.io.IOException { + ClientConfigProfile profile = ClientConfigProfile.load(); WorkflowServiceStubs service = WorkflowServiceStubs.newServiceStubs( - WorkflowServiceStubsOptions.newBuilder() - .setTarget(System.getenv("TEMPORAL_ADDRESS")) - .setEnableHttps(true) - .addApiKey(() -> apiKey) + WorkflowServiceStubsOptions.newBuilder(profile.toWorkflowServiceStubsOptions()) + .setPlugins(new CloudRunIdPlugin()) .build()); WorkflowClient client = - WorkflowClient.newInstance( - service, - WorkflowClientOptions.newBuilder() - .setNamespace(System.getenv("TEMPORAL_NAMESPACE")) - .setPlugins(new CloudRunIdPlugin()) - .build()); + WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); WorkerFactory factory = WorkerFactory.newInstance(client); @@ -328,16 +318,13 @@ Java Worker setup, see [Serverless Workers on GCP Cloud Run - Java SDK](/develop ```csharp using Temporalio.Client; +using Temporalio.Common.EnvConfig; using Temporalio.Extensions.Gcp.CloudRun.Id; using Temporalio.Worker; -var client = await TemporalClient.ConnectAsync(new(Environment.GetEnvironmentVariable("TEMPORAL_ADDRESS")!) -{ - Namespace = Environment.GetEnvironmentVariable("TEMPORAL_NAMESPACE")!, - ApiKey = Environment.GetEnvironmentVariable("TEMPORAL_API_KEY"), - Plugins = new[] { new CloudRunIdPlugin() }, - Tls = new(), -}); +var connectOptions = ClientEnvConfig.LoadClientConnectOptions(); +connectOptions.Plugins = new ITemporalClientPlugin[] { new CloudRunIdPlugin() }; +var client = await TemporalClient.ConnectAsync(connectOptions); var options = new TemporalWorkerOptions(Environment.GetEnvironmentVariable("TEMPORAL_TASK_QUEUE")!) { diff --git a/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/self-hosted-setup.mdx b/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/self-hosted-setup.mdx index d822119e83..0e4d4f6eb3 100644 --- a/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/self-hosted-setup.mdx +++ b/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/self-hosted-setup.mdx @@ -15,7 +15,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - APIs are experimental and may be subject to backwards-incompatible changes. + Cloud Run support is in Public Preview. Serverless Workers require Temporal Service v1.31.0 or later. diff --git a/docs/production-deployment/worker-deployments/serverless-workers/index.mdx b/docs/production-deployment/worker-deployments/serverless-workers/index.mdx index e429ed27c3..818e1a8723 100644 --- a/docs/production-deployment/worker-deployments/serverless-workers/index.mdx +++ b/docs/production-deployment/worker-deployments/serverless-workers/index.mdx @@ -15,8 +15,8 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - AWS Lambda support is in Public Preview. Support for GCP Cloud Run and Amazon Bedrock AgentCore Runtime is in - Pre-release. To request access to Pre-release compute providers on Temporal Cloud, create a + AWS Lambda and GCP Cloud Run support are in Public Preview. Amazon Bedrock AgentCore Runtime support is in + Pre-release. To request AgentCore Runtime access on Temporal Cloud, create a [support ticket](/evaluate/cloud/support#support-ticket) or contact your account team. You can also [sign up for updates](https://temporal.io/pages/serverless-workers-updates) or try them through self-hosting. diff --git a/docs/troubleshooting/serverless-workers/cloud-run.mdx b/docs/troubleshooting/serverless-workers/cloud-run.mdx index 03590babc9..11a285086d 100644 --- a/docs/troubleshooting/serverless-workers/cloud-run.mdx +++ b/docs/troubleshooting/serverless-workers/cloud-run.mdx @@ -17,9 +17,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - Cloud Run support is in Pre-release, and its APIs may change in backwards-incompatible ways. - Create a [support ticket](/evaluate/cloud/support#support-ticket) or contact your account team for access, and - [sign up for updates](https://temporal.io/pages/serverless-workers-updates) to hear when Cloud Run reaches Public Preview. + Cloud Run support is in Public Preview. This page walks through the Serverless Worker scaling flow on GCP Cloud Run and helps you identify where a failure is diff --git a/docs/troubleshooting/serverless-workers/index.mdx b/docs/troubleshooting/serverless-workers/index.mdx index 8facaee6fb..b5d924aef9 100644 --- a/docs/troubleshooting/serverless-workers/index.mdx +++ b/docs/troubleshooting/serverless-workers/index.mdx @@ -16,10 +16,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - AWS Lambda support is in Public Preview. GCP Cloud Run support is in Pre-release, and its APIs may change in - backwards-incompatible ways. To request Cloud Run access, create a [support ticket](/evaluate/cloud/support#support-ticket) or - contact your account team, and [sign up for updates](https://temporal.io/pages/serverless-workers-updates) to hear - when Cloud Run reaches Public Preview. + AWS Lambda and GCP Cloud Run support are in Public Preview. When a Serverless Worker is not running your Tasks, the failure is almost always in one of three places: the diff --git a/src/constants/featureReleaseTypes.js b/src/constants/featureReleaseTypes.js index 6519bcdf48..10b0716f1f 100644 --- a/src/constants/featureReleaseTypes.js +++ b/src/constants/featureReleaseTypes.js @@ -5,7 +5,7 @@ export const FEATURE_RELEASE_TYPES = { standaloneNexusOperation: "prerelease", workflowStreams: "publicPreview", serverlessWorkersLambda: "publicPreview", - serverlessWorkersCloudRun: "prerelease", + serverlessWorkersCloudRun: "publicPreview", externalStorage: "publicPreview", projects: "prerelease", }; From 51fc574e513b6dab36223fb03f7a6f4357a6529b Mon Sep 17 00:00:00 2001 From: "Lenny (Temporal)" Date: Wed, 30 Sep 2026 12:53:23 -0700 Subject: [PATCH 08/12] Add concise Cloud Run identity examples and heading links --- .../workers/serverless-workers/cloud-run.mdx | 9 ++++++++- .../go/workers/serverless-workers/cloud-run.mdx | 9 ++++++++- .../workers/serverless-workers/cloud-run.mdx | 15 +++++++++++++-- .../workers/serverless-workers/cloud-run.mdx | 17 +++++++++++++++-- 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx b/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx index b0b881c612..7c29116d31 100644 --- a/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx @@ -163,6 +163,13 @@ termination window. For the Collector sidecar configuration and deployment steps Use `CloudRunIdPlugin` to identify each Worker instance as `@`. The plugin reads Cloud Run environment variables and instance metadata when the Client connects, then Workers created from that Client inherit the identity. -The preceding example registers `CloudRunIdPlugin` alongside the OpenTelemetry defaults. +Register the plugin on the Client options before connecting: + +```csharp +connectOptions.Plugins = new ITemporalClientPlugin[] { new CloudRunIdPlugin() }; +var client = await TemporalClient.ConnectAsync(connectOptions); +``` + +The [preceding example](#opentelemetry) registers `CloudRunIdPlugin` alongside the OpenTelemetry defaults. The plugin requires the Cloud Run metadata server, so it fails when the Worker runs outside Cloud Run. For a complete example, see the [.NET Cloud Run sample](https://github.com/temporalio/samples-dotnet/tree/gcp-cloud-run/src/Gcp/CloudRun). diff --git a/docs/develop/go/workers/serverless-workers/cloud-run.mdx b/docs/develop/go/workers/serverless-workers/cloud-run.mdx index d9154d8f08..d1db3a3dcd 100644 --- a/docs/develop/go/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/go/workers/serverless-workers/cloud-run.mdx @@ -231,6 +231,13 @@ On shutdown, stop the Worker and call `otelPlugin.Shutdown` with a deadline shor Use the Cloud Run Id plugin to identify each Worker instance as `@`. The plugin reads Cloud Run environment variables and instance metadata once when the Client connects, then Workers created from that Client inherit the identity. -The preceding example registers `id.NewCloudRunIDPlugin()` alongside the OpenTelemetry plugin. +Register the plugin on the Client options before connecting: + +```go +clientOptions.Plugins = append(clientOptions.Plugins, id.NewCloudRunIDPlugin()) +c, err := client.Dial(clientOptions) +``` + +The [preceding example](#opentelemetry) registers `id.NewCloudRunIDPlugin()` alongside the OpenTelemetry plugin. The plugin requires the Cloud Run metadata server, so it fails when the Worker runs outside Cloud Run. For a complete example, see the [Go Cloud Run sample](https://github.com/temporalio/samples-go/tree/gcp-cloud-run/gcp/cloudrun). diff --git a/docs/develop/java/workers/serverless-workers/cloud-run.mdx b/docs/develop/java/workers/serverless-workers/cloud-run.mdx index 66ac030775..14d257f15a 100644 --- a/docs/develop/java/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/java/workers/serverless-workers/cloud-run.mdx @@ -265,7 +265,18 @@ On shutdown, stop the `WorkerFactory`, then run `otelPlugin.newFlushHook()` befo ## Set a Worker identity {/* #worker-identity */} -Use `CloudRunIdPlugin` to identify each Worker instance as `@`. The preceding example registers the plugin on `WorkflowServiceStubsOptions` alongside the OpenTelemetry plugin. -Clients and Workers created from those service stubs inherit the identity. +Use `CloudRunIdPlugin` to identify each Worker instance as `@`. Register it on +`WorkflowServiceStubsOptions` before creating the service stubs. Clients and Workers created from those service stubs +inherit the identity: + +```java +WorkflowServiceStubsOptions serviceOptions = + WorkflowServiceStubsOptions.newBuilder(profile.toWorkflowServiceStubsOptions()) + .setPlugins(new CloudRunIdPlugin()) + .build(); +WorkflowServiceStubs service = WorkflowServiceStubs.newServiceStubs(serviceOptions); +``` + +The [preceding example](#opentelemetry) registers `CloudRunIdPlugin` alongside the OpenTelemetry plugin. The plugin requires Cloud Run metadata, so Client creation fails when the Worker runs outside Cloud Run. For a complete example, see the [Java Cloud Run sample](https://github.com/temporalio/samples-java/tree/gcp-cloud-run/gcp/cloud-run). diff --git a/docs/develop/python/workers/serverless-workers/cloud-run.mdx b/docs/develop/python/workers/serverless-workers/cloud-run.mdx index ca10502bc2..64a6ec7286 100644 --- a/docs/develop/python/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/python/workers/serverless-workers/cloud-run.mdx @@ -230,9 +230,22 @@ Wait until the Collector accepts connections before starting the Worker. On shut ## Set a Worker identity {/* #worker-identity */} -Use `CloudRunIdPlugin` to identify each Worker instance as `@`. The preceding example registers it -on the Client alongside the OpenTelemetry plugin. It reads Cloud Run environment variables and instance metadata when +Use `CloudRunIdPlugin` to identify each Worker instance as `@`. It reads Cloud Run environment variables and instance metadata when the Client connects, then Workers created from that Client inherit the identity. +Register the plugin when connecting the Client: + +```python +client = await Client.connect( + settings.address, + namespace=settings.namespace, + api_key=settings.api_key, + tls=settings.tls, + plugins=[CloudRunIdPlugin()], +) +``` + +The [preceding example](#opentelemetry) registers `CloudRunIdPlugin` alongside the OpenTelemetry plugin. + The Id plugin requires the Cloud Run metadata server, so it fails when the Worker runs outside Cloud Run. For a complete example, see the [Python Cloud Run sample](https://github.com/temporalio/samples-python/tree/gcp-cloud-run/gcp/cloud_run). From b9ea61f3feb022c560049943f2e48ded00fd4c02 Mon Sep 17 00:00:00 2001 From: "Lenny (Temporal)" Date: Wed, 30 Sep 2026 12:58:52 -0700 Subject: [PATCH 09/12] Include imports and connection setup in identity examples --- .../workers/serverless-workers/cloud-run.mdx | 5 +++++ .../go/workers/serverless-workers/cloud-run.mdx | 17 +++++++++++++++++ .../workers/serverless-workers/cloud-run.mdx | 8 ++++++++ .../workers/serverless-workers/cloud-run.mdx | 6 ++++++ 4 files changed, 36 insertions(+) diff --git a/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx b/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx index 7c29116d31..ddd9c20d86 100644 --- a/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx @@ -166,6 +166,11 @@ Use `CloudRunIdPlugin` to identify each Worker instance as `@@< Register the plugin on the Client options before connecting: ```go +import ( + "log" + + "go.temporal.io/sdk/client" + "go.temporal.io/sdk/contrib/envconfig" + "go.temporal.io/sdk/contrib/gcp/cloudrun/id" +) + +// In your Worker startup function: +clientOptions, err := envconfig.LoadDefaultClientOptions() +if err != nil { + log.Fatalln("Unable to load Temporal client options", err) +} clientOptions.Plugins = append(clientOptions.Plugins, id.NewCloudRunIDPlugin()) c, err := client.Dial(clientOptions) +if err != nil { + log.Fatalln("Unable to create Temporal client", err) +} +defer c.Close() ``` The [preceding example](#opentelemetry) registers `id.NewCloudRunIDPlugin()` alongside the OpenTelemetry plugin. diff --git a/docs/develop/java/workers/serverless-workers/cloud-run.mdx b/docs/develop/java/workers/serverless-workers/cloud-run.mdx index 14d257f15a..c82d18e343 100644 --- a/docs/develop/java/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/java/workers/serverless-workers/cloud-run.mdx @@ -270,11 +270,19 @@ Use `CloudRunIdPlugin` to identify each Worker instance as `@ Date: Wed, 30 Sep 2026 13:01:35 -0700 Subject: [PATCH 10/12] Use ID spelling in Cloud Run plugin prose --- .../go/workers/serverless-workers/cloud-run.mdx | 2 +- .../python/workers/serverless-workers/cloud-run.mdx | 2 +- .../serverless-workers/cloud-run/index.mdx | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/develop/go/workers/serverless-workers/cloud-run.mdx b/docs/develop/go/workers/serverless-workers/cloud-run.mdx index 8af161a058..d4197837c3 100644 --- a/docs/develop/go/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/go/workers/serverless-workers/cloud-run.mdx @@ -229,7 +229,7 @@ On shutdown, stop the Worker and call `otelPlugin.Shutdown` with a deadline shor ## Set a Worker identity {/* #worker-identity */} -Use the Cloud Run Id plugin to identify each Worker instance as `@`. The plugin reads Cloud Run environment variables and instance metadata once when the Client connects, then Workers created from that Client inherit the identity. +Use the Cloud Run ID plugin to identify each Worker instance as `@`. The plugin reads Cloud Run environment variables and instance metadata once when the Client connects, then Workers created from that Client inherit the identity. Register the plugin on the Client options before connecting: diff --git a/docs/develop/python/workers/serverless-workers/cloud-run.mdx b/docs/develop/python/workers/serverless-workers/cloud-run.mdx index 2e486801da..71fa4e3b7c 100644 --- a/docs/develop/python/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/python/workers/serverless-workers/cloud-run.mdx @@ -253,5 +253,5 @@ client = await Client.connect( The [preceding example](#opentelemetry) registers `CloudRunIdPlugin` alongside the OpenTelemetry plugin. -The Id plugin requires the Cloud Run metadata server, so it fails when the Worker runs outside Cloud Run. For a complete +The ID plugin requires the Cloud Run metadata server, so it fails when the Worker runs outside Cloud Run. For a complete example, see the [Python Cloud Run sample](https://github.com/temporalio/samples-python/tree/gcp-cloud-run/gcp/cloud_run). diff --git a/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx b/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx index 3eeb55afb7..7e4feb5f20 100644 --- a/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx +++ b/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx @@ -29,7 +29,7 @@ through the Cloud Run admin API as work arrives and drains. For how the pool sca Cloud Run runs a standard long-lived Worker, so no Cloud Run-specific handler is needed and any Temporal SDK can run on a Worker Pool. Serverless Workers require [Worker Versioning](/worker-versioning). The Go, Python, Java, and .NET examples -below also register a Cloud Run Id plugin to give each instance a distinct Worker Identity. +below also register a Cloud Run ID plugin to give each instance a distinct Worker Identity. ## Prerequisites {/* #prerequisites */} @@ -127,7 +127,7 @@ class MyWorkflow: ... ``` -The example uses the Cloud Run Id plugin to identify each Worker as `@`. For more on the +The example uses the Cloud Run ID plugin to identify each Worker as `@`. For more on the Python Worker setup, see [Serverless Workers on GCP Cloud Run - Python SDK](/develop/python/workers/serverless-workers/cloud-run). @@ -198,7 +198,7 @@ w := worker.New(c, os.Getenv("TEMPORAL_TASK_QUEUE"), worker.Options{ If a Version is set and neither is specified, registration panics with `workflow type does not have a versioning behavior`. -The example uses the Cloud Run Id plugin to identify each Worker as `@`. For more on the +The example uses the Cloud Run ID plugin to identify each Worker as `@`. For more on the Go Worker setup, see [Serverless Workers on GCP Cloud Run - Go SDK](/develop/go/workers/serverless-workers/cloud-run). @@ -310,7 +310,7 @@ Each Workflow must have a [versioning behavior](/worker-versioning#versioning-be `AUTO_UPGRADE`. Set it per Workflow with the `@WorkflowVersioningBehavior` annotation, or set a Worker-level default with `setDefaultVersioningBehavior` as shown above. -The example uses the Cloud Run Id plugin to identify each Worker as `@`. For more on the +The example uses the Cloud Run ID plugin to identify each Worker as `@`. For more on the Java Worker setup, see [Serverless Workers on GCP Cloud Run - Java SDK](/develop/java/workers/serverless-workers/cloud-run). @@ -344,7 +344,7 @@ Each Workflow must have a [versioning behavior](/worker-versioning#versioning-be `AutoUpgrade`. Set it per Workflow with `[Workflow(VersioningBehavior = ...)]`, or set a Worker-level default with `DefaultVersioningBehavior` as shown above. -The example uses the Cloud Run Id plugin to identify each Worker as `@`. For more on the +The example uses the Cloud Run ID plugin to identify each Worker as `@`. For more on the .NET Worker setup, see [Serverless Workers on GCP Cloud Run - .NET SDK](/develop/dotnet/workers/serverless-workers/cloud-run). @@ -448,7 +448,7 @@ For more on the Rust Worker setup, see -The Cloud Run Id plugins in the Go, Python, Java, and .NET examples require the Cloud Run metadata server. To run these +The Cloud Run ID plugins in the Go, Python, Java, and .NET examples require the Cloud Run metadata server. To run these Workers outside Cloud Run, omit the plugin registration and add it back before deploying. :::tip From 3479bea3dded38d09f9dc887c92f36cbff197f4e Mon Sep 17 00:00:00 2001 From: "Lenny (Temporal)" Date: Wed, 30 Sep 2026 13:17:52 -0700 Subject: [PATCH 11/12] Format handwritten Cloud Run identity examples as excerpts --- .../workers/serverless-workers/cloud-run.mdx | 8 ++++--- .../workers/serverless-workers/cloud-run.mdx | 23 ++++++++++--------- .../workers/serverless-workers/cloud-run.mdx | 16 +++++++------ .../workers/serverless-workers/cloud-run.mdx | 18 ++++++++------- 4 files changed, 36 insertions(+), 29 deletions(-) diff --git a/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx b/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx index ddd9c20d86..f0fb8f2124 100644 --- a/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx @@ -170,9 +170,11 @@ using Temporalio.Client; using Temporalio.Common.EnvConfig; using Temporalio.Extensions.Gcp.CloudRun.Id; -var connectOptions = ClientEnvConfig.LoadClientConnectOptions(); -connectOptions.Plugins = new ITemporalClientPlugin[] { new CloudRunIdPlugin() }; -var client = await TemporalClient.ConnectAsync(connectOptions); +// ... + var connectOptions = ClientEnvConfig.LoadClientConnectOptions(); + connectOptions.Plugins = new ITemporalClientPlugin[] { new CloudRunIdPlugin() }; + var client = await TemporalClient.ConnectAsync(connectOptions); + // ... ``` The [preceding example](#opentelemetry) registers `CloudRunIdPlugin` alongside the OpenTelemetry defaults. diff --git a/docs/develop/go/workers/serverless-workers/cloud-run.mdx b/docs/develop/go/workers/serverless-workers/cloud-run.mdx index d4197837c3..4537628ca5 100644 --- a/docs/develop/go/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/go/workers/serverless-workers/cloud-run.mdx @@ -242,17 +242,18 @@ import ( "go.temporal.io/sdk/contrib/gcp/cloudrun/id" ) -// In your Worker startup function: -clientOptions, err := envconfig.LoadDefaultClientOptions() -if err != nil { - log.Fatalln("Unable to load Temporal client options", err) -} -clientOptions.Plugins = append(clientOptions.Plugins, id.NewCloudRunIDPlugin()) -c, err := client.Dial(clientOptions) -if err != nil { - log.Fatalln("Unable to create Temporal client", err) -} -defer c.Close() +// ... + clientOptions, err := envconfig.LoadDefaultClientOptions() + if err != nil { + log.Fatalln("Unable to load Temporal client options", err) + } + clientOptions.Plugins = append(clientOptions.Plugins, id.NewCloudRunIDPlugin()) + c, err := client.Dial(clientOptions) + if err != nil { + log.Fatalln("Unable to create Temporal client", err) + } + defer c.Close() + // ... ``` The [preceding example](#opentelemetry) registers `id.NewCloudRunIDPlugin()` alongside the OpenTelemetry plugin. diff --git a/docs/develop/java/workers/serverless-workers/cloud-run.mdx b/docs/develop/java/workers/serverless-workers/cloud-run.mdx index c82d18e343..58d1fc06fb 100644 --- a/docs/develop/java/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/java/workers/serverless-workers/cloud-run.mdx @@ -276,13 +276,15 @@ import io.temporal.gcp.cloudrun.id.CloudRunIdPlugin; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.serviceclient.WorkflowServiceStubsOptions; -ClientConfigProfile profile = ClientConfigProfile.load(); -WorkflowServiceStubsOptions serviceOptions = - WorkflowServiceStubsOptions.newBuilder(profile.toWorkflowServiceStubsOptions()) - .setPlugins(new CloudRunIdPlugin()) - .build(); -WorkflowServiceStubs service = WorkflowServiceStubs.newServiceStubs(serviceOptions); -WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); +// ... + ClientConfigProfile profile = ClientConfigProfile.load(); + WorkflowServiceStubsOptions serviceOptions = + WorkflowServiceStubsOptions.newBuilder(profile.toWorkflowServiceStubsOptions()) + .setPlugins(new CloudRunIdPlugin()) + .build(); + WorkflowServiceStubs service = WorkflowServiceStubs.newServiceStubs(serviceOptions); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); + // ... ``` The [preceding example](#opentelemetry) registers `CloudRunIdPlugin` alongside the OpenTelemetry plugin. diff --git a/docs/develop/python/workers/serverless-workers/cloud-run.mdx b/docs/develop/python/workers/serverless-workers/cloud-run.mdx index 71fa4e3b7c..24319a7def 100644 --- a/docs/develop/python/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/python/workers/serverless-workers/cloud-run.mdx @@ -241,14 +241,16 @@ from temporalio.contrib.gcp.cloud_run.id import CloudRunIdPlugin from gcp.cloud_run.settings import load_settings -settings = load_settings() -client = await Client.connect( - settings.address, - namespace=settings.namespace, - api_key=settings.api_key, - tls=settings.tls, - plugins=[CloudRunIdPlugin()], -) +# ... + settings = load_settings() + client = await Client.connect( + settings.address, + namespace=settings.namespace, + api_key=settings.api_key, + tls=settings.tls, + plugins=[CloudRunIdPlugin()], + ) + # ... ``` The [preceding example](#opentelemetry) registers `CloudRunIdPlugin` alongside the OpenTelemetry plugin. From cb646ac9fbcd8a1290174ef6c69b4c7dbcac2d3b Mon Sep 17 00:00:00 2001 From: "Lenny (Temporal)" Date: Wed, 30 Sep 2026 13:41:50 -0700 Subject: [PATCH 12/12] Clarify Cloud Run Public Preview API stability --- docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx | 2 +- docs/develop/go/workers/serverless-workers/cloud-run.mdx | 2 +- docs/develop/java/workers/serverless-workers/cloud-run.mdx | 2 +- docs/develop/python/workers/serverless-workers/cloud-run.mdx | 2 +- docs/develop/ruby/workers/serverless-workers/cloud-run.mdx | 2 +- docs/develop/ruby/workers/serverless-workers/index.mdx | 2 +- docs/develop/rust/workers/serverless-workers/cloud-run.mdx | 2 +- docs/develop/rust/workers/serverless-workers/index.mdx | 2 +- .../develop/typescript/workers/serverless-workers/cloud-run.mdx | 2 +- docs/encyclopedia/workers/serverless-workers/cloud-run.mdx | 2 +- .../worker-deployments/serverless-workers/cloud-run/index.mdx | 2 +- .../serverless-workers/cloud-run/self-hosted-setup.mdx | 2 +- docs/troubleshooting/serverless-workers/cloud-run.mdx | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx b/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx index f0fb8f2124..34ee080b50 100644 --- a/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/dotnet/workers/serverless-workers/cloud-run.mdx @@ -15,7 +15,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - Cloud Run support is in Public Preview. + Cloud Run support is in Public Preview. APIs and configuration may change before the stable release. On a [GCP Cloud Run worker pool](https://cloud.google.com/run/docs/resource-model#worker-pools), you run a standard long-lived Temporal Worker. diff --git a/docs/develop/go/workers/serverless-workers/cloud-run.mdx b/docs/develop/go/workers/serverless-workers/cloud-run.mdx index 4537628ca5..610572c8ea 100644 --- a/docs/develop/go/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/go/workers/serverless-workers/cloud-run.mdx @@ -15,7 +15,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - Cloud Run support is in Public Preview. + Cloud Run support is in Public Preview. APIs and configuration may change before the stable release. On a [GCP Cloud Run worker pool](https://cloud.google.com/run/docs/resource-model#worker-pools), you run a standard long-lived Temporal Worker. diff --git a/docs/develop/java/workers/serverless-workers/cloud-run.mdx b/docs/develop/java/workers/serverless-workers/cloud-run.mdx index 58d1fc06fb..6cf82dc677 100644 --- a/docs/develop/java/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/java/workers/serverless-workers/cloud-run.mdx @@ -15,7 +15,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - Cloud Run support is in Public Preview. + Cloud Run support is in Public Preview. APIs and configuration may change before the stable release. On a [GCP Cloud Run worker pool](https://cloud.google.com/run/docs/resource-model#worker-pools), you run a standard long-lived Temporal Worker. diff --git a/docs/develop/python/workers/serverless-workers/cloud-run.mdx b/docs/develop/python/workers/serverless-workers/cloud-run.mdx index 24319a7def..8ee09b31c1 100644 --- a/docs/develop/python/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/python/workers/serverless-workers/cloud-run.mdx @@ -15,7 +15,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - Cloud Run support is in Public Preview. + Cloud Run support is in Public Preview. APIs and configuration may change before the stable release. On a [GCP Cloud Run worker pool](https://cloud.google.com/run/docs/resource-model#worker-pools), you run a standard long-lived Temporal Worker. diff --git a/docs/develop/ruby/workers/serverless-workers/cloud-run.mdx b/docs/develop/ruby/workers/serverless-workers/cloud-run.mdx index 31529e39c5..d1b92fc37c 100644 --- a/docs/develop/ruby/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/ruby/workers/serverless-workers/cloud-run.mdx @@ -15,7 +15,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - Cloud Run support is in Public Preview. + Cloud Run support is in Public Preview. APIs and configuration may change before the stable release. On a [GCP Cloud Run worker pool](https://cloud.google.com/run/docs/resource-model#worker-pools), you run a standard long-lived Temporal Worker. diff --git a/docs/develop/ruby/workers/serverless-workers/index.mdx b/docs/develop/ruby/workers/serverless-workers/index.mdx index b30308e7af..65bebe5497 100644 --- a/docs/develop/ruby/workers/serverless-workers/index.mdx +++ b/docs/develop/ruby/workers/serverless-workers/index.mdx @@ -14,7 +14,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - Cloud Run support is in Public Preview. + Cloud Run support is in Public Preview. APIs and configuration may change before the stable release. Serverless Workers run on compute that Temporal starts and stops for you, rather than on long-lived processes you operate. diff --git a/docs/develop/rust/workers/serverless-workers/cloud-run.mdx b/docs/develop/rust/workers/serverless-workers/cloud-run.mdx index 3687d3e21a..09ae528cf0 100644 --- a/docs/develop/rust/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/rust/workers/serverless-workers/cloud-run.mdx @@ -15,7 +15,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - Cloud Run support is in Public Preview. + Cloud Run support is in Public Preview. APIs and configuration may change before the stable release. The code on this page is written against `temporalio-sdk` 1.0.0. diff --git a/docs/develop/rust/workers/serverless-workers/index.mdx b/docs/develop/rust/workers/serverless-workers/index.mdx index 9df7d7e368..9d8dd73102 100644 --- a/docs/develop/rust/workers/serverless-workers/index.mdx +++ b/docs/develop/rust/workers/serverless-workers/index.mdx @@ -14,7 +14,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - Cloud Run support is in Public Preview. + Cloud Run support is in Public Preview. APIs and configuration may change before the stable release. Serverless Workers run on compute that Temporal starts and stops for you, rather than on long-lived processes you operate. diff --git a/docs/develop/typescript/workers/serverless-workers/cloud-run.mdx b/docs/develop/typescript/workers/serverless-workers/cloud-run.mdx index 41170f7a1e..119b3de717 100644 --- a/docs/develop/typescript/workers/serverless-workers/cloud-run.mdx +++ b/docs/develop/typescript/workers/serverless-workers/cloud-run.mdx @@ -23,7 +23,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - Cloud Run support is in Public Preview. + Cloud Run support is in Public Preview. APIs and configuration may change before the stable release. On a [GCP Cloud Run worker pool](https://cloud.google.com/run/docs/resource-model#worker-pools), you run a standard long-lived Temporal Worker. diff --git a/docs/encyclopedia/workers/serverless-workers/cloud-run.mdx b/docs/encyclopedia/workers/serverless-workers/cloud-run.mdx index 3ba22b5a74..047b9c5a26 100644 --- a/docs/encyclopedia/workers/serverless-workers/cloud-run.mdx +++ b/docs/encyclopedia/workers/serverless-workers/cloud-run.mdx @@ -17,7 +17,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - Cloud Run support is in Public Preview. + Cloud Run support is in Public Preview. APIs and configuration may change before the stable release. This page covers how Serverless Workers work on GCP Cloud Run, including the instance lifecycle, autoscaling behavior, and how Worker Versioning maps to Cloud Run Worker Pools. diff --git a/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx b/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx index 7e4feb5f20..a775c9d1e6 100644 --- a/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx +++ b/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/index.mdx @@ -17,7 +17,7 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; - Cloud Run support is in Public Preview. + Cloud Run support is in Public Preview. APIs and configuration may change before the stable release. This guide walks through deploying a Temporal [Serverless Worker](/serverless-workers) to a GCP Cloud Run Worker Pool. diff --git a/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/self-hosted-setup.mdx b/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/self-hosted-setup.mdx index 0e4d4f6eb3..e5975a8756 100644 --- a/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/self-hosted-setup.mdx +++ b/docs/production-deployment/worker-deployments/serverless-workers/cloud-run/self-hosted-setup.mdx @@ -15,7 +15,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - Cloud Run support is in Public Preview. + Cloud Run support is in Public Preview. APIs and configuration may change before the stable release. Serverless Workers require Temporal Service v1.31.0 or later. diff --git a/docs/troubleshooting/serverless-workers/cloud-run.mdx b/docs/troubleshooting/serverless-workers/cloud-run.mdx index 11a285086d..f98febfc4b 100644 --- a/docs/troubleshooting/serverless-workers/cloud-run.mdx +++ b/docs/troubleshooting/serverless-workers/cloud-run.mdx @@ -17,7 +17,7 @@ tags: import { ReleaseNoteHeader } from '@site/src/components'; - Cloud Run support is in Public Preview. + Cloud Run support is in Public Preview. APIs and configuration may change before the stable release. This page walks through the Serverless Worker scaling flow on GCP Cloud Run and helps you identify where a failure is