A Step-by-Step Guide to AWS Instance Scheduler
Tags: aws, devops, tutorial, cloud
Published: 2021-04-27 19:40:51

<!-- wp:paragraph -->
<p>AWS Instance Scheduler is a popular option for saving up a large portion of the cost of computing services in situations where there are <strong>predictable planned times for operating compute services</strong>. In other words, since no clients are accessing particular environments during the period, it's normal for development environments or workloads to be shut down during non-working times.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>By evaluating when the instances are more widely used, you can implement more complex schedules, or even apply an always-stopped schedule and then start up the instances when you need them.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In this article, we will cover a step-by-step guide to creating an AWS schedule and apply it to several instances. At the very end, there is a section on how to do this in less than 5 mins</a>, without having to set up and manage the infrastructure for the scheduler.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>Solution Overview</h2>
<!-- /wp:heading -->

<!-- wp:image {"align":"center"} -->
<div class="wp-block-image"><figure class="aligncenter"><img src="https://lh4.googleusercontent.com/Z0mcI0cjac153FZKafomCfrfU2hLACcZQ7TJU7_fjh83aZemqYckVYv2kRmZj_kC9HWzF1k0h3-eoXQta4jAw-zVzYZd-rPVB2AfWycMivsgKb3LPawsKJyYROEtM0qBYLwXaAU8" alt="AWS-Instance-Scheduler-Architecture"/><figcaption>AWS Instance Scheduler Architecture</figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>This <a href="https://aws.amazon.com/solutions/implementations/instance-scheduler/" target="_blank" rel="noreferrer noopener">CloudFormation template</a> creates an environment for the AWS Instance Scheduler. The solution uses the following AWS services:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li><a href="https://aws.amazon.com/cloudwatch/" target="_blank" rel="noreferrer noopener">Amazon CloudWatch</a></li><li><a href="https://aws.amazon.com/lambda/" target="_blank" rel="noreferrer noopener">AWS Lambda</a></li><li><a href="https://aws.amazon.com/dynamodb/" target="_blank" rel="noreferrer noopener">Amazon DynamoDB</a></li><li><a href="https://aws.amazon.com/rds/" target="_blank" rel="noreferrer noopener">AWS RDS</a></li><li><a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/concepts.html" target="_blank" rel="noreferrer noopener">AWS EC2</a></li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>A CloudWatch event triggers the Lambda function whose job is to check the EC2 and RDS instances, find the appropriate tag for a schedule, and match it against the definition of that schedule saved in DynamoDB. After that, depending on the targeted state the Lambda function decides to turn off or turn on the EC2 or RDS instance.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The default behavior of this solution is to stop EC2 and RDS instances, not terminate or delete them, as terminated instances cannot be restarted. It is also a good idea to create an RDS Instance Snapshot before stopping the instances. Each new snapshot overrides the last one. This is part of setting up the stack and is explained in the next section.&nbsp;&nbsp;&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>How it works</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Schedules actually define when the EC2 and RDS instances should be running. Each schedule has a unique name and its configuration is stored in the DynamoDB.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The entire setup revolves around tagging, which is basically a label you give to an instance to be able to categorize it and later quickly identify it. Tags are defined with a <em>key-value</em> pair which you define.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The AWS Instance Scheduler solution has a default <em>tag key</em> called <strong><em>Schedule</em></strong>. You can of course change it if you need. The <em>tag value</em> should be the <strong><em>unique name</em></strong> of the schedule you want to apply to the instance. Each time the Lambda function runs, it will retrieve the configuration for the schedule from the DynamoDB and apply it to the instance.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>For example you could define a tag with <em>key: value</em> = <strong><em>Schedule: work-days</em></strong>. The name work-days specifies a schedule where the instances should shut down on Friday evening and get started up on Monday morning. Therefore, the instances that are supposed to be covered by this schedule should be tagged with the <em>key: value</em> pair. In the example this is <strong><em>Schedule: work-days</em></strong>.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>Create an Instance Scheduler in your AWS Account</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3>Launch the stack</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Firstly make sure you’re signed in in your AWS account. The starting step is to launch the instance schedule stack in your AWS account. You can launch the cloud formation template by clicking <a href="https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/new?templateURL=https:%2F%2Fs3.amazonaws.com%2Fsolutions-reference%2Faws-instance-scheduler%2Flatest%2Finstance-scheduler.template" target="_blank" rel="noreferrer noopener">on this link</a>. The template launches in the US East - N. Virginia region by default, so adjust the region according to your needs. Likewise, verify that the correct template is being used, and move to the next step.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center"} -->
<div class="wp-block-image"><figure class="aligncenter"><img src="https://lh5.googleusercontent.com/EJPNbaLoTbIhptLOJXOn7x46iLvW1M2wCXWW9cSNEzpOiob0gUjqZO9KE7ZiBifCvD3DDXbwipi42BkIVXRxyEZzuqZvFcHNlStSLG-q-qtY7oIMEfnXxeYqHIeWM9SKlGgMFMg8" alt="Instance-Scheduler-stack-Step1"/><figcaption>Creating the Instance Scheduler stack - Step 1</figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Secondly, you need to define the <strong><em>Stack name</em></strong> and some specific parameters, like tag name (if you’d like to change the default tag name <strong><em>Schedule</em></strong>), which service you want to schedule: EC2, RDS or Both, whether you want and RDS instance snapshot before shutting down the resource, the frequency of running for the AWS Lambda function, whether you want CloudWatch metrics and logs and a couple more parameters.&nbsp;&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:image {"id":4163,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image size-large"><img src="https://mk0microtica2di3k2co.kinstacdn.com/wp-content/uploads/2021/04/screencapture-console-aws-amazon-cloudformation-home-2021-04-22-22_41_46-759x1024.png" alt="Instance-Scheduler-stack-Step2" class="wp-image-4163"/><figcaption>Creating the Instance Scheduler stack - Step 2</figcaption></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Thirdly, leave the stack options as they are - empty. Continue to the last step, review the changes and deploy the stack by clicking on Create. In the AWS Console you can follow the status of the stack deployment. <strong>CREATE_COMPLETE </strong>means<strong> </strong>that the solution is deployed.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>Define the Schedule</h3>
<!-- /wp:heading -->

<!-- wp:image {"align":"center"} -->
<div class="wp-block-image"><figure class="aligncenter"><img src="https://lh4.googleusercontent.com/ZbsRnC0YoLPMfwq9tG9pT6Ld1XyHjf9jzdOW6ioU_mNySM2MWOyBr2lTYCThkNloR8IZY8B9fuLhhVqM0llhyKe6w_txWyEA6IbFYI30GLnUW_EWWBgQpx-pss7wtMgJDHWO6NiS" alt="Deployed-Instance-Scheduler-stack"/><figcaption>Deployed Instance Scheduler stack</figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>In your AWS console you will find an Amazon DynamoDB table (ConfigTable) where the configurations for the periods and schedules are going to be stored. The schedule is defined by several parameters, from which the most important is the <strong>period</strong>. This is the time in which the instances should be active. It can be as specific as hours, days and months. For the schedule to work you must specify at least one of the period’s definitions: <em>begintime</em>, <em>endtime</em>, <em>weekdays</em>, <em>months</em> or <em>monthdays</em>.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The <em>begintime</em> field defines when the instance schedule should start the instances, and accordingly the <em>endtime</em> is when the instances should be stopped. If you define only a starting time then the instance will have to be stopped manually.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In the ConfigTable are already some predefined samples that you can use or create your own. A sample period will look like this:&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center","width":-125,"height":-77} -->
<div class="wp-block-image"><figure class="aligncenter is-resized"><img src="https://lh6.googleusercontent.com/iFacWOwVkJ_M7ULdP1p7_6e7qXs6C6lEeV-ZFL9vfkK74r0OpX8qQlRc1pdwRKH4SaIYxfFDRId6kiSkf_yFzNFrT-kNWovbDnpVHKN1bXl7ni6JCByPA6FvlXt8qFhLqgrSb2QY" alt="Office-hours-sample-period" width="-125" height="-77"/><figcaption>Office hours sample period</figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>This is a <strong>period</strong> set to define office hours with a <em>begintime</em> of 9 am and an <em>endtime</em> of 5 pm, applied only Monday to Friday. This period is used in a schedule to define UK office hours. You can change the periods according to your needs directly from the AWS console.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Schedules don’t have to be used only for shutting down resources. There are also some more complicated schedules you can create, for example if you look at the <em>Vertical scaling on weekdays </em>schedule. Here you’ll see it’s purpose is to run on smaller EC2 instances on weekends and use micro instances on working days.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center","width":675,"height":388} -->
<div class="wp-block-image"><figure class="aligncenter is-resized"><img src="https://lh4.googleusercontent.com/-ZmKJuLT7PKlvtEC4Cv9E5Y6rXmdbdg2k7y1tE_Qz7ieEAzbgx7p1jPkykTZMKqrykVp5RGmvCrXiWYP_iht6KPMrYXjcYWz5TMVUBNehRmgt-fHzHcn9BGVIxgqQ4Vla8rMXIjY" alt="Vertical-scaling-on-weekdays-schedule" width="675" height="388"/><figcaption>Vertical scaling on weekdays<em> </em>schedule</figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:heading {"level":3} -->
<h3>Tag the appropriate instances</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>In order for a schedule to work, you need to tag the EC2/RDS instances you want the schedule to be applied on. You should use the <strong><em>tag key </em></strong>(the tag name you defined when creating the CFN stack - default value is Schedule) and the <strong><em>tag value </em></strong>- which is the name of the schedule stored in the Config table. When you find your resource you go to <em>Manage Tags</em> and enter the key-value pair defining the schedule. You can also use the <a href="https://docs.aws.amazon.com/ARG/latest/userguide/tag-editor.html" target="_blank" rel="noreferrer noopener">Tag Editor</a> to tag multiple instances at once.</p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center"} -->
<div class="wp-block-image"><figure class="aligncenter"><img src="https://lh3.googleusercontent.com/Zz2mdPoX_00C7EL7Y74aZaH49lnz-Shy-nARWQpq-okyDI9owRpMGU6FoSQu0OXp-9_K08HWi6VdOptUNIdFYeeIbSE3O7ZSnHhZ36c07Kkn1roJ5OCTjid-pDUkG7-vNqfHYBYJ" alt="tags-EC2-instance"/><figcaption>Managing tags for an EC2 instance </figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:heading {"level":3} -->
<h3>CloudWatch Metrics</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>In conclusion, after the tag is applied the instance will be part of the resources managed by the schedule you defined for it. You can check the CloudWatch metrics to make sure the solution runs as it's designed to. In the CloudWatch console there will be a namespace <strong><em>&lt;stackname&gt;:InstanceScheduler</em></strong> (<em>DevInstanceScheduler:InstanceScheduler </em>in our case). The Lambda function updates the metrics each time it runs for each instance it’s supposed to apply a schedule on. Moreover, here you get a sense of the number of instances that are running and the ones that are stopped.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 id="saving-schedule-microtica">Create a Saving Schedule in Microtica</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>If you don’t feel like going through the hustle of launching and deploying a solution in your AWS console, you can use Microtica’s Cloud Waste Manager feature. All you have to do is:</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><li><a href="https://portal.microtica.com/register?utm_source=devto&utm_medium=referral_link&utm_campaign=aws_instance_scheduler&utm_content=instance-schedule" target="_blank" rel="noreferrer noopener">Sign up for free</a></li><li><a href="https://docs.microtica.com/connect-an-aws-account?utm_source=devto&utm_medium=referral_link&utm_campaign=aws_instance_scheduler">Connect your AWS Account</a></li><li>Set permissions only for turn on/off of instances</li><li>Go to <a href="https://portal.microtica.com/tools/schedules?utm_source=devto&utm_medium=referral_link&utm_campaign=aws_instance_scheduler" target="_blank" rel="noreferrer noopener">Saving Schedules</a> → Select an active time period for your instances</li><li>Select the instances you want to apply the schedule to</li><li>Activate</li></ol>
<!-- /wp:list -->

<!-- wp:image -->
<figure class="wp-block-image"><img src="https://lh3.googleusercontent.com/L6y0YP4Ndi8hhiynDpS60udiWS22L5tNVsiuV-8Yuhz9p43s_FN_odoozGDUjdMNpEov3fBPyV4eM5iTn8tsduoHxEpXfoP80EaRnOLiRwNQGnOf-mziqihyWpjCa-vcMyXTUOdB" alt="saving-schedule-microtica"/><figcaption>Create a saving schedule in Microtica</figcaption></figure>
<!-- /wp:image -->


<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->

<!-- wp:quote {"className":"is-style-large"} -->
<blockquote class="wp-block-quote is-style-large"><p><em>Check out our comprehensive guide on creating an&nbsp;</em><a href="https://microtica.com/aws-cost-optimization?utm_source=devto&utm_medium=referral_link&utm_campaign=cost_optimization_pillar" target="_blank" rel="noreferrer noopener">AWS cost optimization strategy</a><em>.</em></p></blockquote>
<!-- /wp:quote -->