Managing Amazon RDS clusters can be a time-consuming task, especially when you need to start and stop clusters based on specific schedules or manual triggers. This blog will walk you through creating an AWS Lambda function that starts and stops RDS clusters using API Gateway routes.
Prerequisites
Before you begin, ensure you have the following:
- An AWS account.
- Basic knowledge of AWS Lambda and API Gateway.
Step 1: Setting Up IAM Roles and Policies
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds:StartDBCluster",
"rds:StopDBCluster",
"rds:DescribeDBClusters"
],
"Resource": "*"
}
]
}
Step 2: Create the Lambda Function
import boto3
import datetime
from botocore.exceptions import ClientError
#create rds client rds_client
def get_tags_from_cluster(cluster_response):
stop_time = None
start_time = None
scheduled_action = None
manual_invocation = None
for tag in cluster_response['DBClusters'][0]['TagList']:
if tag['Key'] == 'manual-invocation':
manual_invocation = tag['Value']
elif tag['Key'] == 'stop-time':
stop_time = tag['Value']
elif tag['Key'] == 'start-time':
start_time = tag['Value']
elif tag['Key'] == 'scheduled-action':
scheduled_action = tag['Value']
return manual_invocation, stop_time, start_time, scheduled_action
def start_rds_cluster(db_cluster_identifier):
try:
response = rds_client.start_db_cluster(DBClusterIdentifier=db_cluster_identifier)
return f"Cluster {db_cluster_identifier} start action executed. Will take a few minutes to complete action."
except ClientError as e:
return f"Error starting cluster {db_cluster_identifier}: {str(e)}"
def stop_rds_cluster(db_cluster_identifier):
try:
response = rds_client.stop_db_cluster(DBClusterIdentifier=db_cluster_identifier)
return f"Cluster {db_cluster_identifier} stop action executed. Will take a few minutes to complete action."
except ClientError as e:
return f"Error stopping cluster {db_cluster_identifier}: {str(e)}"
def rds(resource):
results = []
try:
response = rds_client.describe_db_clusters()
for db_cluster in response['DBClusters']:
db_cluster_identifier = db_cluster['DBClusterIdentifier']
print(f"Processing RDS Cluster: {db_cluster_identifier}")
cluster_response = rds_client.describe_db_clusters(DBClusterIdentifier=db_cluster_identifier)
status = db_cluster.get('Status', '')
manual_invocation, stop_time, start_time, scheduled_action = get_tags_from_cluster(cluster_response)
if manual_invocation == 'True':
if 'start' in resource:
if status == 'stopped':
result = start_rds_cluster(db_cluster_identifier)
results.append(result)
elif status == 'starting':
results.append(f"RDS Cluster '{db_cluster_identifier}' already in starting state")
elif status == "stopping":
results.append(f"RDS Cluster '{db_cluster_identifier}' cluster is in stopping state. Cannot start now")
else:
results.append(f"RDS Cluster '{db_cluster_identifier}': already in start state")
elif 'stop' in resource:
if status == 'available':
result = stop_rds_cluster(db_cluster_identifier)
results.append(result)
elif status == 'stopping':
results.append(f"RDS Cluster '{db_cluster_identifier}' already in stopping state")
elif status == "starting":
results.append(f"RDS Cluster '{db_cluster_identifier}' cluster is in starting state. Cannot stop now")
else:
results.append(f"RDS Cluster '{db_cluster_identifier}': already in stop state")
else:
results.append(f"RDS Cluster '{db_cluster_identifier}': manual invocation not set to True")
if not results:
return "No RDS clusters found with the required tags."
return results
except Exception as e:
return f"Internal Server Error: {str(e)}"
def lambda_handler(event, context):
resource = event.get('input', '')
if 'rds' in resource:
return rds(resource)
Step 3: Deploy the Lambda Function
- Open the AWS Management Console.
- Navigate to the Lambda service.
- Click on “Create function” and choose “Author from scratch”.
- Enter a name for your function and select the execution role you created earlier.
- Copy and paste the above Python script into the function code editor.
- Click “Deploy”.
Step 4: Set Up API Gateway
- Open the API Gateway service in the AWS Management Console.
- Click on “Create API” and choose “HTTP API”.
- Add a new route for starting the RDS cluster:
- Resource path:
/rds/start
- Add another route for stopping the RDS cluster:
- Resource path:
/rds/stop
- For both routes, set the integration target to your Lambda function.
Step 5: Test Your API
You can now test your API using tools like Postman or curl. Send a POST request to /rds/start
or /rds/stop
with the necessary payload.
For example, to start the RDS cluster, you can use the following curl command:
https://<your-api-id>.execute-api.<region>.amazonaws.com/rds/start
Conclusion
By following these steps, you have successfully automated the process of starting and stopping RDS clusters using AWS Lambda and API Gateway. This setup ensures efficient management of RDS clusters, allowing you to control them programmatically based on your needs.
Enhance your RDS management by implementing this automated solution today! Follow the steps outlined in the tutorial to easily start and stop your RDS clusters with AWS Lambda and API Gateway, ensuring optimal resource utilization based on your specific needs.