Skip to content
This repository has been archived by the owner on Nov 26, 2023. It is now read-only.

Commit

Permalink
Added autostop functions
Browse files Browse the repository at this point in the history
  • Loading branch information
kyhau committed Mar 10, 2017
1 parent c763b2e commit 0a1246f
Show file tree
Hide file tree
Showing 4 changed files with 217 additions and 1 deletion.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ install:

# command to run tests
script:
- tox
- pytest -s -vvvv EC2

108 changes: 108 additions & 0 deletions EC2/autostop_ec2/autostop-ec2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#!/usr/bin/env python
from __future__ import absolute_import
import argparse
import boto3


# App defaults
DEFAULTS = {
'ec2_regions': ['ap-southeast-2'],
'autostop_tag_key': 'AutoStop'
}

class StopAllEC2(object):

def __init__(self, profile_name=None):
self._loaded = False
self.profile_name = profile_name
self.ec2_regions = list()
self.autostop_tag_key = DEFAULTS['autostop_tag_key']

def _load_config(self):
if self._loaded:
return

parser = argparse.ArgumentParser(description='Create backups for EC2 instances with Tag [Service]')
parser.add_argument('--regions', metavar='region', nargs='*',
help='EC2 Region(s) to process for snapshots',
default=DEFAULTS['ec2_regions'])
settings = parser.parse_args()

for region in settings.regions:
self.ec2_regions.append(region)

self._loaded = True

def configure_from_lambda_event(self, event_details):
for setting in DEFAULTS.keys():
if setting in event_details:
self.__setattr__(setting, event_details[setting])
else:
self.__setattr__(setting, DEFAULTS[setting])
self._loaded = True

def start_process(self):
self._load_config()
for region in self.ec2_regions:
self.stop_all_vms(region)

def stop_all_vms(self, region):
"""
Stopping all running VMs (with a tag AutoStop=True) in a region of all aws
accounts defined in profiles
"""
try:
ec2_client = self.ec2_resource(region=region, profile_name=self.profile_name)

# find all ec2 instances which are tagged as 'vm'
ret = ec2_client.instances.filter(
Filters=[
{'Name': 'tag:Service', 'Values': ['vm']},
{'Name': 'tag:{}'.format(self.autostop_tag_key), 'Values': ['True']}
]
).stop()

for r in ret:
if 'StoppingInstances' in r.keys():
checked_instances = r['StoppingInstances']
for i in checked_instances:
if i['PreviousState']['Name'] in ['pending', 'running'] \
and i['CurrentState']['Name'] in ['stopped', 'stopping']:
print('{} has been stopped'.format(i['InstanceId']))
elif i['PreviousState']['Name'] in ['pending', 'running']:
print('{} has been stopped and current status is {}'.format(
i['InstanceId'], i['CurrentState']['Name']))

except Exception as e:
print('Error: Failed to stop all VM EC2 instances')
print(e)

@staticmethod
def ec2_resource(region, profile_name=None):
"""
Return a EC2 client
"""
if profile_name is None:
ec2 = boto3.resource('ec2', region_name=region)
else:
session = boto3.session.Session(profile_name=profile_name)
ec2 = session.resource('ec2', region)
return ec2


def lambda_handler(event, context):
"""
Entry point for triggering from a AWS Lambda job
"""
helper = StopAllEC2()
helper.configure_from_lambda_event(event)
helper.start_process()


if __name__ == '__main__':
"""
Entry point for running from command line
"""
# TODO change profile_name
helper = StopAllEC2(profile_name='default-profile')
helper.start_process()
101 changes: 101 additions & 0 deletions EC2/autostop_ec2/reset-autostop-ec2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#!/usr/bin/env python
from __future__ import absolute_import
import argparse
import boto3


# App defaults
DEFAULTS = {
'ec2_regions': ['ap-southeast-2'],
'autostop_tag_key': 'AutoStop'
}

class ResetAutoStop(object):

def __init__(self, profile_name=None):
self._loaded = False
self.profile_name = profile_name
self.ec2_regions = list()
self.autostop_tag_key = DEFAULTS['autostop_tag_key']

def _load_config(self):
if self._loaded:
return

parser = argparse.ArgumentParser(description='Create backups for EC2 instances with Tag [Service]')
parser.add_argument('--regions', metavar='region', nargs='*',
help='EC2 Region(s) to process for snapshots',
default=DEFAULTS['ec2_regions'])
settings = parser.parse_args()

for region in settings.regions:
self.ec2_regions.append(region)

self._loaded = True

def configure_from_lambda_event(self, event_details):
for setting in DEFAULTS.keys():
if setting in event_details:
self.__setattr__(setting, event_details[setting])
else:
self.__setattr__(setting, DEFAULTS[setting])
self._loaded = True

def start_process(self):
self._load_config()
for region in self.ec2_regions:
self.reset_autostop_on_all_vms(region)

def reset_autostop_on_all_vms(self, region):
"""
Reset the tag AutoStop to True to all VMs in a region of all aws accounts defined in profiles
"""
try:
ec2_client = self.ec2_resource(region=region, profile_name=self.profile_name)

# find all ec2 instances which are tagged as 'vm'

ret = ec2_client.instances.filter(
Filters=[
{'Name': 'tag:Service', 'Values': ['vm']}
]
).create_tags(
Tags=[{'Key': self.autostop_tag_key, 'Value': 'True'}]
)

if ret[0]['ResponseMetadata']['HTTPStatusCode'] != 200:
print('Error: Failed to reset autostop: {}'.format(ret))

except Exception as e:
print('Error: Failed to reset autostop')
print(e)

@staticmethod
def ec2_resource(region, profile_name=None):
"""
Return a EC2 client
"""
if profile_name is None:
ec2 = boto3.resource('ec2', region_name=region)
else:
session = boto3.session.Session(profile_name=profile_name)
ec2 = session.resource('ec2', region)
return ec2


def lambda_handler(event, context):
"""
Entry point for triggering from a AWS Lambda job
"""
helper = ResetAutoStop()
helper.configure_from_lambda_event(event)
helper.start_process()


if __name__ == '__main__':
"""
Entry point for running from command line
"""
# TODO change profile_name
helper = ResetAutoStop(profile_name='default-profile')
helper.start_process()
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
My AWS Lambda functions for personal use.

## Scripts being run through Lambda

1. `EC2/autostop_ec2/autostop-ec2`
- Autostop EC2 instances with specified tag

1. `EC2/autostop_ec2/reset-autostop-ec2`
- Reset Autostop tags of specific EC2 instances

1. `EC2/backup_ec2/create-ec2-backups`
- Create AMI and Snapshot(s) for EC2 instance
Expand Down

0 comments on commit 0a1246f

Please sign in to comment.