Click here to Skip to main content
13,795,575 members
Click here to Skip to main content
Add your own
alternative version

Stats

19.1K views
468 downloads
5 bookmarked
Posted 2 Jun 2017
Licenced CPOL

Start/Stop RDS instances on schedule

, 5 Jun 2017
Rate this:
Please Sign up or sign in to vote.
How to start/stop RDS instances on schedule with aws-sdk, nodeJs Lambda function and CloudWatch

Introduction

As you might know, AWS recently added an ability to start and stop RDS instances, which can be really helpful for anyone who wants to save some costs on AWS bill. Let's use AWS Lambda function with CloudWatch events to stop RDS instances used by testing environment at night and on weekends.

Using the Code

First, let's create policy, which is in AWS IAM console. Go to Services -> Policies -> Create Policy -> Create Your Own Policy.

Let's call it RDSManagement. Put the code given below to the 'Policy Document' field:

{
    "Version": "2012-10-17",
    "Statement": [        
        {
            "Action": [
                "rds:StopDBInstance",
                "rds:StartDBInstance"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}

Press 'Create policy', Create Your Own Policy put name, description and JSON to the appropriate fields and press save. Eventually, you have to get something like on the screenshot bellow: 

The second step is to create a role which will be associated with lambda function and allow it to manage RDS instances.

Navigate to Services -> Roles -> Create new Role. Select 'AWS Lambda' in 'AWS Service Role' section. Search for the policy we created previously, select it, and press 'Next'. Put LambdaRDSManagement as a Role Name, set some description and press 'Create Role'.

Now we are ready to go and create lambda function which will manage our instances. Navigate to Services -> Lambda -> Create a Lambda function -> Blank function. Let's call it 'ManageRDSInstances', select latest Node js 6.x as a runtime. Ignore lambda function code for now, and select 'Choose an existing role' in 'Role' field. You have to be able to find the previously created role in 'Existing role' field. Press 'Next' -> 'Create function'.

Good, a puppet for the function is created and ready to go. You can check out a repo on github, clone it, run 'npm install', archive the whole folder to a '.ZIP' file. (or just download it - rds-lambda-stop-start.zip). We are using original aws-sdk for node js provided by amazon.

It contains mainly three files:

  1. index.js - which is an actual lambda function which will handle your CloudWatch event:
    var startInstance = require('./start');
    var stopInstance = require('stop');
    
    exports.handler = (event, context, callback) => {
        event.instances.forEach((instance) => {
            switch (event.action) {
                case 'stop':
                    console.log(`Stopping instance '${instance}'...`);
                    stopInstance(instance);
                    break;
                case 'start':
                    console.log(`Starting instance '${instance}'...`);
                    startInstance(instance);
                    break;
                default:
                    throw `Invalid action ${event.action}`;
            }
        })
        callback(null, 'Done!');
    };
  2. stop.js, which stops running instance and create RDS snapshot in format "{instanceId}-{day}-{month}-{year}-{ticks}":
    var AWS = require('aws-sdk');
    
    module.exports = (instanceId) => {
      var rds = new AWS.RDS();
      var today = new Date();
      var params = {
        DBInstanceIdentifier: instanceId,
        DBSnapshotIdentifier: `${instanceId}-${today.getDate()}-
                              ${today.getMonth() + 1}-${today.getFullYear()}-${today.getTime()}`
      };
      rds.stopDBInstance(params, function (err, data) {
        if (err) console.log(err, err.stack); // an error occurred
        else console.log(data);           // successful response
      });
    };
  3. start.js which starts stopped instance.
    var AWS = require('aws-sdk');
    
    module.exports = (instanceId) => {
      var rds = new AWS.RDS();
      var params = {
        DBInstanceIdentifier: instanceId
      };
      rds.startDBInstance(params, function (err, data) {
        if (err) console.log(err, err.stack); // an error occurred
        else console.log(data);           // successful response
      });
    };

Now let's upload our archive to newly created lambda function. Services -> Lambda -> ManageRDSInstances, and change Code entry type to 'Upload a .ZIP file'. Press 'Upload', select your zip file and press 'Save'. Now we need to configure test event: Actions -> Configure test event.

{  
   "instances":[  
      "some-test-instance-1",
      "some-test-instance-2"
   ],
   "action":"stop"
}

Where some-test-instance-1 and some-test-instance-2 are your testing RDS instances. After pressing Press 'Save and Test', you will see that your RDS instances changed state to 'Stopping' and soon to 'Stopped'. Presto!

After they are stopped, you can run the same test with action 'start', which will run change state of instances to running.

The last thing is to set up CloudWatch rules to trigger these function on schedule. Services -> CloudWatch -> Rules -> Create Rule. Select Schedule instead of default Event Pattern. Now you need to set up cron time, you can read more about it here. Keep in mind that time must be set in GMT timezone. For instance, to correctly start instances every morning Monday to Friday at 8 am in GMT+12 timezone cron time will look like this: '0 20 ? * SUN-THU *'.

After you set cron time for waking up your instances, select Lambda function as a Target and pick your newly create lambda function. Then in Configure Input section put your JSON to Constant(JSON text) field:

{ "instances": ["some-test-instance-1",
"some-test-instance-2"], "action":"start" }

Configure Details -> Update rule. Done!

Now your instances will be woken on every morning from Monday to Friday. Create a similar rule with correct cron time for stopping them, do not forget to change action from start to stop in the json:

{ "instances": ["some-test-instance-1",
"some-test-instance-2"], "action":"stop" }

Points of Interest

Starting/stopping RDS instances was a feature which was expected for a long while, and finally, guys from Amazon provided this functionality. Hopefully, this will reduce your AWS bill as well :)

History

  • 6.02.2017 - Article created
  • 6.03.2017 - fixed small mistakes, added images

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Ivan Perevernykhata
Software Developer (Senior) MYOB
New Zealand New Zealand
No Biography provided

You may also be interested in...

Pro
Pro

Comments and Discussions

 
Questionurgent question why .zip file tobe upload required?? Pin
abhishekmittal25-Nov-18 19:37
memberabhishekmittal25-Nov-18 19:37 
AnswerRe: urgent question why .zip file tobe upload required?? Pin
abhishekmittal25-Nov-18 20:57
memberabhishekmittal25-Nov-18 20:57 
QuestionCloudwatch logs setup Pin
Member 1168407416-Nov-18 0:38
memberMember 1168407416-Nov-18 0:38 
QuestionThank you ! Pin
Member 140412591-Nov-18 23:08
memberMember 140412591-Nov-18 23:08 
QuestionQuantity Pin
Member 139322763-Aug-18 1:24
memberMember 139322763-Aug-18 1:24 
QuestionAWS Billing without any update Pin
Member 1391194917-Jul-18 5:46
memberMember 1391194917-Jul-18 5:46 
AnswerRe: AWS Billing without any update Pin
Matthew@work18-Jul-18 2:02
adminMatthew@work18-Jul-18 2:02 
QuestionRegarding instance id for RDS Pin
Radhika Peddi9-Apr-18 21:12
memberRadhika Peddi9-Apr-18 21:12 
Questionthanks Pin
Member 137090335-Mar-18 3:00
memberMember 137090335-Mar-18 3:00 
QuestionVery helpfull Pin
Member 4631993-Dec-17 8:37
memberMember 4631993-Dec-17 8:37 
QuestionThanks for this RDS stop start Pin
Member 134937881-Nov-17 10:41
memberMember 134937881-Nov-17 10:41 
QuestionStop instance Part Not Working Pin
Member 1341541718-Sep-17 1:15
memberMember 1341541718-Sep-17 1:15 
AnswerRe: Stop instance Part Not Working Pin
Ivan Perevernykhata22-Nov-17 22:51
memberIvan Perevernykhata22-Nov-17 22:51 
QuestionChange to TAGS Pin
Member 114298678-Sep-17 4:43
memberMember 114298678-Sep-17 4:43 
AnswerRe: Change to TAGS Pin
Ivan Perevernykhata22-Nov-17 22:53
memberIvan Perevernykhata22-Nov-17 22:53 
GeneralRe: Change to TAGS Pin
Member 136085725-Jan-18 4:18
memberMember 136085725-Jan-18 4:18 
QuestionWhen I do npm install, I get the following error. Pin
ShabbirBata15-Aug-17 12:51
memberShabbirBata15-Aug-17 12:51 
AnswerRe: When I do npm install, I get the following error. Pin
Ivan Perevernykhata22-Nov-17 22:54
memberIvan Perevernykhata22-Nov-17 22:54 
QuestionSingle file/code? Pin
Jason Bradley15-Aug-17 11:36
memberJason Bradley15-Aug-17 11:36 
GeneralMy vote of 5 Pin
Member 133446983-Aug-17 14:15
memberMember 133446983-Aug-17 14:15 
Questionvery good Pin
Member 133446983-Aug-17 14:14
memberMember 133446983-Aug-17 14:14 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web04 | 2.8.181207.3 | Last Updated 5 Jun 2017
Article Copyright 2017 by Ivan Perevernykhata
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid