<repo_name>tonyfruzza/AwsSsmAgentMonitoringPoC<file_sep>/README.md
## SSM Agent Monitor
Triggers a CloudWatch Alarm when a managed instance is not capable of receiving SSM commands and generating an CloudWatch Metric within the allotted threshold of time.

### Configuration
1. Set `alarm_sns_arn` within conifg-common.yml for where the alarm should be directed.
2. Duplicate the example CloudWatch alarm in the resources section to match your managed instances. One for each instance.

Your IAM role assigned to your managed instance should include at least these managed policies:
* AmazonSSMManagedInstanceCore
* CloudWatchAgentServerPolicy

### Management
This serverless framework is designed to be launched by runway. Create a module directory with a .sls folder extension, add the module to your runway.yml list. The example configuration files use -common.yml extensions, if you'd rather launch in a different environment you'll need to change those to match your desired environment name.


### Deployment
AWS infrastructure managed by [Serverles Framework](https://github.com/serverless/serverless) follow the install guidelines for your OS and AWS CLI. This example comes with a autoscaling group which launches an instance to be monitored. There are parameter values that must be configured to launch this within your VPC within `deploy.sh`. Configure your AWS credentials and then execute the provided `./deploy.sh` after performing the Configuration step to set your SNS topic.
<file_sep>/deploy.sh
#!/bin/sh
REGION=us-west-2

sls deploy --stage common --region $REGION
<file_sep>/lambda/ssm-run-doc.rb
require 'aws-sdk-ssm'

def lambda_handler(event:, context:)
  ssm = Aws::SSM::Client.new(region: ENV['AWS_REGION'])

  # Get list of instances that are checking into SSM
  managed_instances = []
  next_token = nil
  loop do
    dii = ssm.describe_instance_information({next_token: next_token}).to_h
    managed_instances += dii[:instance_information_list].map{|i| i[:instance_id]}
    break unless next_token = dii[:next_token]
    next_token = dii[:next_token]
  end

  puts "Targeting #{managed_instances}"
  managed_instances.each do |mi|
    ssm.send_command({
      targets: [{key: 'InstanceIds', values: managed_instances}],
      document_name: 'AWS-RunPowerShellScript',
      parameters: {
        commands: ["aws --region #{ENV['AWS_REGION']} cloudwatch put-metric-data --metric-name heart-beat --namespace mi-health --value 1 --dimensions InstanceID=#{mi}"]
      },
      timeout_seconds: 300
    })
  end
end
