Skip to main content

EventBridge Webhook Migration Runbook

Migrating a Shopify app's product/collection webhooks from HTTP delivery to EventBridge delivery.

Architecture

Shopify → Partner Event Source → Partner Event Bus → EventBridge Rules → SQS → Lambda
(accepted by CDK) (created by CDK)

Shopify sends all webhook events with detail-type: "shopifyWebhook". The actual topic (e.g., products/update) is in detail.metadata.X-Shopify-Topic. EventBridge rules use content filtering on this field to route product and collection events to separate SQS queues.

Each Shopify app gets its own partner event source and partner event bus. CDK accepts the partner event source (creating the bus) and attaches routing rules. All automated on cdk deploy — the only manual step is creating the source in Shopify's Partner Dashboard.

Prerequisites

  • PR #2597 infrastructure deployed (SQS queues, Lambda event source mappings)
  • Access to Shopify Partner Dashboard for the target app

Per-App Migration Steps

Each Shopify app needs its own EventBridge partner event source. Repeat these steps for each app.

Step 1: Create Partner Event Source in Shopify

  1. Go to Shopify Partner Dashboard > Apps > select the app
  2. Navigate to Configuration > Event Bridge
  3. Select the AWS region (us-east-1) and enter the AWS account ID
  4. Click Create source to generate a partner event source
  5. Copy the partner event source ARN (format: arn:aws:events:us-east-1::event-source/aws.partner/shopify.com/<app-id>/<source-name>)

This is the only manual step. Everything else is automated.

Step 2: Add ARN to Config and Deploy

Update infra/ecom/config/<env>.json:

{
"shopify": {
"eventbridge_arns": {
"<client_id>": "arn:aws:events:us-east-1::event-source/aws.partner/shopify.com/<app-id>/<source-name>"
}
}
}

The key is the Shopify app's client_id (API key). For dev environments with a single app, use "default" as the key instead — it acts as a fallback when no client_id match is found.

Deploy the CDK stack. CDK will:

  1. Accept the partner event source (creating the partner event bus automatically)
  2. Create EventBridge routing rules on the partner bus for product/collection events
  3. Pass the ARN map to the admin Lambda as SHOPIFY_EVENTBRIDGE_ARNS

Step 3: Re-register Webhooks Per Shop

For each shop using this app, re-save the API key in the Shopify app settings UI. This automatically:

  1. Lists existing webhooks (paginated, includes EventBridge endpoints)
  2. Deletes HTTP webhooks for EventBridge-eligible topics (products/, collections/)
  3. Re-registers them via EventBridge using the configured partner event source ARN
  4. Leaves HTTP-only topics unchanged (bulk_operations/finish, app/uninstalled)

Step 4: Verify

  1. Edit a product in the Shopify admin for a migrated shop
  2. Check the Shopify Partner Dashboard for a successful event-bridge delivery
  3. Check CloudWatch logs for the webhook worker Lambda — look for Processing SQS batch: source=product
  4. Verify a new webhook job appears with webhook_topic: "eventbridge-batch" and status COMPLETED

Manual Partner Event Source Acceptance (alternative to CDK)

If you need to accept a partner event source without deploying CDK:

AWS Console:

  1. Go to EventBridge > Partner event sources in us-east-1
  2. Find the source (status: Pending)
  3. Click Associate with event bus > Confirm

AWS CLI:

aws events create-event-bus \
--name "aws.partner/shopify.com/<app-id>/<source-name>" \
--event-source-name "aws.partner/shopify.com/<app-id>/<source-name>" \
--region us-east-1 --profile <env>

Note: you still need to deploy CDK after to create the routing rules on the bus.

Rollback

To revert a shop to HTTP webhooks:

  1. Remove the app's ARN from eventbridge_arns in config and redeploy
  2. Re-save the API key for the shop — webhooks will register via HTTP since no EventBridge ARN is configured

The SQS queues and partner event bus can remain deployed — they are inert when no routing rules deliver events.

IAM Notes

When has_existing_role=True (shared staging role), the webhook worker Lambda's role needs these permissions on the webhook queue ARNs:

  • sqs:ReceiveMessage
  • sqs:DeleteMessage
  • sqs:ChangeMessageVisibility
  • sqs:GetQueueAttributes

Queue ARNs are exported as CloudFormation outputs: ProductWebhookQueueArn, CollectionWebhookQueueArn.

In prod, has_existing_role=False so CDK auto-grants these permissions.