Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS: Why does my RDS instance keep starting after I turned it off?

I have an RDS database instance on AWS and have turned it off for now. However, every few days it starts up on its own. I don't have any other services running right now.

There is this event in my RDS log: "DB instance is being started due to it exceeding the maximum allowed time being stopped."

Why is there a limit to how long my RDS instance can be stopped? I just want to put my project on hold for a few weeks, but AWS won't let me turn off my DB? It costs $12.50/mo to have it sit idle, so I don't want to pay for this, and I certainly don't want AWS starting an instance for me that does not get used.

Please help!

like image 240
SH10151 Avatar asked Jan 16 '18 22:01

SH10151


People also ask

Will I be charged when an Amazon RDS DB Instance is idle?

Will I be charged if the DB instance is idle? What is the minimum charge for the data transferred between Amazon RDS and Amazon EC2 Instances in the same Availability Zone? No charge. It is free.

How can I tell if an RDS instance is running?

You can view the status of a DB instance by using the Amazon RDS console, the AWS CLI command describe-db-instances, or the API operation DescribeDBInstances. Amazon RDS also uses another status called maintenance status, which is shown in the Maintenance column of the Amazon RDS console.


1 Answers

That's a limitation of this new feature.

You can stop an instance for up to 7 days at a time. After 7 days, it will be automatically started. For more details on stopping and starting a database instance, please refer to Stopping and Starting a DB Instance in the Amazon RDS User Guide.

You can setup a cron job to stop the instance again after 7 days. You can also change to a smaller instance size to save money.

Another option is the upcoming Aurora Serverless which stops and starts for you automatically. It might be more expensive than a dedicated instance when running 24/7.

Finally, there is always Heroku which gives you a free database instance that starts and stops itself with some limitations.


You can also try saving the following following CloudFormation template as KeepDbStopped.yml and then deploy with this command:

aws cloudformation deploy --template-file KeepDbStopped.yml --stack-name stop-db --capabilities CAPABILITY_IAM --parameter-overrides DB=arn:aws:rds:us-east-1:XXX:db:XXX 

Make sure to change arn:aws:rds:us-east-1:XXX:db:XXX to your RDS ARN.

Description: Automatically stop RDS instance every time it turns on due to exceeding the maximum allowed time being stopped Parameters:   DB:     Description: ARN of database that needs to be stopped     Type: String     AllowedPattern: arn:aws:rds:[a-z0-9\-]+:[0-9]+:db:[^:]* Resources:   DatabaseStopperFunction:     Type: AWS::Lambda::Function     Properties:       Role: !GetAtt DatabaseStopperRole.Arn       Runtime: python3.6       Handler: index.handler       Timeout: 20       Code:         ZipFile:           Fn::Sub: |             import boto3             import time              def handler(event, context):               print("got", event)               db = event["detail"]["SourceArn"]               id = event["detail"]["SourceIdentifier"]               message = event["detail"]["Message"]               region = event["region"]               rds = boto3.client("rds", region_name=region)                if message == "DB instance is being started due to it exceeding the maximum allowed time being stopped.":                 print("database turned on automatically, setting last seen tag...")                 last_seen = int(time.time())                 rds.add_tags_to_resource(ResourceName=db, Tags=[{"Key": "DbStopperLastSeen", "Value": str(last_seen)}])                elif message == "DB instance started":                 print("database started (and sort of available?)")                  last_seen = 0                 for t in rds.list_tags_for_resource(ResourceName=db)["TagList"]:                   if t["Key"] == "DbStopperLastSeen":                     last_seen = int(t["Value"])                  if time.time() < last_seen + (60 * 20):                   print("database was automatically started in the last 20 minutes, turning off...")                   time.sleep(10)  # even waiting for the "started" event is not enough, so add some wait                   rds.stop_db_instance(DBInstanceIdentifier=id)                    print("success! removing auto-start tag...")                   rds.add_tags_to_resource(ResourceName=db, Tags=[{"Key": "DbStopperLastSeen", "Value": "0"}])                  else:                   print("ignoring manual database start")                else:                 print("error: unknown database event!")   DatabaseStopperRole:     Type: AWS::IAM::Role     Properties:       AssumeRolePolicyDocument:         Version: '2012-10-17'         Statement:           - Action:               - sts:AssumeRole             Effect: Allow             Principal:               Service:                 - lambda.amazonaws.com       ManagedPolicyArns:         - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole       Policies:         - PolicyName: Notify           PolicyDocument:             Version: '2012-10-17'             Statement:               - Action:                   - rds:StopDBInstance                 Effect: Allow                 Resource: !Ref DB               - Action:                   - rds:AddTagsToResource                   - rds:ListTagsForResource                   - rds:RemoveTagsFromResource                 Effect: Allow                 Resource: !Ref DB                 Condition:                   ForAllValues:StringEquals:                     aws:TagKeys:                       - DbStopperLastSeen   DatabaseStopperPermission:     Type: AWS::Lambda::Permission     Properties:       Action: lambda:InvokeFunction       FunctionName: !GetAtt DatabaseStopperFunction.Arn       Principal: events.amazonaws.com       SourceArn: !GetAtt DatabaseStopperRule.Arn   DatabaseStopperRule:     Type: AWS::Events::Rule     Properties:       EventPattern:         source:           - aws.rds         detail-type:           - "RDS DB Instance Event"         resources:           - !Ref DB         detail:           Message:             - "DB instance is being started due to it exceeding the maximum allowed time being stopped."             - "DB instance started"       Targets:         - Arn: !GetAtt DatabaseStopperFunction.Arn           Id: DatabaseStopperLambda 

It has worked for at least one person. If you have issues please report here.

like image 153
kichik Avatar answered Oct 10 '22 11:10

kichik