AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: Notify subscribers of database updates via EventBridge Parameters: AppSyncEndpoint: Type: String AppSyncApiKey: Type: String Resources: OrdersEventBus: ## EventBridge Event Bus for processing orders Type: AWS::Events::EventBus Properties: Name: orders ApiDestination: ## EventBridge API destination pointing to AppSync API Type: AWS::Events::ApiDestination Properties: ConnectionArn: !GetAtt ApiDestinationConnection.Arn HttpMethod: POST InvocationEndpoint: !Ref AppSyncEndpoint ApiDestinationConnection: ## Connection for EventBridge API Destination Type: AWS::Events::Connection Properties: AuthorizationType: API_KEY AuthParameters: ApiKeyAuthParameters: ApiKeyName: x-api-key ApiKeyValue: !Ref AppSyncApiKey RouteToAppSyncRule: ## Route order status updates to AppSync endpoint Type: AWS::Events::Rule Properties: EventBusName: !GetAtt OrdersEventBus.Name EventPattern: source: - orders.system detail-type: - Order Status Update Targets: - Id: appsync-order-status-update Arn: !GetAtt ApiDestination.Arn RoleArn: !GetAtt EventBridgeRole.Arn DeadLetterConfig: Arn: !GetAtt DLQ.Arn InputTransformer: InputPathsMap: orderId: "$.detail.order-id" status: "$.detail.status" prevStatus: "$.detail.previous-status" updatedAt: "$.time" InputTemplate: | { "query": "mutation PublishStatusUpdate($orderId:ID!, $status:Status!, $prevStatus:Status, $updatedAt:AWSDateTime!) { publishStatusUpdate(orderId:$orderId, status:$status, prevStatus:$prevStatus, updatedAt:$updatedAt) { orderId status prevStatus updatedAt } }", "operationName": "PublishStatusUpdate", "variables": { "orderId": "<orderId>", "status": "<status>", "prevStatus": "<prevStatus>", "updatedAt": "<updatedAt>" } } DLQ: Type: AWS::SQS::Queue DLQPolicy: Type: AWS::SQS::QueuePolicy Properties: Queues: - !Ref DLQ PolicyDocument: Statement: - Action: "sqs:SendMessage" Effect: Allow Resource: !GetAtt DLQ.Arn Principal: Service: events.amazonaws.com Condition: ArnEquals: aws:SourceArn: !GetAtt RouteToAppSyncRule.Arn EventBridgeRole: ## Service role to invoke Api Destination Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: events.amazonaws.com Action: "sts:AssumeRole" Path: / Policies: - PolicyName: eventbridge-invoke-api-destination PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: events:InvokeApiDestination Resource: - !Sub "arn:aws:events:${AWS::Region}:${AWS::AccountId}:api-destination/${ApiDestination}/*" Outputs: OrdersEventBusArn: Value: !GetAtt OrdersEventBus.Arn Description: The ARN of OrdersEventBus OrdersEventBusName: Value: !GetAtt OrdersEventBus.Name Description: The Name OrdersEventBus