Skip to content

Instantly share code, notes, and snippets.

@PercussiveRepair
Last active January 13, 2017 09:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PercussiveRepair/2b48a09ae8e0ca5f65d7c594b411aa76 to your computer and use it in GitHub Desktop.
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
Copy link

richupshall commented Jan 13, 2017

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