Skip to content

Workflow orchestration (Temporal)

Temporal is a durable workflow engine. You write ordinary functions, and Temporal makes sure they run to completion even when the process crashes, the network drops, or a step needs to wait hours for an external event. It handles retries, timeouts, state, and history automatically.

Peach hosts a Temporal service per codops. Your code connects to it the same way it connects to peach-models — with the same per-codops credential.

gRPC (external) temporal-grpc.<codops>.peach.ebu.io:443
gRPC (in-cluster) peach-codops-<codops>-temporal-frontend:7233
Web UI https://temporal.<codops>.peach.ebu.io
Default namespace default (7-day history retention)

Replace <codops> with your codops name.

Not yet on your codops? Use the test environment in the meantime

If your codops is not yet enabled for Temporal, you can start building and testing against the shared test environment on dev-2 while your deployment is being set up.

gRPC temporal-grpc.test.dev.peach.ebu.io:443
Web UI https://temporal.test.dev.peach.ebu.io
API key test:<token> — retrieve with --profile dev (see below)
Namespace default

When you move to your own codops, only two things change in your code:

  1. The hostname: test.dev.peach.ebu.io → <your-codops>.peach.ebu.io
  2. The API key prefix: test:<token> → <your-codops>:<token>

Everything else — SDK calls, namespace, TLS setup — stays identical.

Authentication

The gRPC endpoint uses the same {codops}:{token} bearer credential as peach-models. If you already call peach-models from outside the cluster, you already have the right token — set it as your Temporal api_key.

# Production
aws --profile prod secretsmanager get-secret-value \
  --secret-id codops-auth \
  --query SecretString --output text | jq -r '.<codops>'

# Dev / test codops
aws --profile dev secretsmanager get-secret-value \
  --secret-id codops-auth \
  --query SecretString --output text | jq -r '.test'

Your api_key is then <codops>:<token>.

In-cluster code can skip the public endpoint, TLS, and the credential entirely by connecting to the internal service name. Most Temporal workloads should run this way.

Connect — Python

import os
from temporalio.client import Client

# External (from outside the cluster, or from another cluster)
client = await Client.connect(
    "temporal-grpc.<codops>.peach.ebu.io:443",
    namespace="default",
    api_key=os.environ["TEMPORAL_API_KEY"],  # "<codops>:<token>"
    tls=True,
)

# In-cluster — no TLS, no key
client = await Client.connect(
    "peach-codops-<codops>-temporal-frontend:7233",
    namespace="default",
)

Install the SDK:

# pyproject.toml
dependencies = ["temporalio"]

Connect — Go

import (
    "crypto/tls"
    "os"
    "go.temporal.io/sdk/client"
)

// External
c, err := client.Dial(client.Options{
    HostPort:    "temporal-grpc.<codops>.peach.ebu.io:443",
    Namespace:   "default",
    Credentials: client.NewAPIKeyStaticCredentials(os.Getenv("TEMPORAL_API_KEY")),
    ConnectionOptions: client.ConnectionOptions{
        TLS: &tls.Config{},
    },
})

// In-cluster — no TLS, no key
c, err := client.Dial(client.Options{
    HostPort:  "peach-codops-<codops>-temporal-frontend:7233",
    Namespace: "default",
})

Web UI

https://temporal.<codops>.peach.ebu.io is protected by GitLab OAuth (same login as the rest of Peach). The Temporal Web UI has no authentication of its own, so the OAuth session is the only gate — anyone who can log in can read every workflow history and terminate running workflows. Treat it as a privileged surface.

Things worth knowing

  • Namespace default keeps histories for 7 days. Older runs are permanently gone. Need a different retention or a dedicated namespace? Ask the platform team.
  • The datastore is shared with Prefect on the same codops. Heavy load from either service affects the other.
  • The credential is per-codops, not per-user. Rotating it breaks every caller at the same time. If you store it in a pod, load it from an environment variable (the platform injects CODOPS_SECRET for you) rather than hardcoding it.
  • In-cluster workers need no public credential. A pod running inside the cluster connects directly to peach-codops-<codops>-temporal-frontend:7233 with no API key.