Run events and workflows
Route events, run state machines and workflows, and queue timed tasks with EventBridge, Step Functions, Cloud Tasks, Cloud Scheduler, Workflows and Event Grid against pogi.
pogi delivers events, runs state machines and workflows, and dispatches queued tasks, so you can test the logic that connects your services. You'll send an event through EventBridge to a queue, run a Step Functions state machine, run Google Cloud tasks, schedules and workflows, and publish to an Azure Event Grid topic.
Before you start
-
Start pogi in another terminal:
pogi start -
Load the settings that point your tools at pogi. The lines after
evalsign the Azure CLI (az) in to pogi, for the Event Grid section. Azure CLI explains them, and you can run them again:eval "$(pogi env)" export REQUESTS_CA_BUNDLE="$HOME/.pogi/certs/ca.pem" # pogi's CA; `pogi cert` prints its path export AZURE_CONFIG_DIR="$HOME/.pogi/azure" # keeps your own ~/.azure as it is az cloud show -n pogi > /dev/null 2>&1 || az cloud register -n pogi --endpoint-resource-manager https://localhost:7644/ az cloud set -n pogi --only-show-errors az login --service-principal -u 00000000-0000-0000-0000-000000000001 -p secret \ --tenant 00000000-0000-0000-0000-000000000000 --output none
You need the AWS CLI, gcloud, the Azure CLI and curl. No Docker needed.
AWS: EventBridge
You'll make a rule that sends matching events to an SQS queue, put one event that matches and one that doesn't, and receive the match.
-
Create a queue and read its ARN (the ID AWS gives a resource):
QUEUE_URL=$(aws sqs create-queue --queue-name matches --query QueueUrl --output text) QUEUE_ARN=$(aws sqs get-queue-attributes --queue-url $QUEUE_URL --attribute-names QueueArn --query Attributes.QueueArn --output text) echo $QUEUE_ARNOutput arn:aws:sqs:us-east-1:000000000000:matches -
Make a rule for events from
demo.app, and point it at the queue:aws events put-rule --name demo-rule --event-pattern '{"source":["demo.app"]}' aws events put-targets --rule demo-rule --targets "Id=1,Arn=$QUEUE_ARN"Output { "RuleArn": "arn:aws:events:us-east-1:000000000000:rule/demo-rule" } { "FailedEntryCount": 0, "FailedEntries": [] } -
Put two events. Only the first matches the rule:
aws events put-events --entries '[{"Source":"demo.app","DetailType":"order","Detail":"{\"id\":1}"}]' aws events put-events --entries '[{"Source":"other","DetailType":"order","Detail":"{\"id\":2}"}]'Output { "FailedEntryCount": 0, "Entries": [ { "EventId": "46ac0520-8442-476f-9074-66ca23e235f2" } ] } { "FailedEntryCount": 0, "Entries": [ { "EventId": "c85a68e1-9158-4191-9ef4-b5cc91d012bb" } ] } -
Receive from the queue. One message arrived:
aws sqs receive-message --queue-url $QUEUE_URL --wait-time-seconds 2 --max-number-of-messages 10 --query 'Messages[].Body' --output textOutput {"version":"0","id":"46ac0520-8442-476f-9074-66ca23e235f2","detail-type":"order","source":"demo.app","account":"000000000000","time":"2026-10-26T08:55:55Z","region":"us-east-1","resources":[],"detail":{"id":1}}
AWS: Step Functions
You'll make a state machine with a Choice state that picks a branch by order size, run it, and read the result.
-
Write the definition. Orders over 100 take the
Bigbranch:cat > machine.json <<'JSON' { "StartAt": "Check", "States": { "Check": { "Type": "Choice", "Choices": [{"Variable": "$.total", "NumericGreaterThan": 100, "Next": "Big"}], "Default": "Small" }, "Big": {"Type": "Pass", "Result": "big order", "End": true}, "Small": {"Type": "Pass", "Result": "small order", "End": true} } } JSON -
Create the state machine. The role can be any ARN:
MACHINE=$(aws stepfunctions create-state-machine --name orders --definition file://machine.json \ --role-arn arn:aws:iam::000000000000:role/sfn --query stateMachineArn --output text) echo $MACHINEOutput arn:aws:states:us-east-1:000000000000:stateMachine:orders -
Start an execution with a total of 42:
EXECUTION=$(aws stepfunctions start-execution --state-machine-arn $MACHINE --input '{"total":42}' --query executionArn --output text) -
Describe it:
aws stepfunctions describe-execution --execution-arn $EXECUTION --query '{status:status,output:output}'Output { "status": "SUCCEEDED", "output": "\"small order\"" }
Google Cloud: Cloud Tasks and Cloud Scheduler
You'll make a task queue whose task calls pogi's Pub/Sub API, so you can see the task run, and then a scheduled job. Name the location in each command: without an App Engine app, gcloud asks for --location, as it does on Google Cloud.
-
Make a topic and a subscription for the task to publish to:
gcloud pubsub topics create jobs gcloud pubsub subscriptions create jobs-sub --topic=jobsOutput Created topic [projects/pogi/topics/jobs]. Created subscription [projects/pogi/subscriptions/jobs-sub]. -
Make a queue:
gcloud tasks queues create orders --location=us-central1Output Created queue [us-central1/orders]. -
Add an HTTP task that publishes the message
hello(aGVsbG8=in base64) to the topic:gcloud tasks create-http-task --queue=orders --location=us-central1 \ --url=http://localhost:7644/v1/projects/pogi/topics/jobs:publish --method=POST \ --header=Content-Type:application/json --body-content='{"messages":[{"data":"aGVsbG8="}]}'Output Created task [projects/pogi/locations/us-central1/queues/orders/tasks/2068978760639546097]. -
Pull the message the task published:
sleep 3 gcloud pubsub subscriptions pull jobs-sub --auto-ackOutput ┌───────┬────────────┬──────────────┬────────────┬──────────────────┬────────────┐ │ DATA │ MESSAGE_ID │ ORDERING_KEY │ ATTRIBUTES │ DELIVERY_ATTEMPT │ ACK_STATUS │ ├───────┼────────────┼──────────────┼────────────┼──────────────────┼────────────┤ │ hello │ 1 │ │ │ │ SUCCESS │ └───────┴────────────┴──────────────┴────────────┴──────────────────┴────────────┘ -
Make a job that runs every day at 03:00, and list it:
gcloud scheduler jobs create http nightly --schedule="0 3 * * *" --uri=http://localhost:7644/_localstack/health --location=us-central1 \ --format='value(name,state)' gcloud scheduler jobs list --location=us-central1Output projects/pogi/locations/us-central1/jobs/nightly ENABLED ID LOCATION SCHEDULE (TZ) TARGET_TYPE STATE nightly us-central1 0 3 * * * (Etc/UTC) HTTP ENABLED
Google Cloud: Workflows
You'll deploy a workflow that builds a greeting, run it with an argument, and read the result.
-
Write the workflow:
cat > workflow.yaml <<'YAML' main: params: [args] steps: - greet: assign: - message: ${"Hello, " + args.name} - done: return: ${message} YAML -
Deploy it:
gcloud workflows deploy hello --source=workflow.yaml --location=us-central1 --format='value(name,state)'Output Waiting for operation [operation-7f177d3e016e8b0e08787785c30570dd] to complete... ....done. projects/pogi/locations/us-central1/workflows/hello ACTIVE -
Run it:
gcloud workflows run hello --location=us-central1 --data='{"name":"pogi"}'Output Waiting for execution [573527d5-f630-1041-4edb-0a5d85318453] to complete... done. argument: '{"name":"pogi"}' duration: 0.000081s endTime: '2026-10-26T08:56:05.825582Z' name: projects/pogi/locations/us-central1/workflows/hello/executions/573527d5-f630-1041-4edb-0a5d85318453 result: '"Hello, pogi"' startTime: '2026-10-26T08:56:05.825501Z' state: SUCCEEDED workflowRevisionId: 000001-9b3
Azure: Event Grid
You'll make a custom topic with a subscription that delivers to a Storage queue, publish an event, and read it from the queue. The topic and subscription are Azure Resource Manager (ARM) calls, so az makes them. The queue is Azure Storage, which uses the connection string from pogi env.
-
Make a resource group and a topic:
az group create --name demo --location eastus --output none az eventgrid topic create --resource-group demo --name orders --location eastus --query '{name:name,state:provisioningState,endpoint:endpoint}'Output { "endpoint": "https://orders.eventgrid.localhost:7644/api/events", "name": "orders", "state": "Succeeded" } -
Make the queue, then subscribe it to the topic.
azsplits the destination into ARM's two properties:resourceIdis the storage account, andqueueNamesits beside it:az storage queue create --name events --only-show-errors --output none SUB=$(az account show --query id --output tsv) az eventgrid event-subscription create --name to-queue \ --source-resource-id "/subscriptions/$SUB/resourceGroups/demo/providers/Microsoft.EventGrid/topics/orders" \ --endpoint-type storagequeue \ --endpoint "/subscriptions/$SUB/resourceGroups/demo/providers/Microsoft.Storage/storageAccounts/devstoreaccount1/queueServices/default/queues/events" \ --query '{name:name,state:provisioningState}'Output { "name": "to-queue", "state": "Succeeded" } -
Publish an event to the topic's own address, the
endpointfrom step 1. pogi's certificate covers it, socurlneeds--cacert. Anyaeg-sas-keyworks. The command prints the HTTP status:curl -s --cacert ~/.pogi/certs/ca.pem \ -o /dev/null -w "%{http_code}\n" -X POST https://orders.eventgrid.localhost:7644/api/events \ -H "aeg-sas-key: any" -H "content-type: application/json" \ -d '[{"id":"1","eventType":"order.created","subject":"orders/1","eventTime":"2026-10-25T00:00:00Z","data":{"total":42},"dataVersion":"1.0"}]'Output 200 -
Give pogi a moment to deliver, then read the queue. The event is base64 text in
content, so decode it:sleep 2 az storage message get --queue-name events --query '[0].content' --output tsv --only-show-errors | base64 --decode; echoOutput {"id":"1","topic":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/demo/providers/Microsoft.EventGrid/topics/orders","subject":"orders/1","eventType":"order.created","eventTime":"2026-10-25T00:00:00Z","data":{"total":42},"dataVersion":"1.0","metadataVersion":"1"}
Limits
- EventBridge: Pipes are a separate service (see the coverage page). A schedule with no input delivers
{}, where AWS sends a default notification. - Step Functions: distributed Map and redrive are not supported yet. Every real wait, a Wait state or a retry backoff, ends after at most 60 seconds, so a Wait of an hour ends after one minute.
- Cloud Tasks and Cloud Scheduler: App Engine tasks and targets, queue-level HTTP overrides and cron macros are not supported yet.
- Workflows:
parallelsteps, connectors (googleapis.*), callbacks and most of the longer tail of standard library functions are not supported yet. A step pogi can't run fails the execution with an error that names it.sys.logoutput is dropped and doesn't reach Cloud Logging. - Event Grid: hybrid connections and input schema mapping are not supported yet.
See the EventBridge and Scheduler, Step Functions, Cloud Tasks, Cloud Scheduler and Workflows and Event Grid rows in the coverage page.