Event Source - SNS



In this section we’ll walkthrough how to trigger your lambda function in response to SNS events. This overview is based on the SpartaApplication sample code if you’d rather jump to the end result.

Goal

Assume that we have an SNS topic that broadcasts notifications. We’ve been asked to write a lambda function that logs the Subject and Message text to CloudWatch logs for later processing.

Getting Started

We’ll start with an empty lambda function and build up the needed functionality.

func echoSNSEvent(event *json.RawMessage,
                  context *sparta.LambdaContext,
                  w http.ResponseWriter,
                  logger *logrus.Logger)
{
  logger.WithFields(logrus.Fields{
    "RequestID": context.AWSRequestID,
  }).Info("Request received")
}

Unmarshalling the SNS Event

Since the echoSNSEvent is expected to be triggered by SNS notifications, we will unmarshal the *json.RawMessage data into an SNS-specific event provided by Sparta via:

var lambdaEvent spartaSNS.Event
err := json.Unmarshal([]byte(*event), &lambdaEvent)
if err != nil {
  logger.Error("Failed to unmarshal event data: ", err.Error())
  http.Error(w, err.Error(), http.StatusInternalServerError)
}

SNS events are delivered in batches, via lists of EventRecords, so we’ll need to process each record.

for _, eachRecord := range lambdaEvent.Records {
  logger.WithFields(logrus.Fields{
    "Subject": eachRecord.Sns.Subject,
    "Message": eachRecord.Sns.Message,
  }).Info("SNS Event")
}

That’s enough to get the data into CloudWatch Logs.

Sparta Integration

With the core of the echoSNSEvent complete, the next step is to integrate the Go function with Sparta. This is performed by the appendSNSLambda function. Since the echoSNSEvent function doesn’t access any additional services (Sparta enables CloudWatch Logs privileges by default), the integration is pretty straightforward:

lambdaFn = sparta.NewLambda(sparta.IAMRoleDefinition{}, echoSNSEvent, nil)

Event Source Registration

If we were to deploy this Sparta application, the echoSNSEvent function would have the ability to log SNS events, but would not be invoked in response to messages published to that topic. To register for notifications, we need to configure the lambda’s Permissions:

lambdaFn.Permissions = append(lambdaFn.Permissions, sparta.SNSPermission{
  BasePermission: sparta.BasePermission{
    SourceArn: snsTopic,
  },
})
lambdaFunctions = append(lambdaFunctions, lambdaFn)

The snsTopic param is the ARN of the SNS topic that will notify your lambda function (eg: _arn:aws:sns:us-west-2:000000000000:myTopicName).

See the S3 docs for more information on how the Permissions data is processed.

Wrapping Up

With the lambdaFn fully defined, we can provide it to sparta.Main() and deploy our service. The workflow below is shared by all SNS-triggered lambda function:

  • Define the lambda function (echoSNSEvent).
  • If needed, create the required IAMRoleDefinition with appropriate privileges if the lambda function accesses other AWS services.
  • Provide the lambda function & IAMRoleDefinition to sparta.NewLambda()
  • Add the necessary Permissions to the LambdaAWSInfo struct so that the lambda function is triggered.

Other Resources

  • TBD