Temporal AI Workflows: Production CI/CD Deploy
Table of Contents
Part 3 of 3. Read Part 1 for architecture and Part 2 for deployment.
Quick recap: Temporal’s server manages workflow state through four services (Frontend, History, Matching, Worker) while workers execute activities. Temporal persists every state transition to PostgreSQL and indexes it in Elasticsearch. After running this stack for months across AI pipelines, I have found these patterns separate reliable deployments from ones that keep you up at night. See Meet the Engineer.
Step 5: Configure Persistence & Retention
Temporal stores workflow history in PostgreSQL forever by default. Thirty days of retention covers most use cases. Configure Elasticsearch index lifecycle management to roll over indices at 30 days and delete at 90. Refer to the PostgreSQL documentation for backup strategies and the Elasticsearch guide for index lifecycle policies.
kubectl exec -it -n temporal deploy/temporal-server -- tctl workflow list --retention 30Step 6: Implement Saga Pattern for AI
The saga pattern guarantees data consistency across multi-step workflows. Fail a step, and every prior step gets compensated. The Part 2 worker demonstrates this: failed summarization triggers the compensation handler, rolling back generated text.
Use Cases in AI
- Multi-Model Pipelines: Generate with GPT-4o, translate with Llama 3, summarize with Claude; compensate everything if any step fails.
- Human-in-the-Loop: Wait for human approval post-generation, compensate if rejected.
- Multi-Database Updates: Update three databases with results, roll back all if one fails.
- Payment + Content: Charge customer, generate content, reverse payment if content generation fails.
Step 7: Security Configuration
Production requires mTLS between server and workers. Use cert-manager or OpenSSL, mount certificates as Kubernetes secrets, and configure Temporal with TLS environment variables. See the Temporal documentation for TLS configuration and the Kubernetes docs for cert-manager integration.
- name: TLS_ENABLED value: "true"- name: TLS_CERT_PATH value: /etc/tls/tls.crt- name: TLS_KEY_PATH value: /etc/tls/tls.keyCreate separate Temporal namespaces for different teams using tctl:
kubectl exec -it -n temporal deploy/temporal-server -- tctl namespace register --namespace ai-pipelines --owner eduardo --retention 30Restrict network access to Temporal ports with Kubernetes NetworkPolicies, allowing ingress only from worker pods. For more security hardening, see Securing AI Automation:
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: temporal-network-policy namespace: temporalspec: podSelector: matchLabels: app: temporal-server ingress: - from: - podSelector: matchLabels: app: temporal-ai-worker ports: - port: 7233 - port: 7234 - port: 7235Step 8: Monitoring with Prometheus
Temporal exposes Prometheus metrics on port 7233 by default. See the Prometheus documentation for scraping configuration. Target the server pod with a scrape job:
- job_name: 'temporal' kubernetes_sd_configs: - role: pod relabel_configs: - source_labels: [__meta_kubernetes_pod_label_app] action: keep regex: temporal-server - target_label: __address__ replacement: temporal-server.temporal.svc.cluster.local:7233Watch four key metrics: temporal_workflow_completed, temporal_activity_failed, temporal_task_queue_depth, temporal_worker_pollers. Alert on failed workflows and queue depth spikes.
Step 9: n8n → Temporal Hybrid Pattern
Run n8n’s visual editor alongside Temporal’s reliability engine. The handoff takes three steps: n8n triggers a Temporal workflow through an HTTP webhook (a small Flask or FastAPI proxy works if needed), Temporal executes the AI workflow with saga guarantees, then Temporal signals n8n on completion. Non-technical teams get reliable workflow triggers through n8n while engineers own the core logic in Temporal.
{ "nodes": [ { "type": "n8n-nodes-base.httpRequest", "name": "Trigger Temporal Workflow", "parameters": { "url": "http://temporal-proxy:8080/signal", "method": "POST", "body": { "prompt": "{{$json.prompt}}" } } }, { "type": "n8n-nodes-base.wait", "name": "Wait for Completion", "parameters": { "amount": 5, "unit": "minutes" } }, { "type": "n8n-nodes-base.httpRequest", "name": "Check Workflow Status", "parameters": { "url": "http://temporal-server:7233/namespaces/default/workflows/{{$json.workflowId}}" } } ]}CI/CD for Temporal Workers
Set up a GitHub Actions pipeline that builds, tests, and deploys workers on every push to main. It installs Python dependencies, runs pytest, builds a Docker image tagged with the commit SHA, pushes to your registry, then deploys the updated Kubernetes manifest.
name: Deploy Temporal Workeron: push: branches: [main]jobs: build-and-deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install dependencies run: pip install -r requirements.txt - name: Run tests run: pytest tests/ - name: Build and push image uses: docker/build-push-action@v5 with: context: . push: true tags: your-registry/temporal-ai-worker:${{ github.sha }} - name: Deploy to Kubernetes uses: azure/k8s-deploy@v4 with: namespace: temporal manifests: temporal-worker.yaml images: your-registry/temporal-ai-worker:${{ github.sha }}Access Temporal Web UI
Temporal ships with a web UI for workflow management. Expose it through an Ingress with TLS via cert-manager:
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: temporal-web namespace: temporal annotations: cert-manager.io/cluster-issuer: "letsencrypt-prod"spec: tls: - hosts: - temporal.yourdomain.com secretName: temporal-tls rules: - host: temporal.yourdomain.com http: paths: - path: / pathType: Prefix backend: service: name: temporal-server port: number: 7233Navigate to https://temporal.yourdomain.com to view running workflows, search history, and kill stuck executions.
Frequently Asked Questions
How do I migrate Temporal databases? Stop the server, backup PostgreSQL, restore on the new instance, update connection strings, and restart. Always test migrations on a staging cluster first.
Can I run Temporal without Elasticsearch? Yes, but you lose searchable visibility. Without it you can only list workflows by ID. For production with hundreds of daily executions, Elasticsearch is essential.
What is the difference between a workflow and an activity? A workflow orchestrates the overall process: sequence of steps, error handling. An activity is a single unit of work; calling an API, processing data. Activities are where business logic lives.
Next Steps
- Deploy manifests to your Kubernetes cluster with
kubectl apply -f . - Build and push the Python worker image to your container registry
- Set up Prometheus monitoring for workflow success rates and latency
- Configure alerts for failed workflows and high queue depth
- Review the n8n vs Temporal guide to pick the right tool for your team
For further reading, see the n8n vs Temporal comparison, Event-Driven AI Pipelines, and Kubernetes Security Best Practices.