Skip to content

Instantly share code, notes, and snippets.

@ronaldbradford
Created January 26, 2023 15:06

Revisions

  1. ronaldbradford created this gist Jan 26, 2023.
    90 changes: 90 additions & 0 deletions lambda.auto-shutdown.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,90 @@
    # this Code will help to schedule stop the RDS databasrs using Lambda
    # Yesh
    # Version -- 2.0
    # Adapted from https://aws.amazon.com/blogs/database/schedule-amazon-rds-stop-and-start-using-aws-lambda/

    import boto3
    import os
    import sys
    import time
    from datetime import datetime, timezone
    from time import gmtime, strftime

    def shut_rds_all():
    region=os.environ['REGION']
    key=os.environ['KEY']
    value=os.environ['VALUE']

    print(f"Looking for RDS resources in Region: {region} with Tag Key: {key} Value: {value}")
    client = boto3.client('rds', region_name=region)
    response = client.describe_db_instances()
    v_readReplica=[]
    print("Looking for DBInstances with ReadReplicaDBInstanceIdentifiers")
    for i in response['DBInstances']:
    print(f"..{i}")
    readReplica=i['ReadReplicaDBInstanceIdentifiers']
    v_readReplica.extend(readReplica)

    print("Looking for DBInstances")
    for i in response['DBInstances']:
    print(f"..{i}")
    #The if condition below filters aurora clusters from single instance databases as boto3 commands defer to stop the aurora clusters.
    if i['Engine'] not in ['aurora-mysql','aurora-postgresql']:
    #The if condition below filters Read replicas.
    if i['DBInstanceIdentifier'] not in v_readReplica and len(i['ReadReplicaDBInstanceIdentifiers']) == 0:
    arn=i['DBInstanceArn']
    resp2=client.list_tags_for_resource(ResourceName=arn)
    #check if the RDS instance is part of the Auto-Shutdown group (the value passed for tag).
    if 0==len(resp2['TagList']):
    print('DB Instance {0} is not part of {1}'.format(i['DBInstanceIdentifier'], value))
    else:
    for tag in resp2['TagList']:
    #If the tags match, then stop the instances by validating the current status.
    if tag['Key']==key and tag['Value']==value:
    if i['DBInstanceStatus'] == 'available':
    client.stop_db_instance(DBInstanceIdentifier = i['DBInstanceIdentifier'])
    print('stopping DB instance {0}'.format(i['DBInstanceIdentifier']))
    elif i['DBInstanceStatus'] == 'stopped':
    print('DB Instance {0} is already stopped'.format(i['DBInstanceIdentifier']))
    elif i['DBInstanceStatus']=='starting':
    print('DB Instance {0} is in starting state. Please stop the cluster after starting is complete'.format(i['DBInstanceIdentifier']))
    elif i['DBInstanceStatus']=='stopping':
    print('DB Instance {0} is already in stopping state.'.format(i['DBInstanceIdentifier']))
    elif tag['Key']!=key and tag['Value']!=value:
    print('DB instance {0} is not part of {1}'.format(i['DBInstanceIdentifier'], value))
    elif len(tag['Key']) == 0 or len(tag['Value']) == 0:
    print('DB Instance {0} is not part of {1}'.format(i['DBInstanceIdentifier'], value))
    elif i['DBInstanceIdentifier'] in v_readReplica:
    print('DB Instance {0} is a Read Replica. Cannot shutdown a Read Replica instance'.format(i['DBInstanceIdentifier']))
    else:
    print('DB Instance {0} has a read replica. Cannot shutdown a database with Read Replica'.format(i['DBInstanceIdentifier']))
    else:
    print("DBInstance Engine is a cluster i.e. ['aurora-mysql','aurora-postgresql'] ")

    print("Looking for DBClusters")
    response=client.describe_db_clusters()
    for i in response['DBClusters']:
    print(f"..{i}")
    cluarn=i['DBClusterArn']
    resp2=client.list_tags_for_resource(ResourceName=cluarn)
    if 0==len(resp2['TagList']):
    print('DB Cluster {0} is not part of {1}}'.format(i['DBClusterIdentifier'], value))
    else:
    for tag in resp2['TagList']:
    if tag['Key']==key and tag['Value']==value:
    if i['Status'] == 'available':
    client.stop_db_cluster(DBClusterIdentifier=i['DBClusterIdentifier'])
    print('stopping DB cluster {0}'.format(i['DBClusterIdentifier']))
    elif i['Status'] == 'stopped':
    print('DB Cluster {0} is already stopped'.format(i['DBClusterIdentifier']))
    elif i['Status']=='starting':
    print('DB Cluster {0} is in starting state. Please stop the cluster after starting is complete'.format(i['DBClusterIdentifier']))
    elif i['Status']=='stopping':
    print('DB Cluster {0} is already in stopping state.'.format(i['DBClusterIdentifier']))
    elif tag['Key'] != key and tag['Value'] != value:
    print('DB Cluster {0} is not part of {1}'.format(i['DBClusterIdentifier'], value))
    else:
    print('DB Instance {0} is not part of {1}'.format(i['DBClusterIdentifier'], value))

    def lambda_handler(event, context):
    shut_rds_all()