AWS SDK for Ruby
Developer Guide

Sending Events to Amazon CloudWatch Events

CloudWatch Events delivers a near real-time stream of system events that describe changes in AWS resources to AWS Lambda functions or other targets. See What is Amazon CloudWatch Events? to learn more. In this example, you use the AWS SDK for Ruby with CloudWatch Events to:

  1. Create a rule in CloudWatch Events by using Aws::CloudWatchEvents::Client#put_rule.

  2. Add a target to the rule by using Aws::CloudWatchEvents::Client#put_targets.

  3. Send an event to CloudWatch Events so that it can be matched to the rule.

  4. View the results in Amazon CloudWatch Logs and metrics by using Aws::CloudWatch::Client#get_metric_statistics and Aws::CloudWatchLogs::Client#describe_log_streams.

Prerequisites

Before running the example code, you need to install and configure the AWS SDK for Ruby, as described in:

You also need to:

  • Replace the placeholder value assigned to lambda_function_arn with an actual Lambda function ARN.

    1. Create a Lambda function, as described here.

    2. Name the function LogEC2InstanceStateChange.

    3. For a role, select Choose an Existing Role. For the existing role, select lambda_basic_execution.

    4. After you create the function, copy the ARN and paste it into your code.

  • Replace the placeholder value assigned to cwe_service_role_arn with an appropriate AWS Identity and Access Management service role ARN.

    1. In the IAM console, create a role and attach a policy that grants full access to CloudWatch Events.

    2. Ensure that the role has a trust relationship to events.amazonaws.com. For an example policy and role, see the comments in the example code on GitHub.

    3. After you create the role, attach the policy, and establish the trust relationship, copy the role ARN and paste it into your code.

  • Replace the placeholder value assigned to instance_id with an actual Amazon EC2 instance ID.

Example

require 'aws-sdk-cloudwatch' # v2: require 'aws-sdk' # Uncomment for Windows. # Aws.use_bundled_cert! cwe = Aws::CloudWatchEvents::Client.new(region: 'us-east-1') # Replace this value with the ARN of the AWS Lambda function you created earlier. lambda_function_arn = "arn:aws:lambda:REGION-ID:ACCOUNT-ID:function:LogEC2InstanceStateChange" # Replace this value with the ARN of the AWS IAM service role you created earlier. cwe_service_role_arn = "arn:aws:iam::ACCOUNT-ID:role/SERVICE-ROLE-NAME" # Create a rule in Amazon CloudWatch Events. rule_name = "my-ec2-rule" # The rule will use this pattern to route the event to the target. # This pattern is used whenever an Amazon EC2 instance begins running. event_pattern = { "source" => [ "aws.ec2" ], "detail-type" => [ "EC2 Instance State-change Notification" ], "detail" => { "state" => [ "running" ] } }.to_json cwe.put_rule({ name: rule_name, event_pattern: event_pattern, state: "ENABLED", role_arn: cwe_service_role_arn }) # Add a target to the rule. cwe.put_targets({ rule: rule_name, targets: [ { id: "my-rule-target", arn: lambda_function_arn } ] }) # To test the rule, stop and then restart an existing Amazon EC2 instance. # For example: ec2 = Aws::EC2::Client.new(region: 'us-east-1') # Replace this with an actual instance ID. instance_id = "i-INSTANCE-ID" puts "Attempting to stop the instance. This may take a few minutes..." ec2.stop_instances({ instance_ids: [ instance_id ] }) # Make sure the instance is stopped before attempting to restart it. ec2.wait_until(:instance_stopped, instance_ids: [ instance_id ]) puts "Attempt to restart the instance. This may take a few minutes..." ec2.start_instances({ instance_ids: [ instance_id ] }) # Make sure the instance is running before continuing on. ec2.wait_until(:instance_running, instance_ids: [ instance_id ]) # See if and when the rule was triggered. cw = Aws::CloudWatch::Client.new(region: 'us-east-1') invocations = cw.get_metric_statistics({ namespace: "AWS/Events", metric_name: "Invocations", dimensions: [ { name: "RuleName", value: rule_name, }, ], start_time: Time.now - 600, # Look back over the past 10 minutes to see if the rule was triggered (10 minutes * 60 seconds = 600 seconds). end_time: Time.now, period: 60, # Look back every 60 seconds over those past 10 minutes to see how many times the rule may have been triggered. statistics: [ "Sum" ], unit: "Count" }) if invocations.datapoints.count > 0 puts "Rule invocations:" invocations.datapoints.each do |datapoint| puts " #{datapoint.sum} invocation(s) at #{datapoint.timestamp}" end else puts "No rule invocations." end # View the latest related log in Amazon CloudWatch Logs. cwl = Aws::CloudWatchLogs::Client.new(region: 'us-east-1') describe_log_streams_response = cwl.describe_log_streams({ log_group_name: "/aws/lambda/LogEC2InstanceStateChange", order_by: "LastEventTime", descending: true }) get_log_events_response = cwl.get_log_events({ log_group_name: "/aws/lambda/LogEC2InstanceStateChange", log_stream_name: describe_log_streams_response.log_streams[0].log_stream_name # Get the latest log stream only. }) puts "\nLog messages:\n\n" get_log_events_response.events.each do |event| puts event.message end

On this page: