github.com/mweagle/Sparta@v1.15.0/docs_source/content/reference/eventsources/cloudwatchevents.md (about) 1 --- 2 date: 2016-03-09T19:56:50+01:00 3 title: CloudWatch Events 4 weight: 10 5 --- 6 7 In this section we'll walkthrough how to trigger your lambda function in response to different types of [CloudWatch Events](https://aws.amazon.com/blogs/aws/new-cloudwatch-events-track-and-respond-to-changes-to-your-aws-resources/). This overview is based on the [SpartaApplication](https://github.com/mweagle/SpartaApplication) sample code if you'd rather jump to the end result. 8 9 # Goal 10 11 Assume that we're supposed to write a simple "HelloWorld" CloudWatch event function that has two requirements: 12 13 * Run every *5 minutes* to provide a heartbeat notification to our alerting system via a logfile entry 14 * Log *EC2-related* events for later processing 15 16 ## Getting Started 17 18 The lambda function is relatively small: 19 ```go 20 func echoCloudWatchEvent(ctx context.Context, event map[string]interface{}) (map[string]interface{}, error) { 21 logger, _ := ctx.Value(sparta.ContextKeyRequestLogger).(*logrus.Entry) 22 23 logger.WithFields(logrus.Fields{ 24 "Event": event, 25 }).Info("Request received") 26 return event, nil 27 } 28 ``` 29 Our lambda function doesn't need to do much with the event other than log and return it. 30 31 ## Sparta Integration {#spartaIntegration} 32 33 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](https://github.com/mweagle/SpartaApplication/blob/master/application.go) source. 34 35 36 Our lambda function only needs logfile write privileges, and since these are enabled by default, we can use an empty `sparta.IAMRoleDefinition` value: 37 ```go 38 func appendCloudWatchEventHandler(api *sparta.API, 39 lambdaFunctions []*sparta.LambdaAWSInfo) []*sparta.LambdaAWSInfo { 40 41 lambdaFn, _ := sparta.NewAWSLambda(sparta.LambdaName(echoCloudWatchEvent), 42 echoCloudWatchEvent, 43 sparta.IAMRoleDefinition{}) 44 ``` 45 46 The next step is to add a `CloudWatchEventsPermission` value that includes the two rule triggers. 47 ```go 48 cloudWatchEventsPermission := sparta.CloudWatchEventsPermission{} 49 cloudWatchEventsPermission.Rules = make(map[string]sparta.CloudWatchEventsRule, 0) 50 ``` 51 52 Our two rules will be inserted into the `Rules` map in the next steps. 53 54 ### Cron Expression 55 56 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: 57 ```go 58 cloudWatchEventsPermission.Rules["Rate5Mins"] = sparta.CloudWatchEventsRule{ 59 ScheduleExpression: "rate(5 minutes)", 60 } 61 ``` 62 The `ScheduleExpression` value can either be a _rate_ or a _cron_ [expression](http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/ScheduledEvents.html). The map keyname is used when adding the [rule](http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CloudWatchEvents.html#putRule-property) during stack provisioning. 63 64 ### Event Pattern 65 66 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`: 67 68 ```go 69 cloudWatchEventsPermission.Rules["EC2Activity"] = sparta.CloudWatchEventsRule{ 70 EventPattern: map[string]interface{}{ 71 "source": []string{"aws.ec2"}, 72 "detail-type": []string{"EC2 Instance State-change Notification"}, 73 }, 74 } 75 ``` 76 77 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. 78 79 80 {{% notice warning %}} 81 Sparta does <b>NOT</b> attempt to validate either <code>ScheduleExpression</code> or <code>EventPattern</code> values prior to calling CloudFormation. Syntax errors in either value will be detected during provisioning when the Sparta CloudFormation CustomResource calls <a href="http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CloudWatchEvents.html#putRule-property">putRule</a> to add the lambda target. This error will cause the CloudFormation operation to fail. Any API errors will be logged & are viewable in the <a href="https://blogs.aws.amazon.com/application-management/post/TxPYD8JT4CB5UY/View-CloudFormation-Logs-in-the-Console">CloudFormation Logs Console</a>. 82 {{% /notice %}} 83 84 ## Add Permission 85 86 With the two rules configured, the final step is to add the `sparta.CloudWatchPermission` to our `sparta.LambdaAWSInfo` value: 87 88 ```go 89 lambdaFn.Permissions = append(lambdaFn.Permissions, cloudWatchEventsPermission) 90 return append(lambdaFunctions, lambdaFn) 91 ``` 92 93 Our entire function is therefore: 94 95 ```go 96 func appendCloudWatchEventHandler(api *sparta.API, 97 lambdaFunctions []*sparta.LambdaAWSInfo) []*sparta.LambdaAWSInfo { 98 99 lambdaFn, _ := sparta.NewAWSLambda(sparta.LambdaName(echoCloudWatchEvent), 100 echoCloudWatchEvent, 101 sparta.IAMRoleDefinition{}) 102 103 cloudWatchEventsPermission := sparta.CloudWatchEventsPermission{} 104 cloudWatchEventsPermission.Rules = make(map[string]sparta.CloudWatchEventsRule, 0) 105 cloudWatchEventsPermission.Rules["Rate5Mins"] = sparta.CloudWatchEventsRule{ 106 ScheduleExpression: "rate(5 minutes)", 107 } 108 cloudWatchEventsPermission.Rules["EC2Activity"] = sparta.CloudWatchEventsRule{ 109 EventPattern: map[string]interface{}{ 110 "source": []string{"aws.ec2"}, 111 "detail-type": []string{"EC2 Instance state change"}, 112 }, 113 } 114 lambdaFn.Permissions = append(lambdaFn.Permissions, cloudWatchEventsPermission) 115 return append(lambdaFunctions, lambdaFn) 116 } 117 ``` 118 119 # Wrapping Up 120 121 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: 122 123 * Define the lambda function (`echoCloudWatchEvent`). 124 * If needed, create the required [IAMRoleDefinition](https://godoc.org/github.com/mweagle/Sparta*IAMRoleDefinition) with appropriate privileges. 125 * Provide the lambda function & IAMRoleDefinition to `sparta.NewAWSLambda()` 126 * Create a [CloudWatchEventsPermission](https://godoc.org/github.com/mweagle/Sparta#CloudWatchEventsPermission) value. 127 * Add one or more [CloudWatchEventsRules](https://godoc.org/github.com/mweagle/Sparta#CloudWatchEventsRule) to the `CloudWatchEventsPermission.Rules` map that define your lambda function's trigger condition: 128 * [Scheduled Events](http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/ScheduledEvents.html) 129 * [Event Patterns](http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/CloudWatchEventsandEventPatterns.html) 130 * Append the `CloudWatchEventsPermission` value to the lambda function's `Permissions` slice. 131 * Include the reference in the call to `sparta.Main()`. 132 133 ## Other Resources 134 135 * Introduction to [CloudWatch Events](https://aws.amazon.com/blogs/aws/new-cloudwatch-events-track-and-respond-to-changes-to-your-aws-resources/) 136 * Tim Bray's [Cloud Eventing](https://www.tbray.org/ongoing/When/201x/2016/01/11/CloudWatch-Events) writeup 137 * [Run an AWS Lambda Function on a Schedule Using the AWS CLI](http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/RunLambdaSchedule.html) 138 * The EC2 event pattern is drawn from the AWS [Events & Event Patterns](http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/CloudWatchEventsandEventPatterns.html) documentation