GCP for DevOps — Eventarc & Workflows
Eventarc & Workflows
Eventarc provides a unified eventing layer for routing events from Google Cloud services, SaaS, and custom sources to event-driven targets. Workflows orchestrates multi-step serverless workflows with conditional logic and error handling.
Event-Driven Architecture
GCP Event-Driven Architecture:
┌──────────────┐ ┌──────────┐ ┌──────────────────┐
│ Cloud Storage │───▶│ │───▶│ Cloud Functions │
│ (event) │ │ │ └──────────────────┘
├──────────────┤ │ │ ┌──────────────────┐
│ Pub/Sub │───▶│ Eventarc │───▶│ Cloud Run │
│ (message) │ │ │ └──────────────────┘
├──────────────┤ │ │ ┌──────────────────┐
│ Audit Logs │───▶│ │───▶│ Workflows │
│ (event) │ │ │ └──────────────────┘
├──────────────┤ │ │ ┌──────────────────┐
│ Custom App │───▶│ │───▶│ GKE Service │
│ (CloudEvent) │ └──────────┘ └──────────────────┘
└──────────────┘
Eventarc
Create an Eventarc Trigger
# Trigger Cloud Run on Cloud Storage events
$ gcloud eventarc triggers create storage-trigger \
--location=us-central1 \
--destination-run-service=my-processor \
--destination-run-region=us-central1 \
--event-filters="type=google.cloud.storage.object.v1.finalized" \
--event-filters="bucket=my-data-bucket" \
--service-account=my-sa@my-project.iam.gserviceaccount.com
# Trigger on Audit Log events
$ gcloud eventarc triggers create audit-trigger \
--location=us-central1 \
--destination-run-service=my-audit-handler \
--destination-run-region=us-central1 \
--event-filters="type=google.cloud.audit.log.v1.written" \
--event-filters="serviceName=storage.googleapis.com" \
--event-filters="methodName=storage.objects.create" \
--service-account=my-sa@my-project.iam.gserviceaccount.com
# List triggers
$ gcloud eventarc triggers list --location=us-central1
# Describe a trigger
$ gcloud eventarc triggers describe storage-trigger \
--location=us-central1
CloudEvent Format
Eventarc delivers events in CloudEvent format:
{
"specversion": "1.0",
"type": "google.cloud.storage.object.v1.finalized",
"source": "//storage.googleapis.com/projects/_/buckets/my-bucket",
"id": "1234567890",
"time": "2026-03-30T07:00:00.000Z",
"datacontenttype": "application/json",
"data": {
"name": "uploads/report.csv",
"bucket": "my-data-bucket",
"contentType": "text/csv",
"size": "2048"
}
}
Handle Events in Cloud Run
from flask import Flask, request
import json
app = Flask(__name__)
@app.route("/", methods=["POST"])
def handle_event():
event = request.get_json()
event_type = request.headers.get("Ce-Type")
event_source = request.headers.get("Ce-Source")
print(f"Event type: {event_type}")
print(f"Event source: {event_source}")
print(f"Event data: {json.dumps(event)}")
# Process the event
if event_type == "google.cloud.storage.object.v1.finalized":
bucket = event["bucket"]
name = event["name"]
print(f"New file: gs://{bucket}/{name}")
return "OK", 200
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8080)
Workflows
Workflow YAML Syntax
main:
params: [input]
steps:
- init:
assign:
- project_id: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
- bucket: ${input.bucket}
- filename: ${input.filename}
- validate_input:
switch:
- condition: ${filename == ""}
raise: "Filename cannot be empty"
- process_file:
call: http.get
args:
url: ${"https://storage.googleapis.com/storage/v1/b/" + bucket + "/o/" + filename}
auth:
type: OAuth2
result: file_metadata
- check_size:
switch:
- condition: ${int(file_metadata.body.size) > 10485760}
next: large_file_handler
- condition: true
next: small_file_handler
- large_file_handler:
call: http.post
args:
url: https://my-processor-abc123.a.run.app/process-large
body:
bucket: ${bucket}
filename: ${filename}
auth:
type: OIDC
result: processing_result
next: return_result
- small_file_handler:
call: http.post
args:
url: https://my-processor-abc123.a.run.app/process-small
body:
bucket: ${bucket}
filename: ${filename}
auth:
type: OIDC
result: processing_result
- return_result:
return: ${processing_result.body}
Deploy and Execute Workflows
# Deploy a workflow
$ gcloud workflows deploy file-processor \
--location=us-central1 \
--source=workflow.yaml \
--service-account=workflow-sa@my-project.iam.gserviceaccount.com
# Execute a workflow
$ gcloud workflows execute file-processor \
--location=us-central1 \
--data='{"bucket":"my-bucket","filename":"report.csv"}'
# List workflow executions
$ gcloud workflows executions list file-processor \
--location=us-central1
# Get execution details
$ gcloud workflows executions describe EXECUTION_ID \
--workflow=file-processor \
--location=us-central1
Error Handling in Workflows
main:
steps:
- try_step:
try:
call: http.post
args:
url: https://my-api.example.com/process
body:
data: "test"
result: api_response
retry:
predicate: ${default_retry_predicate}
max_retries: 3
backoff:
initial_delay: 1
max_delay: 60
multiplier: 2
except:
as: e
steps:
- log_error:
call: sys.log
args:
text: ${"Error: " + e.message}
severity: "ERROR"
- return_error:
return:
status: "error"
message: ${e.message}
Connect Eventarc to Workflows
# Trigger workflow on Cloud Storage events
$ gcloud eventarc triggers create storage-to-workflow \
--location=us-central1 \
--destination-workflow=file-processor \
--destination-workflow-location=us-central1 \
--event-filters="type=google.cloud.storage.object.v1.finalized" \
--event-filters="bucket=my-data-bucket" \
--service-account=my-sa@my-project.iam.gserviceaccount.com
Common Mistakes
| Mistake | Why It’s Wrong | Fix |
|---|---|---|
| No retry logic in Workflows | Transient failures cause job failure | Use retry with backoff |
| Missing service account | Trigger has no permission | Always specify --service-account |
| Ignoring event ordering | Events may arrive out of order | Design for idempotency |
| No dead-letter topic | Lost events on failure | Configure DLT for Pub/Sub triggers |
| Hardcoded URLs | Breaks across environments | Use project variables |
Quick Reference
| Command | Description |
|---|---|
gcloud eventarc triggers create |
Create trigger |
gcloud eventarc triggers list |
List triggers |
gcloud eventarc triggers delete |
Delete trigger |
gcloud workflows deploy |
Deploy workflow |
gcloud workflows execute |
Execute workflow |
gcloud workflows executions list |
List executions |
Next → Practice Exercises