Run a Lambda function for RDS using the DBInstanceIdentifier

0

Hello,

I have been trying to automate stopping RDS instance using a Lambda Function when the number of connections made to the instances are low than 1. I have used an EventBridge that triggers the Lambda function when the Alarm created goes into In Alarm.

From this, it stops all the RDS instances even those with connections. I understand that the issue is in the Lambda function since it loops through all instances and turns them off.

I was inquiring if there is a way to pass the DBInstanceIdentifier of the instance in alarm state only to the lambda function for it to only shut down the instance in which the alarm is on.

Below is the lambda code used.

import boto3 import os

target_db = None region = os.environ['AWS_REGION'] rds = boto3.client('rds', region_name=region)

def get_tags_for_db(db): instance_arn = db['DBInstanceArn'] instance_tags = rds.list_tags_for_resource(ResourceName=instance_arn) return instance_tags['TagList']

def get_tags_for_db_cluster(db): instance_arn = db['DBClusterArn'] instance_tags = rds.list_tags_for_resource(ResourceName=instance_arn) return instance_tags['TagList']

def lambda_handler(event, context):

dbs = rds.describe_db_instances()
readReplica = []
for db in dbs['DBInstances']:
    readReplicaDB = db['ReadReplicaDBInstanceIdentifiers']
    readReplica.extend(readReplicaDB)
print("readReplica : " + str(readReplica))

for db in dbs['DBInstances']:
    db_id = db['DBInstanceIdentifier']
    db_engine = db['Engine']
    print('DB ID : ' + str(db_id))
    db_tags = get_tags_for_db(db)
    print("All Tags : " + str(db_tags))
    tag = next(iter(filter(lambda tag: tag['Key'] == 'AutoStop' and tag['Value'].lower() == 'true', db_tags)), None)
    print("AutoStop Tag : " + str(tag))

    if db_engine not in ['aurora-mysql','aurora-postgresql']:
        if db_id not in readReplica and len(readReplica) == 0:
            if tag:
                target_db = db
                print("DB Details : " + str(target_db))
                db_id = target_db['DBInstanceIdentifier']
                db_status = target_db['DBInstanceStatus']
                print("DB ID : " + str(db_id))
                print("DB Status : " + str(db_status))
                if db_status == "available":
                    AutoStopping = rds.stop_db_instance(DBInstanceIdentifier=db_id)
                    print("Stopping DB : " + str(db_id))
                else:
                    print("Database already stopped : " + str(db_id))
            else:
                print("AutoStop Tag Key not set for Database to Stop...")
        else:
            print("Cannot stop or start a Read-Replica Database...")

dbs = rds.describe_db_clusters()
readReplica = []
for db in dbs['DBClusters']:
    readReplicaDB = db['ReadReplicaIdentifiers']
    readReplica.extend(readReplicaDB)
print("readReplica : " + str(readReplica))

for db in dbs['DBClusters']:
    db_id = db['DBClusterIdentifier']
    db_engine = db['Engine']
    print('DB ID : ' + str(db_id))
    db_tags = get_tags_for_db_cluster(db)
    print("All Tags : " + str(db_tags))
    tag = next(iter(filter(lambda tag: tag['Key'] == 'AutoStop' and tag['Value'].lower() == 'true', db_tags)), None)
    print("AutoStop Tag : " + str(tag))

    if db_engine in ['aurora-mysql','aurora-postgresql']:
        if db_id not in readReplica and len(readReplica) == 0:
            if tag:
                target_db = db
                db_id = target_db['DBClusterIdentifier']
                db_status = target_db['Status']
                print("Cluster DB ID : " + str(db_id))
                print("Cluster DB Status : " + str(db_status))
                if db_status == "available":
                    AutoStopping = rds.stop_db_cluster(DBClusterIdentifier=db_id)
                    print("Stopping Cluster DB : " + str(db_id))
                else:
                    print("Cluster Database already stopped : " + str(db_id))
            else:
                print("AutoStop Tag Key not set for Cluster Database to Stop...")
        else:
            print("Cannot stop or start a Read-Replica Cluster Database...")
2개 답변
0

Note that lambda_handler() accepts an "event" argument which, as described at https://docs.aws.amazon.com/lambda/latest/dg/services-cloudwatchevents.html is a document that wraps the source event. You can dig a bit deeper into the docs to find the event format that applies for your alarm, or trigger the alarm, capture the event and view it. I'd expect the DB identifier would be in there.

전문가
답변함 2년 전
0

Hello guys,

I did some research and was able to get a break through. Using SNS as a trigger to the lambda function after the Cloud Watch alarm changes to IN ALARM. CloudWatch provides a message that is sent to a SNS Topic. When the SNS triggers the Lambda Function, the message event can be obtained by a Lambda code. From that you can tap into the message dictionary and get the value of the DBIdentifier.

The below link shows how you can get the message from the SNS topic

https://docs.aws.amazon.com/lambda/latest/dg/with-sns-create-package.html#with-sns-example-deployment-pkg-python

답변함 2년 전

로그인하지 않았습니다. 로그인해야 답변을 게시할 수 있습니다.

좋은 답변은 질문에 명확하게 답하고 건설적인 피드백을 제공하며 질문자의 전문적인 성장을 장려합니다.

질문 답변하기에 대한 가이드라인

관련 콘텐츠