Search code examples
amazon-cloudwatchaws-event-bridge

EventRule matched by default EventBridge EventBus ignored by custom EventBus


I have a Cloudformation template which implements a CI/CD process for Lambda functions (at bottom)

Essentially it -

  1. watches a Github repo
  2. pulls source code on new git tag creation
  3. starts a CodeBuild process which runs unit tests, zips source code (on test success) and pushes archive to S3
  4. enables CodeBuild notifications
  5. implements a CloudWatch EventRule to pattern match raw CodeBuild notifications, format and push them to SNS
  6. binds a Lambda function to SNS, which pushes the notifications to Slack via a webhook

This works fine with the default EventBridge EventBus, but the pattern matching seems to fail if I switch to a custom EventBus.

(see resources EventBus and EventRule in the stack; it's currently set up to use the custom EventBus, and fails / ignores new git tags; if you comment out the reference to property EventBusName in EventBus, it defaults to using the default EventBus and works)

Why would a custom EventBus behave differently to the default EventBus in this situation ?

---
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  AppName:
    Type: String
  RepoOwner:
    Type: String
  RepoName:
    Type: String
  RepoBranch:
    Type: String
    Default: master
  RepoAuth:
    Type: String
    Default: master
  WebhookUrl:
    Type: String
  WebhookLambda:
    Type: String
  CodeBuildBuildSpec:
    Type: String
  CodeBuildType:
    Type: String
    Default: LINUX_CONTAINER
  CodeBuildComputeType:
    Type: String
    Default: BUILD_GENERAL1_SMALL
  CodeBuildImage:
    Type: String
    Default: aws/codebuild/standard:4.0
  LambdaHandler:
    Type: String
    Default: "index.handler"
  LambdaMemory:
    Type: Number
    Default: 128
  LambdaTimeout:
    Type: Number
    Default: 30
  LambdaRuntime:
    Type: String
    Default: python3.8
Resources:
  ArtifactsBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName:
        Fn::Sub:
          - ${app_name}-lambda-artifacts
          - app_name:
              Ref: AppName
  CodeBuildProject:
    Properties:
      Environment:
        ComputeType:
          Ref: CodeBuildComputeType
        Image:
          Ref: CodeBuildImage
        Type:
          Ref: CodeBuildType
      Name:
        Fn::Sub:
          - ${app_name}-lambda-ci
          - app_name:
              Ref: AppName
      ServiceRole:
        Fn::GetAtt:
          - CodeBuildRole
          - Arn
      Source:
        Auth:
          Resource:
            Ref: RepoAuth
          Type: OAUTH
        Location:
          Fn::Sub:
            - "https://github.com/${repo_owner}/${repo_name}.git"
            - repo_owner:
                Ref: RepoOwner
              repo_name:
                Ref: RepoName
        Type: GITHUB
        BuildSpec:
          Fn::Sub:
            - "${build_spec}"
            - build_spec:
                Ref: CodeBuildBuildSpec
      Artifacts:
        Type: NO_ARTIFACTS
      SourceVersion:
        Ref: RepoBranch
      Triggers:
        Webhook: true
        FilterGroups:
          - - Type: EVENT
              Pattern: PUSH
              ExcludeMatchedPattern: false
            - Type: HEAD_REF
              Pattern: "refs/tags/.*"
              ExcludeMatchedPattern: false
    Type: AWS::CodeBuild::Project
  CodeBuildRole:
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: codebuild.amazonaws.com
        Version: '2012-10-17'
      Policies:
        - PolicyDocument:
            Statement:
              - Action:
                  - codebuild:*
                  - events:*
                  - s3:PutObject
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Effect: Allow
                Resource: '*'
            Version: '2012-10-17'
          PolicyName: code-build-role-policy
    Type: AWS::IAM::Role
  WebhookFunction:
    Properties:
      FunctionName:
        Fn::Sub:
          - ${app_name}-lambda-webhook
          - app_name:
              Ref: AppName
      Code:
        ZipFile:
          Ref: WebhookLambda
      Environment:
        Variables:
          WEBHOOK_URL:
            Ref: WebhookUrl
      Handler:
        Ref: LambdaHandler
      MemorySize:
        Ref: LambdaMemory
      Role:
        Fn::GetAtt:
          - WebhookFunctionRole
          - Arn
      Runtime:
        Ref: LambdaRuntime
      Timeout:
        Ref: LambdaTimeout
    Type: AWS::Lambda::Function
  WebhookFunctionRole:
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
        Version: '2012-10-17'
      Policies:
        - PolicyDocument:
            Statement:
              - Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Effect: Allow
                Resource: '*'
            Version: '2012-10-17'
          PolicyName: webhook-role-policy
    Type: AWS::IAM::Role
  WebhookFunctionPermission:
    Properties:
      Action: "lambda:InvokeFunction"
      FunctionName:
        Ref: WebhookFunction
      Principal: "sns.amazonaws.com"
      SourceArn:
        Ref: WebhookTopic
    Type: AWS::Lambda::Permission
  WebhookTopic:
    Properties:
      Subscription:
        - Protocol: lambda
          Endpoint:
            Fn::GetAtt:
              - WebhookFunction
              - Arn
    Type: AWS::SNS::Topic
  WebhookTopicPolicy:
    Properties:
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: "events.amazonaws.com"
            Action:
              - "sns:Publish"
            Resource:
              Ref: WebhookTopic
      Topics:
        - Ref: WebhookTopic
    Type: AWS::SNS::TopicPolicy
  EventBus:
    Type: AWS::Events::EventBus
    Properties:
      Name:
        Fn::Sub:
          - ${app_name}-bus
          - app_name:
              Ref: AppName
  EventRule:
    Type: AWS::Events::Rule
    Properties:
      EventBusName:  # CURRENTLY USING CUSTOM EVENT BUS (PATTERN MATCHING FAILS); REMOVE THIS PROPERTY TO SWITCH TO DEFAULT EVENT BUS (PATTERN MATCHING WORKS)
        Ref: EventBus
      EventPattern:
        source:
          - "aws.codebuild"
        detail-type:
          - "CodeBuild Build Phase Change"
        detail:
          completed-phase:
            - SUBMITTED
            - PROVISIONING
            - DOWNLOAD_SOURCE
            - INSTALL
            - PRE_BUILD
            - BUILD
            - POST_BUILD
            - UPLOAD_ARTIFACTS
            - FINALIZING
          completed-phase-status:
            - TIMED_OUT
            - STOPPED
            - FAILED
            - SUCCEEDED
            - FAULT
            - CLIENT_ERROR
          project-name:
            - Ref: CodeBuildProject
      State: ENABLED
      Targets:
        - Arn:
            Ref: WebhookTopic
          Id:
            Fn::Sub:
              - "${project_name}-codebuild-notifications"
              - project_name:
                  Ref: CodeBuildProject
          InputTransformer:
            InputPathsMap:
              build-id: "$.detail.build-id"
              project-name: "$.detail.project-name"
              completed-phase: "$.detail.completed-phase"
              completed-phase-status: "$.detail.completed-phase-status"
            InputTemplate: |
              "{'build-id': '<build-id>', 'project-name': '<project-name>', 'completed-phase': '<completed-phase>', 'completed-phase-status': '<completed-phase-status>'}"

Solution

  • "Custom event buses serve a use case of receiving events from your custom applications and services. Unfortunately, it is not possible for AWS services to push events to a custom event bus." (AWS Support)