In today’s cloud-native landscape, event-driven architectures are gaining traction for their flexibility and scalability. Amazon Web Services (AWS) offers a powerful combination of services to orchestrate events and serverless functions. In this guide, we’ll explore how to set up a Go Lambda function triggering an EventBridge event, which is then processed by another Go Lambda function displaying event details.

For this tutorial you need to have the aws cli and go installed on your machine.

First we create a directory called sender-go-lambda and init the Go module.

mkdir sender-go-lambda

cd sender-go-lambda

go mod init sender-go-lambda

The following snippet is our Go code for the Lambda Request Handler. You should put this in a file called main.go

package main

import (
  "context"
  "github.com/aws/aws-lambda-go/lambda"
  "github.com/aws/aws-sdk-go/aws/session"
  "github.com/aws/aws-sdk-go/aws"
  "github.com/aws/aws-sdk-go/service/eventbridge"
  "encoding/json"
  "errors"
)

type MyEvent struct {
  Message string `json:"message"`
}

func HandleRequest(ctx context.Context, name MyEvent) (string, error) {
  event := MyEvent{Message: "Hello, World!"}
  eventBytes, err := json.Marshal(event)

  if err != nil {
    return "error", errors.New(err.Error())
  }

  sess := session.Must(session.NewSession())
  svc := eventbridge.New(sess)
  putEventsInput := &eventbridge.PutEventsInput {
    Entries: []*eventbridge.PutEventsRequestEntry {
      {
        Detail:     aws.String(string(eventBytes)),
        DetailType:   aws.String("myEvent"),
        EventBusName: aws.String("our-cool-event-bus"),
        Source:     aws.String("myEventBridgeSource"),
      },
    },
  }

  _, err = svc.PutEvents(putEventsInput)


  if err != nil {
    return "error", errors.New(err.Error())
  }


  return "Done", nil
}

func main() {
  lambda.Start(HandleRequest)
}

In your command line tool write the following:

//following command will download all our dependencies
go mod tidy

mkdir -p dist

//here we compile the file for necessary runtime arm64 in AWS the output file has to be named bootstrap
env GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -tags lambda.norpc -ldflags="-s -w" -o ./dist/bootstrap main.go

chmod +x ./dist/bootstrap

//zip the created bootstrap file, in Windows do it manually
cd ./dist && zip bootstrap.zip bootstrap && cd ..

Now you have to create your lambda in the AWS management console or via CLI SenderGoLambda

Next we have to upload our zip file to our lambda function. You can do this either with the AWS cli or go to the AWS managment console and click on the Code Tab in the Lambda. On the right side you can upload the zip.

aws lambda update-function-code --function-name sender-go-lambda --zip-file fileb://./dist/bootstrap.zip

The lambda function has to be configured that it takes the correct entrypoint. This can be done on the Lambda Management in the Code tab when you scroll down to Runtime Settings and click on Edit Here you have to add bootstrap (the name of our binary) as Handler and then edit a second time and choose ARM64 as architecture. EditHandler

Then we are ready to create a custom event bus via the AWS management console.

EventBridge

Next we create a rule with the name ‘send-event-rule’ which will be triggered if an Event has the source ‘myEventBridgeSource’

aws events put-rule --name send-event-rule --event-pattern "{\"source\":[\"myEventBridgeSource\"]}"

After this is finished we need to add some additional stuff.

To allow our sender-go-lambda to put events to the event bus it needs the permission to do it. For that go to the lambda sender-go-lambda and click on the configuration tab. Left click on ‘Permissions’ AddPermission Under Role Name it displays the role which when you click brings you to IAM

IAM

Under Permission Policies you click on Add permissions > Add inline policy

InlinePolicy

Here you filter for service EventBridge, Actions PutEvents (which you check) and under resources add the ARN of your previously created eventbus

Now is the time where we can create our Receiver lambda which will be triggered by the event bus on incoming events. This Lambda will print out all the information of our event.

cd ..

mkdir receiver-go-lambda

cd receiver-go-lambda

go mod init receiver-go-lambda
package main

import (
  "context"
  "github.com/aws/aws-lambda-go/lambda"
  "github.com/aws/aws-lambda-go/events"
  "encoding/json"
  "fmt"
)

type MyEvent struct {
  Message string `json:"message"` 
}

func HandleRequest(ctx context.Context, event events.CloudWatchEvent) (string, error) {
  if err := json.Unmarshal(event.Detail, &event); err != nil {
    return "Error",err
  }
  fmt.Printf("Version: %s\n", event.Version)
    fmt.Printf("ID: %s\n", event.ID)
    fmt.Printf("DetailType: %s\n", event.DetailType)
    fmt.Printf("Source: %s\n", event.Source)
    fmt.Printf("AccountID: %s\n", event.AccountID)
    fmt.Printf("Time: %s\n", event.Time)
    fmt.Printf("Region: %s\n", event.Region)

    for _, resource := range event.Resources {
        fmt.Printf("Resource: %s\n", resource)
    }

    fmt.Printf("Detail: %+v\n", event.Detail)

  fmt.Printf("Version: %s\n", event.Detail)
    
  return "Done", nil
}

func main() {
  lambda.Start(HandleRequest)
}

For compiling and updating the lambda function do the following:

go mod tidy

go get github.com/aws/aws-lambda-go/lambda
go get github.com/aws/aws-sdk-go/aws

mkdir -p dist

env GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -tags lambda.norpc -ldflags="-s -w" -o ./dist/bootstrap main.go

chmod +x ./dist/bootstrap

cd ./dist && zip bootstrap.zip bootstrap && cd ..

aws lambda update-function-code --function-name receiver-go-lambda --zip-file fileb://./dist/bootstrap.zip

The lambda function has to be configured that it takes the correct entrypoint. This can be done on the Lambda Management in the Code tab when you scroll down to Runtime Settings and click on Edit Here you have to add bootstrap (the name of our binary) as Handler and then edit a second time and choose ARM64 as architecture.

EditHandler

Now we can create a target which we apply to our previous created rule. You have to change the Arn to the function ARN you created before for the receiver lambda.

aws events put-targets --rule send-event-rule --targets "Id"="1","Arn"="PUT_HERE_RECEIVER_LAMBDA_FUNCTION_ARN"

We also have to add an trigger in the Lambda console under configuration/triggers so that the lambda will be triggered by the EventBus. AddTrigger In the field Existing rules as we have a custom event bus the rule will not show up, so you have to copy the ARN directly from the rule which you can open in the EventBridge Managment console under rules when you select our custom event bus. Trigger

Now we are ready for testing. To do this select the sender-go-lambda in the Managment Console click on the Test Tab and without adjusting any other parameters click on the orange Test Button on the right. If everything works well you can now go to CloudWatch and click the LogGroup for our receiver-go-lambda. There you should see now log entries which print out all the information of the incoming event. If it doesnt work you have to go and test every part of our application. Test the sender-go-lambda. If green go to the EventBridge and Click on Send Events. Add the necessary information especially the Event source which we defined above for our rule and click on Send. If you still doesnt see entries in the cloudwatch log of the receiver lambda test the receiver lambda itself via the Lambda Test Tab. Check for errors with permissions or if you get errors regarding runtime invocation look if you did the compiling correctly, the output file is called bootstrap and the runtime is configured correctly with bootstrap as Request Handler and arm64 as architecture.

I hope you learned something today.