Hello,
Well, many of you may already have this, but most of you have deployed this kind of script with lambda with a list of instances as input.
However, in my case the instances changes at least weekly as we build and terminate every two weeks and instances list is not constant, so with instances list in lambda we have to change that frequently.
So to have flexibility , while building we provide a tag ('AutoOff=True') to our RDS instance so our lambda or cronjob will pick up the rds database and stop according to schedule. If we do not want the database to be shut down we simply remove the tag.
Pre-Requisite:- Use the stable version of boto and botocore which contains the rds stop/start modules
pip install botocore==1.5.75
pip install boto3==1.4.4
And here is the script, which takes input of start, stop,status , if you provide an instance name the second argument will be start/stop/status
rdsmanage.py import boto3 import logging import sys import os import boto3 rds_client = boto3.client('rds') db_instance_info = rds_client.describe_db_instances() for each_db in db_instance_info['DBInstances']: response = rds_client.list_tags_for_resource(ResourceName=each_db['DBInstanceArn']) taglist = response['TagList'] if sys.argv[1] == each_db['DBInstanceIdentifier'] and sys.argv[2] == 'stop': for tag in taglist: if tag['Key'] == 'AutoOff' and tag['Value'] == 'True' and each_db['DBInstanceStatus'] == 'available': db=each_db['DBInstanceIdentifier'] status=each_db['DBInstanceStatus'] print db +':'+ status response = rds_client.stop_db_instance(DBInstanceIdentifier=db) elif sys.argv[1] == each_db['DBInstanceIdentifier'] and sys.argv[2] == 'start': for tag in taglist: if tag['Key'] == 'AutoOff' and tag['Value'] == 'True' and each_db['DBInstanceStatus'] == 'available': db=each_db['DBInstanceIdentifier'] status=each_db['DBInstanceStatus'] print db +':'+ status response = rds_client.start_db_instance(DBInstanceIdentifier=db) elif sys.argv[1] == each_db['DBInstanceIdentifier'] and sys.argv[2] == 'status': for tag in taglist: if tag['Key'] == 'AutoOff' and tag['Value'] == 'True': db=each_db['DBInstanceIdentifier'] status=each_db['DBInstanceStatus'] print db +':'+ status elif sys.argv[1] == 'stop' and sys.argv[:2]: for tag in taglist: if tag['Key'] == 'AutoOff' and tag['Value'] == 'True' and each_db['DBInstanceStatus'] == 'available': db=each_db['DBInstanceIdentifier'] status=each_db['DBInstanceStatus'] print db +':'+ status response = rds_client.stop_db_instance(DBInstanceIdentifier=db) elif sys.argv[1] == 'start' and sys.argv[:2]: for tag in taglist: if tag['Key'] == 'AutoOff' and tag['Value'] == 'True' and each_db['DBInstanceStatus'] == 'stopped': db=each_db['DBInstanceIdentifier'] status=each_db['DBInstanceStatus'] print db +':'+ status response = rds_client.start_db_instance(DBInstanceIdentifier=db) elif sys.argv[1] == 'status' and sys.argv[:2]: for tag in taglist: if tag['Key'] == 'AutoOff' and tag['Value'] == 'True': db=each_db['DBInstanceIdentifier'] status=each_db['DBInstanceStatus'] print db +':'+ status
Sample Run To check the status, start and stop
root@wash-i-xx-restore ~ $ python rdsmanage.py status c92base:stopped cs89upg:stopped cs92dev:stopped csdmo:stopped dp4adwe8ind3oy:stopped rp19a3160yh53k3:stopped sitecore:stopped root@wash-i-xx-restore ~ $ python rdsmanage.py start c92base:starting cs89upg:starting cs92dev:starting csdmo:starting dp4adwe8ind3oy:starting rp19a3160yh53k3:starting sitecore:starting root@wash-i-xx-restore ~ $ python rdsmanage.py stop c92base:stopping cs89upg:stopping cs92dev:stopping csdmo:stopping dp4adwe8ind3oy:stopping rp19a3160yh53k3:stopping sitecore:stopping
You can also stop the instance specifically by providing the instance name and then action.
root@ /scripts/db_reconfiguration $ python /scripts/rdsmanage.py xxx stop ipfx2:available root@ /scripts/db_reconfiguration $ python /scripts/rdsmanage.py xxx status ipfx2:stopping
You can schedule this script using cron or lambda, for example we want stop databases at night 7PM and start them at 7AM. The cron looks like follows
00 19 * * * python /scripts/rdsmanage.py stop 00 07 * * * python /scripts/rdsmanage.py start
00 19 * * * python /scripts/rdsmanage.py ipfx stop 00 07 * * * python /scripts/rdsmanage.py ipfx start
Hope this may help you somewhere.
Thanks
Suresh
Hi
Am getting below error while running this script in lambda ,could you help me to clear this error please,
Response:
{
“errorMessage”: “module initialization error”
}
Request ID:
“9082d091-3273-11e8-95e5-65c67cf8431c”
Function Logs:
START RequestId: 9082d091-3273-11e8-95e5-65c67cf8431c Version: $LATEST
module initialization error: An error occurred (AccessDenied) when calling the ListTagsForResource operation: User: arn:aws:sts::801263038525:assumed-role/lambda_role_test_rds_nonprod/autostop_rds_test is not authorized to perform: rds:ListTagsForResource on resource: arn:aws:rds:eu-west-1:801263038525:db:intl-ireland-ds-talend-rds-u-rds-mysql-nonprod
END RequestId: 9082d091-3273-11e8-95e5-65c67cf8431c
REPORT RequestId: 9082d091-3273-11e8-95e5-65c67cf8431c Duration: 456.45 ms Billed Duration: 500 ms Memory Size: 128 MB Max Memory Used: 36 MB
module initialization error
An error occurred (AccessDenied) when calling the ListTagsForResource operation: User: arn:aws:sts::801263038525:assumed-role/lambda_role_test_rds_nonprod/autostop_rds_test is not authorized to perform: rds:ListTagsForResource on resource: arn:aws:rds:eu-west-1:801263038525:db:intl-ireland-ds-talend-rds-u-rds-mysql-nonprod
Sorry for the delay, it marked as spam.
User: arn:aws:sts::801263038525:assumed-role/lambda_role_test_rds_nonprod/autostop_rds_test is not authorized to perform: rds:ListTagsForResource on resource
As per Error, it seems you the lambda role does not have privileges on RDS ListsTagsResource, hence failure.
Suresh