Skip to content

Instantly share code, notes, and snippets.

@PercussiveRepair
Last active January 13, 2017 09:40
Show Gist options
  • Select an option

  • Save PercussiveRepair/2b48a09ae8e0ca5f65d7c594b411aa76 to your computer and use it in GitHub Desktop.

Select an option

Save PercussiveRepair/2b48a09ae8e0ca5f65d7c594b411aa76 to your computer and use it in GitHub Desktop.
Send AWS instance retirement/maintenance events from multiple accounts/regions to Slack
#! /usr/bin/python
# gets instance events from mulitple accounts/regions and posts to slack
import boto3
from slackclient import SlackClient
from tabulate import tabulate
token = '<slack token>'
creds = open('<creds location>', 'r')
regions = ['eu-west-1', 'us-east-1']
filters = [{ 'Name': 'event.code', 'Values': [ 'instance-reboot','system-reboot','system-maintenance','instance-retirement','instance-stop']}]
instanceevents = []
# get instance maintenance data
# assumes a standard aws cli credentials file format - http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html#cli-multiple-profiles
try:
for line in creds:
if line.startswith('['):
profile=line[1:-2]
for region in regions:
boto3.setup_default_session(profile_name=profile, region_name=region)
client = boto3.client('ec2')
for status in client.describe_instance_status(Filters=filters)['InstanceStatuses']:
instance = client.describe_instances(InstanceIds=[status['InstanceId']])
instancename = ''
instancerole = ''
instanceproduct = ''
if 'Tags' in instance['Reservations'][0]['Instances'][0]:
for tag in instance['Reservations'][0]['Instances'][0]['Tags']:
if tag['Key'] == 'Name':
instancename = tag['Value']
elif tag['Key'] == 'role':
instancerole = tag['Value']
elif tag['Key'] == 'product':
instanceproduct = tag['Value']
date = str(status['Events'][0]['NotBefore'])[:-15]
description = str(status['Events'][0]['Description']).replace('The instance is running on ', '')
action = str(status['Events'][0]['Code']).replace('system-', '').replace('instance-', '')
instanceinfo = { 'Account': profile, 'InstanceId': status['InstanceId'], 'Action': action, 'Status': description, 'Name': instancename, 'Region/AZ': status['AvailabilityZone'], 'DueDate': date}
instanceevents.append(instanceinfo)
except Exception,e:
print str(e)
pass
# assemble slack message
# Slack formatted code blocks have a 4k byte limit. Your events list may need splitting or formatting as a snippet if it is too large
table = tabulate(instanceevents, headers='keys')
message = '``` ' + table + ' ```'
if instanceevents:
sc = SlackClient(token)
print sc.api_call(
"chat.postMessage", channel="<slack channel>", text=message,
username='AWS Instance Events', icon_emoji=':bomb:'
)
@richupshall

richupshall commented Jan 13, 2017

Copy link
Copy Markdown

What could be nice is to not have to specify the region list, especially as regions get added. Perhaps something like:

ec2 = boto3.client('ec2',region_name='us-east=1')
allRegions = [region['RegionName'] for region in ec2.describe_regions()['Regions']]
for region in allRegions:
   <loop over logic>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment