Integrating GitHub with AWS EventBridge

Integrating GitHub with AWS EventBridge

Ever since I saw this announcement, I've been dying to get a chance to set it up and play with it. That time is now!

We are giving GitHub Enterprise Managed Users a test run, which looks good!

Don't know what that is, then here is a summary!

GitHub Enterprise Managed Users allows enterprise members' user accounts to be controlled through an identity provider (IdP). The enterprise controls usernames, profile data, team membership, and repository access.

In the IdP, managed users can be assigned the roles of user, enterprise owner, or billing manager and can own organizations.

Managed user accounts can access and contribute to repositories within the enterprise but cannot create public content or collaborate with others. Enterprise owners can audit managed user account actions.

While browsing through the various configuration options, I was excited when I saw the following:-

Hooks

With the above setting, we can set up the following allowing us to suck all the cool events that our GitHub generates into the AWS ecosystem and act on them using native cloud services.

Only our imagination is going to hold us back here.

Flow

Time to give it a whirl!

Setup

Within the Event Bridge page in the AWS Console, we select "Quick Starts" and select the Inbound webhooks using Lambda function URLs option.

Inbound Webhook

On the next page, we click through the GitHub Set up tile.

GitHub Tile

Next, we select our custom Event Bus name, kick off a redirect to Cloudformation, accept that we will provision a public lambda, and CFN will do the rest.

NOTE:- We are protecting this public lambda with a complex password. This is one of the parameters of the CFN template. I'd suggest you do the same!

After a couple of minutes, we have our endpoint, which we cut and paste into our GitHub instance. Events are ready to flow!

Setup Webhook

For those interested, here is the resulting Cloudformation template.

AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: >
  github-webhook

  Amazon EventBridge Inbound webhooks using lambda fURLs CFN Template.

Parameters:
  GithubWebhookSecret:
    Type: String
    Description: Github webhook secret
    NoEcho: true
    AllowedPattern: ".+"

  EventBusName:
    Type: String
    Description: EventBridge event bus name
    Default: default

  LambdaInvocationThreshold:
    Type: String
    Description: Innovation Alarm Threshold for number of events in a 5 minute period.
    Default: 2000

Resources:
  WebhookSecretsManager:
    Type: AWS::SecretsManager::Secret
    Properties:
      Name: !Sub WebhookSecret-${AWS::StackName}
      Description: Secrets Manager for storing Webhook Secret
      SecretString: !Ref GithubWebhookSecret

  LambdaInvocationsAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmDescription: !Sub Alarm for ${AWS::StackName} - InboundWebhook Lambda for traffic spikes
      AlarmName: !Sub InboundWebhook-Lambda-Invocation-Alarm-${AWS::StackName}
      MetricName: Invocations
      Namespace: AWS/Lambda
      Statistic: Sum
      Period: "300"
      EvaluationPeriods: "2"
      Threshold: !Ref LambdaInvocationThreshold
      Dimensions:
        - Name: FunctionName
          Value: !Ref WebhookFunction
      ComparisonOperator: GreaterThanThreshold

  WebhookFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    DependsOn: WebhookSecretsManager
    Properties:
      FunctionName: !Sub [
          "InboundWebhook-Lambda-${ID}",
          ID: !Select [2, !Split ["/", !Ref AWS::StackId]],
        ] # Append the stack UUID
      CodeUri:
        Bucket: !Sub "eventbridge-inbound-webhook-templates-prod-${AWS::Region}"
        Key: "lambda-templates/github-lambdasrc.zip"
      Handler: app.lambda_handler
      Runtime: python3.8
      ReservedConcurrentExecutions: 10
      Environment:
        Variables:
          GITHUB_WEBHOOK_SECRET_ARN: !Ref WebhookSecretsManager
          EVENT_BUS_NAME: !Ref EventBusName
      MemorySize: 128
      Timeout: 100
      FunctionUrlConfig:
        AuthType: NONE
      Policies:
        - EventBridgePutEventsPolicy:
            EventBusName: !Ref EventBusName
        - Version: "2012-10-17"
          Statement:
            - Effect: Allow
              Action:
                - secretsmanager:DescribeSecret
                - secretsmanager:GetSecretValue
              Resource: !Ref WebhookSecretsManager

Outputs:
  FunctionUrlEndpoint:
    Description: "Webhhook Function URL Endpoint"
    Value: !GetAtt WebhookFunctionUrl.FunctionUrl

  LambdaFunctionName:
    Value: !Ref WebhookFunction

  LambdaFunctionARN:
    Description: Lambda function ARN.
    Value: !GetAtt WebhookFunction.Arn

Event Schema

One of the nice things about EventBridge is the schema discovery option. You can turn this on for any event bus, and it will chew through and drop the discovered schemas under the registry.

I've turned this on because I don't know what payloads we will get from GitHub.

Custom Eventbus

After a bit of time and action in the GitHub instance, we can see our workflow jobs have been discovered.

Discovered Schemas

Now we have our events and understand the patterns; we can start acting on those events.

Summary

In this post, we set up a custom AWS EventBridge Event Bus to receive all the events from our GitHub Enterprise Managed Users instance via Lambda.

In the next post, we will set up and do some cool stuff with Step Functions, and I'll explain what is happening in this diagram!

Step Function Flow Diagram

I hope this helps someone else.

Cheers

For more articles on GitHub click here!

Did you find this article valuable?

Support Stephen Jones by becoming a sponsor. Any amount is appreciated!