Eventarc acts as a universal event bus for Google Cloud, allowing services to react to events emitted by other Google Cloud services without direct integration.
Let’s see it in action. Imagine we have a Cloud Storage bucket, and whenever a new object is uploaded, we want to trigger a Cloud Run service to process that file.
First, we need our Cloud Run service. Here’s a simple Python Flask app that just prints the event data it receives:
from flask import Flask, request
app = Flask(__name__)
@app.route('/', methods=['POST'])
def index():
event_data = request.get_json()
print(f"Received event: {event_data}")
return 'Event processed!', 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)
Deploy this to Cloud Run:
gcloud run deploy process-uploaded-file \
--image gcr.io/your-project-id/your-image-name \
--platform managed \
--region us-central1 \
--allow-unauthenticated
Next, we need to create an Eventarc trigger. This trigger will listen for a specific event (object finalization in Cloud Storage) and route it to our Cloud Run service.
gcloud eventarc triggers create process-storage-object \
--location us-central1 \
--destination-run-service process-uploaded-file \
--destination-run-region us-central1 \
--event-filters="type=google.cloud.storage.object.v1.finalized" \
--event-filters="bucket=your-source-bucket-name" \
--service-account=YOUR_EVENTARC_SERVICE_ACCOUNT@your-project-id.iam.gserviceaccount.com
Here’s what’s happening:
--location us-central1: Where the trigger itself lives.--destination-run-service process-uploaded-file: The target Cloud Run service.--event-filters="type=google.cloud.storage.object.v1.finalized": This is the core of the event subscription. We’re telling Eventarc to listen for theobject.v1.finalizedevent. This event is published by Cloud Storage whenever a new object is successfully created or an existing one is overwritten.--event-filters="bucket=your-source-bucket-name": This is a qualifier. We only want to trigger on objects uploaded to a specific bucket. Without this, any object creation across all buckets in your project would trigger the event.--service-account: Eventarc needs permissions to read events from the source and invoke your Cloud Run service. You’ll need to create a service account for Eventarc and grant it roles likeroles/pubsub.subscriber(for receiving events) androles/run.invoker(for calling Cloud Run).
Now, upload a file to your-source-bucket-name:
echo "Hello Eventarc!" > test.txt
gsutil cp test.txt gs://your-source-bucket-name/
Check the logs of your process-uploaded-file Cloud Run service. You should see output similar to this:
Received event: {'bucket': 'your-source-bucket-name', 'name': 'test.txt', 'metageneration': '1', 'timeCreated': '2023-10-27T10:30:00.123Z', 'updated': '2023-10-27T10:30:00.123Z'}
The event data contains details about the object that was created.
Eventarc abstracts away the underlying message queues (like Pub/Sub) and the direct plumbing between services. It provides a unified API for eventing across Google Cloud. The type and source (implied by the bucket filter here) are the primary ways you specify what event you care about. Under the hood, when you create a trigger, Eventarc provisions a Pub/Sub topic for the specified event type and creates a Pub/Sub subscription for your destination service. It then configures the event publisher (e.g., Cloud Storage) to send events to that topic.
What most people don’t realize is how granular the event filtering can get and how this applies to debugging. While type and bucket are common, you can filter on object name prefixes and suffixes, content types, and even custom attributes for certain event sources. This allows you to create highly specific triggers that only fire when you expect them to, reducing unnecessary invocations and simplifying your application logic. For instance, you could filter for name="path/to/specific/file.json" or contentType="application/json".
The next step in mastering Eventarc is exploring custom event types and understanding how to set up event delivery retries and dead-letter queues.