In this section we’ll walkthrough how to trigger your lambda function in response to AWS Simple Queue Service (SQS) events. This overview is based on the SpartaSQS sample code if you’d rather jump to the end result.
The goal here is to create a self-contained service that provisions a SQS queue, an AWS Lambda function that processes messages posted to the queue
We’ll start with an empty lambda function and build up the needed functionality.
import (
"context"
awsLambdaGo "github.com/aws/aws-lambda-go/events"
sparta "github.com/mweagle/Sparta/v3"
spartaCF "github.com/mweagle/Sparta/v3/aws/cloudformation"
gocf "github.com/mweagle/go-cloudformation"
"github.com/rs/zerolog"
)
func sqsHandler(ctx context.Context, sqsRequest awsLambdaGo.SQSEvent) error {
logger, _ := ctx.Value(sparta.ContextKeyLogger).(*zerolog.Logger)
logger.WithField("Event", sqsRequest).Info("SQS Event Received")
return nil
}
Since the sqsHandler
function subscribes to SQS messages, it can use the AWS provided SQSEvent to automatically unmarshal the incoming event.
Typically the lambda function would process each record in the event, but for this example we’ll just log the entire batch and then return.
The next step is to integrate the lambda function with Sparta:
// 1. Create the Sparta Lambda function
lambdaFn, _ := sparta.NewAWSLambda(sparta.LambdaName(sqsHandler),
sqsHandler,
sparta.IAMRoleDefinition{})
Once the lambda function is integrated with Sparta, we can use a TemplateDecoratorHandler to include the SQS provisioning request as part of the overall service creation.
Decorators enable a Sparta service to provision other types of infrastructure together with the core lambda functions. In this example, our sqsHandler
function should also provision an SQS queue from which it will receive events. This is done as in the following:
sqsResourceName := "LambdaSQSFTW"
sqsDecorator := func(serviceName string,
lambdaResourceName string,
lambdaResource gocf.LambdaFunction,
resourceMetadata map[string]interface{},
S3Bucket string,
S3Key string,
buildID string,
template *gocf.Template,
context map[string]interface{},
logger *zerolog.Logger) error {
// Include the SQS resource in the application
sqsResource := &gocf.SQSQueue{}
template.AddResource(sqsResourceName, sqsResource)
return nil
}
lambdaFn.Decorators = []sparta.TemplateDecoratorHandler{sparta.TemplateDecoratorHookFunc(sqsDecorator)}
This function-level decorator includes an AWS CloudFormation SQS::Queue definition that will be included with the stack definition.
The final step is to make the sqsHandler
the Lambda’s EventSourceMapping target for the dynamically provisioned Queue’s ARN:
lambdaFn.EventSourceMappings = append(lambdaFn.EventSourceMappings,
&sparta.EventSourceMapping{
EventSourceArn: gocf.GetAtt(sqsResourceName, "Arn"),
BatchSize: 2,
})
With the lambdaFn
fully defined, we can provide it to sparta.Main()
and deploy our service. It’s also possible to use a pre-existing SQS resource by providing a string literal as the EventSourceArn
value.