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