Stop/Start RDS Instance

RDS Managed Instances are one of the top expends in AWS.

Stop/Start RDS Instance script in Python, provide a Tag "Shutdown" and "StartUp". You can program this via a Lambda handler.

from __future__ import print_function
import boto3
from datetime import datetime, timedelta

prof_name = ""   # Profile Name Identifier
acc_number = "" # AWS Account Number

#boto3.setup_default_session(profile_name=prof_name)

def rds_start(list_instances):

    for instance in list_instances:
        this_inst = instance.split(",")
        db_instance_id = this_inst[0]
        environment = this_inst[1]
        print ("{0} (UTC): Starting Instance '{1}' from Environment '{2}'".format(datetime.utcnow(), db_instance_id, environment))
        boto3.client('rds').start_db_instance(DBInstanceIdentifier=db_instance_id)

def rds_stop(list_instances):

    for instance in list_instances:
        this_inst = instance.split(",")
        db_instance_id = this_inst[0]
        environment = this_inst[1]
        print("{0} (UTC): Stopping Instance '{1}' from Environment '{2}'".format(datetime.utcnow(), this_inst[0], this_inst[1]))
        boto3.client('rds').stop_db_instance(DBInstanceIdentifier=db_instance_id)

def lambda_handler(event, context):

    rds = boto3.client('rds')

    instances_to_start = []
    instances_to_stop = []

    # Date calculation
    date = datetime.utcnow() + timedelta(hours=10)

    current_hour = date.hour
    current_day = date.weekday()

    print("Running State Change Script for hour {0} on day {1}".format(current_hour, current_day))

    try:
        # get all of the db instances
        dbs = rds.describe_db_instances()

        for db in dbs['DBInstances']:
            #print("--------------------------------------------")
            print("Checking RDS Instance: {0} {1} {2} {3} {4}".format(db['DBInstanceIdentifier'], db['MasterUsername'], db['Endpoint']['Address'], db['Endpoint']['Port'], db['DBInstanceStatus']) )

            arn = "arn:aws:rds:ap-southeast-2:" + acc_number + ":db:" + db['DBInstanceIdentifier']
            # print("{0}".format(arn))

            tags = rds.list_tags_for_resource(ResourceName=arn)
            # print (tags)

            instance_id = db['DBInstanceIdentifier']
            current_status = db['DBInstanceStatus']
            environment = ""
            startup = ""
            shutdown = ""

            for tg in tags['TagList']:

                if tg['Key'] == 'Environment':
                    environment = tg['Value']

                if tg['Key'] == 'StartUp':
                    startup = tg['Value']

                if tg['Key'] == 'Shutdown':
                    shutdown = tg['Value']

            if environment == "PROD": # Skip prod
                if startup != "":
                    print("Skipping Production RDS Instance. Do not assign StartUp/Shutdown Tags to PROD instances.")

                if shutdown != "":
                    print("Skipping Production RDS Instance. Do not assign StartUp/Shutdown Tags to PROD instances.")

                continue

            if startup != "":
                startup_schedule =  startup.split(" ")
                print("StartUp:  {0}".format(startup_schedule))
                if (int(startup_schedule[current_day]) == current_hour):
                    if current_status == "stopped" : instances_to_start.append(instance_id + "," + environment)

            if shutdown != "":
                shutdown_schedule =  shutdown.split(" ")
                print("Shutdown: {0}".format(shutdown_schedule))
                if (int(shutdown_schedule[current_day]) == current_hour):
                    if current_status == "available": instances_to_stop.append(instance_id + "," + environment)

            #print("--------------------------------------------")

        if (len(instances_to_start) == 0): print ("{0} (UTC): No instances to start at this time.".format(datetime.utcnow()))
        if (len(instances_to_stop) == 0): print ("{0} (UTC): No instances to stop at this time.".format(datetime.utcnow()))

        rds_start(instances_to_start)
        rds_stop(instances_to_stop)

    except Exception as error:
        print(error)

lambda_handler(0, 0)