Connecting Cloud Run functions with Workflows
Workflows is a fully managed, serverless orchestration platform that executes services in an order you define - that ordered set of steps is the workflow. It acts as the central orchestrator for the service orchestration pattern: you design and deploy a workflow that combines Google Cloud services and API calls, including custom services or functions hosted on Cloud Run, into stateful, automated processes.
A workflow can connect a series of services together - HTTP services built with Cloud Run functions, external APIs, and other Cloud services like Cloud Run - so you can compose a flexible serverless application from small pieces.
- A workflow is a central source of truth for the application flow - the logic lives in one definition, not scattered across services.
- Each execution is logged and observable, making it easier to see the current state and troubleshoot issues.
- A workflow can hold state, retry, poll, or wait for up to a year, which enables long-running business processes.
Building the workflow
The steps to stand up a workflow that connects Cloud Run functions:
- Enable the required Google APIs for Cloud Run functions, Cloud Run, Workflows, and any other services you use.
- Create any service accounts required to access those services.
- Write and deploy the functions. These are HTTP functions with HTTP triggers that generate the URL endpoints used to invoke them.
- Test the functions individually with
curlor another HTTP client - and it is a best practice to test locally before deploying. - Create the workflow that connects the Cloud Run functions.
- Deploy and execute the workflow.
The workflow definition
A workflow is a series of steps written in the Workflows syntax, in either YAML or JSON. Functions are invoked from the workflow through HTTP requests, and the URLs to the functions are passed as arguments in each step.
The definition can also link an external REST API and connect a Cloud Run service, threading each result into the next step. The Cloud Run service's result becomes the result of the whole workflow:
Each step names its output with result: (e.g. cfn1_result), and later steps read it with a ${...} expression (${cfn1_result.body.xyz}). Misname a result or its reference and the downstream step gets no input - the chain is only as connected as these names.