Skip to content

How do I stop an Aurora cluster for longer than 7 days?

4 minute read
0

I want to know how to stop an Amazon Aurora cluster for longer than 7 days.

Resolution

Configure IAM permissions

Create the following AWS Identity and Access Management (IAM) policy to allow AWS Lambda to start, stop, and retrieve information from the cluster:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "VisualEditor0",
      "Effect": "Allow",
      "Action": [
        "rds:StartDBCluster",
        "rds:StopDBCluster",
        "rds:ListTagsForResource",
        "rds:DescribeDBInstances",
        "rds:StopDBInstance",
        "rds:DescribeDBClusters",
        "rds:StartDBInstance"
      ],
      "Resource": "*"
    }
  ]
}

Note: Use a wildcard (*) for all resources, or specify your cluster's Amazon Resource Name (ARN).

Create an IAM role, and attach the required IAM policies

Use the IAM console to create an IAM role and attach the required policies. For Service or use case, choose Lambda. For permissions policies, select the AWSLambdaBasicExecutionRole policy, and then select the policy that you created.

Add tags to the DB clusters

Use the Amazon Relational Databases (Amazon RDS) console to add two tags to your DB cluster. For Key, enter autostart and then enter yes for Value. Choose Add another Tag, and then enter autostop for Key and yes for Value.

Create Lambda functions to start and stop the DB cluster

To create a Lambda function to start the cluster, complete the following steps:

  1. Open the Lambda console.

  2. In the navigation pane, choose Functions.

  3. Choose Create function.

  4. Choose Author from scratch.

  5. For Function name, enter a name for your function.

  6. For Runtime, choose Python 3.13.

  7. For Architecture, keep the default selection of x86_64.

  8. Expand Change default execution role.

  9. For Execution role, choose Use an existing role.

  10. For Existing role, select your IAM role.

  11. Choose Create function.

  12. Choose the Code tab.

  13. In the Code source editor, delete the example code and enter the following code:

    import boto3
    rds = boto3.client('rds')
    
    def lambda_handler(event, context):
        #Start DB clusters
        dbs = rds.describe_db_clusters()
        for db in dbs['DBClusters']:
            #Check if DB cluster stopped. Start it if eligible.
            if (db['Status'] == 'stopped'):
                try:
                    GetTags = rds.list_tags_for_resource(ResourceName=db['DBClusterArn'])['TagList']
                    for tags in GetTags:
                        #if tag "autostart=yes" is set for cluster, start it
                        if(tags['Key'] == 'autostart' and tags['Value'] == 'yes'):
                            result = rds.start_db_cluster(DBClusterIdentifier=db['DBClusterIdentifier'])
                            print("Starting cluster: {0}.".format(db['DBClusterIdentifier']))
                except Exception as e:
                    print("Cannot start cluster {0}.".format(db['DBClusterIdentifier']))
                    print(e)
    
    if __name__ == "__main__":
        lambda_handler(None, None)
  14. Choose Deploy.

  15. Choose the Configuration tab, and then choose Edit.

  16. For Timeout, choose 0 for min and 10 for sec.

  17. Choose Save.

To create a Lambda function to stop the cluster, repeat the preceding steps. In the Code source editor, enter the following code:

import boto3
rds = boto3.client('rds')

def lambda_handler(event, context):
    #Stop DB clusters
    dbs = rds.describe_db_clusters()
    for db in dbs['DBClusters']:
        #Check if DB cluster started. Stop it if eligible.
        if (db['Status'] == 'available'):
            try:
                GetTags = rds.list_tags_for_resource(ResourceName=db['DBClusterArn'])['TagList']
                for tags in GetTags:
                #if tag "autostop=yes" is set for cluster, stop it
                    if(tags['Key'] == 'autostop' and tags['Value'] == 'yes'):
                        result = rds.stop_db_cluster(DBClusterIdentifier=db['DBClusterIdentifier'])
                        print ("Stopping cluster: {0}.".format(db['DBClusterIdentifier']))
            except Exception as e:
                print ("Cannot stop cluster {0}.".format(db['DBClusterIdentifier']))
                print(e)
                

if __name__ == "__main__":
    lambda_handler(None, None)

Test your functions

Before you test your functions, stop your DB cluster. Then, use the Lambda console to invoke your functions. For Edit saved event, select your event.

Create a schedule to automatically start and stop your DB cluster

You can use the Amazon EventBridge Scheduler to create a schedule that starts and stops your cluster at a specified time before and after a maintenance window. for Schedule type, choose Cron-based schedule, and then enter the cron expression.

Related information

How can I use a Lambda function to stop an Amazon RDS instance for longer than seven days?

AWS OFFICIALUpdated a month ago
1 Comment

Check out github.com/sqlxpert/stay-stopped-aws-rds-aurora , my open-source Lambda solution. There's also Step Function version, github.com/sqlxpert/step-stay-stopped-aws-rds-aurora .

The accepted AWS answer isn't reliable.

The bigger and busier your Aurora and RDS environment, the greater the risk that describe_db_clusters() will be subject to throttling or won't return information about all clusters. Use RDS.Paginator.DescribeDBClusters .

There is no need to call list_tags_for_resource. TagList is in the "describe" response! Follow the link above and search within-page for Response Syntax .

Eventually, the opportunity to stop a running cluster will be missed. Because the status check (via describe_db_clusters) and the stop request (stop_db_cluster) are separate, checking status first creates a race condition. Call stop_db_cluster without regard to Status, and handle InvalidDBClusterStateFault . See 5 AWS Services, 5 Different Approaches to Idempotence on community.aws for a detailed explanation.

Hope this helps!

replied 4 months ago