In this section we’ll walkthrough how to trigger your lambda function in response to different types of CloudWatch Events. This overview is based on the SpartaApplication sample code if you’d rather jump to the end result.
Assume that we’re supposed to write a simple “HelloWorld” CloudWatch event function that has two requirements:
The lambda function is relatively small:
func echoCloudWatchEvent(ctx context.Context, event map[string]interface{}) (map[string]interface{}, error) {
logger, _ := ctx.Value(sparta.ContextKeyRequestLogger).(*zerolog.Logger)
logger.Info().
Interface("Event", event).
Msg("Event received")
return event, nil
}
Our lambda function doesn’t need to do much with the event other than log and return it.
With echoCloudWatchEvent()
implemented, the next step is to integrate the go function with Sparta. This is done by the appendCloudWatchEventHandler
in the SpartaApplication application.go source.
Our lambda function only needs logfile write privileges, and since these are enabled by default, we can use an empty sparta.IAMRoleDefinition
value:
func appendCloudWatchEventHandler(api *sparta.API,
lambdaFunctions []*sparta.LambdaAWSInfo) []*sparta.LambdaAWSInfo {
lambdaFn, _ := sparta.NewAWSLambda(sparta.LambdaName(echoCloudWatchEvent),
echoCloudWatchEvent,
sparta.IAMRoleDefinition{})
The next step is to add a CloudWatchEventsPermission
value that includes the two rule triggers.
cloudWatchEventsPermission := sparta.CloudWatchEventsPermission{}
cloudWatchEventsPermission.Rules = make(map[string]sparta.CloudWatchEventsRule, 0)
Our two rules will be inserted into the Rules
map in the next steps.
Our first requirement is that the lambda function write a heartbeat to the logfile every 5 mins. This can be configured by adding a scheduled event:
cloudWatchEventsPermission.Rules["Rate5Mins"] = sparta.CloudWatchEventsRule{
ScheduleExpression: "rate(5 minutes)",
}
The ScheduleExpression
value can either be a rate or a cron expression. The map keyname is used when adding the rule during stack provisioning.
The other requirement is that our lambda function be notified when matching EC2 events are created. To support this, we’ll add a second Rule
:
cloudWatchEventsPermission.Rules["EC2Activity"] = sparta.CloudWatchEventsRule{
EventPattern: map[string]interface{}{
"source": []string{"aws.ec2"},
"detail-type": []string{"EC2 Instance State-change Notification"},
},
}
The EC2 event pattern is the go JSON-compatible representation of the event pattern that CloudWatch Events will use to trigger our lambda function. This structured value will be marshaled to a String during CloudFormation Template marshaling.
Sparta does NOT attempt to validate either ScheduleExpression
or EventPattern
values prior to calling CloudFormation. Syntax errors in either value will be detected during provisioning when the Sparta CloudFormation CustomResource calls putRule to add the lambda target. This error will cause the CloudFormation operation to fail. Any API errors will be logged & are viewable in the CloudFormation Logs Console.
With the two rules configured, the final step is to add the sparta.CloudWatchPermission
to our sparta.LambdaAWSInfo
value:
lambdaFn.Permissions = append(lambdaFn.Permissions, cloudWatchEventsPermission)
return append(lambdaFunctions, lambdaFn)
Our entire function is therefore:
func appendCloudWatchEventHandler(api *sparta.API,
lambdaFunctions []*sparta.LambdaAWSInfo) []*sparta.LambdaAWSInfo {
lambdaFn, _ := sparta.NewAWSLambda(sparta.LambdaName(echoCloudWatchEvent),
echoCloudWatchEvent,
sparta.IAMRoleDefinition{})
cloudWatchEventsPermission := sparta.CloudWatchEventsPermission{}
cloudWatchEventsPermission.Rules = make(map[string]sparta.CloudWatchEventsRule, 0)
cloudWatchEventsPermission.Rules["Rate5Mins"] = sparta.CloudWatchEventsRule{
ScheduleExpression: "rate(5 minutes)",
}
cloudWatchEventsPermission.Rules["EC2Activity"] = sparta.CloudWatchEventsRule{
EventPattern: map[string]interface{}{
"source": []string{"aws.ec2"},
"detail-type": []string{"EC2 Instance state change"},
},
}
lambdaFn.Permissions = append(lambdaFn.Permissions, cloudWatchEventsPermission)
return append(lambdaFunctions, lambdaFn)
}
With the lambdaFn
fully defined, we can provide it to sparta.Main()
and deploy our service. The workflow below is shared by all CloudWatch Events-triggered lambda functions:
echoCloudWatchEvent
).sparta.NewAWSLambda()
CloudWatchEventsPermission.Rules
map that define your lambda function’s trigger condition:
CloudWatchEventsPermission
value to the lambda function’s Permissions
slice.sparta.Main()
.