At Content Bloom we leverage Amazon Web Services for not only hosting websites and infrastructure, but we also host a wide range of development and demo machines. If you’re like us, it’s an ongoing struggle to make sure we’re turning off our machines at the end of the day and not burning resources for no reason.
We wanted to setup our AWS infrastructure so that we could tag an instance and based on the region-specific tag applied, shut-down the machine at the end of the business day. We have colleagues spread through-out the world, so it was important that this was configurable so that we could define working hours for each region. Turns out, there’s a solution that exists already – AWS Instance Scheduler.
We’re going to leverage several of the AWS services for the Instance Scheduler:
AWS Lambda – a service to execute code without provisioning a server, which is why it’s called serverless. We’ll leverage it to execute the shut-down / start-up code.
Amazon DynamoDB – a NoSQL database offering managed in AWS. We’ll be using it to store the instance scheduler shut-down configurations.
Amazon CloudWatch – monitoring and management service; monitors operational health of infrastructure. We’ll use it to trigger events and execute Lambda functions.
We’re going to use CloudWatch events to execute some code that should check to see if the machine should be shut-down based on the tags, etc. CloudWatch events trigger a Lambda function which will determine whether or not it should shut down the machines down (or started, etc) based on configurations stored in DynamoDB tables.
Taken from https://aws.amazon.com/answers/infrastructure-management/instance-scheduler/
AWS CloudFormation
So we’ve talked about Lamba, DynamoDB & CloudWatch – but now it’s time to set this all up. One of the cool features in AWS is CloudFormation which will allow you to design infrastructure setups in a single text file (JSON). You can design an entire infrastructure setup and upload it into S3, an AWS file service, and simply share the URL of the file which people can then use to build the infrastructure defined in the file.
Taken from https://aws.amazon.com/cloudformation/
The Instance Scheduler makes use of CloudFormation to create the Lambda function, create the configuration tables in DynamoDB and the CloudWatch events which will trigger the Lambda functions to execute.
Setting up AWS Instance Scheduler
The Instance Scheduler is a preconfigured setup which will allow us to easily define some times when we would like machines tagged a specific way shut-down, restarted or started. We’re going to be following the AWS documentation detailing how to setup Instance Scheduler, but straying off course to setup specific shut-down scripts:
https://docs.aws.amazon.com/solutions/latest/instance-scheduler/deployment.html
To setup Instance Scheduler, we need to install the stack by opening CloudFormation and provisioning all of the resources:
- Open CloudFormation in any region. Note that it can execute commands on instances cross-region.
- Specify the template in an Amazon S3 URL: https://s3.amazonaws.com/solutions-reference/aws-instance-scheduler/latest/instance-scheduler.template
Click next and provide a name for the Stack (the set of resources):
- Provide a tag name which will be the name of the tag applied to instances which commands are being executed against.
- Type in the regions your instances are in, comma-separated (i.e. us-west-1,us-east-1)
- Set the default timezone
- Set the SchedulerFrequency to 30 so the Lambda scripts is only executed every half-hour
- Leave all of the other configurations the same and proceed through the installer
Wait for the stack to go through and create all of the resources. You should see a SUCCESS on the stack overview:
Which means that it’s created our Lambda function, created the DynamoDB tables and setup the CloudWatch events.
Configuring the shut-down tags
The final step is to define our working hours so that we know when to shut the machines down. The configurations are stored in DynamoDB like I mentioned, which is basically a NoSQL database managed directly in the cloud.
- Open AWS DynamoDB
- Open the table with “ConfigTable” in the name
- There are some predefined “period” and “schedule” rows. Delete them all but do NOTdelete the row with type “config”
- Create a new entry with the following data:
{ "description": { "S": "Shut-down period. Daily (end of the day)." }, "endtime": { "S": "23:30" }, "name": { "S": "office-hours" }, "type": { "S": "period" }, "weekdays": { "SS": [ "mon-sun" ] } }
This is a “period” definition which is a range of time. In our case, we wanted all machines shut-down at the end of day at 11:30pm. We also give the period a name which is referenced below in the schedule.
The schedule below will stop all instances at 11:30pm every night, so that we can be sure machines aren’t running overnight unnecessarily.
{ "description": { "S": "Office hours in Canada (AST)" }, "enforced": { "S": "false" }, "name": { "S": "ca-autostop" }, "periods": { "SS": [ "office-hours" ] }, "retain_running": { "S": "false" }, "stop_new_instances": { "S": "true" }, "timezone": { "S": "Canada/Atlantic" }, "type": { "S": "schedule" } }
This is a “schedule” definition which is what we’ll tag our instances against. This schedule will shut-down machines tagged with the “ca-autostop” schedule. Note that the schedule contains the timezone information, so that we can maintain consistent working hours in our different regions. We can create multiple schedules with different timezones for all of the regions we have employees.
We can then create new schedules for our different regions and timezones, which we then can tag our EC2 instances against so the machines are shut-down at the end of the working day per region.
Tagging EC2 Instances to shut-down
We can now simply add a tag to any EC2 instances which we want to be shut-down based on the schedule and period we defined in DynamoDB.
Summary
So to summarize – every 30 minutes a CloudWatch event will be triggered which will execute a Lamda function; a serverless piece of code. That function will query the period and schedule configuration data stored in DynamoDB and depending on that data, determine if the machine(s) should be shut-down.
CloudFormation made it super easy and fast to set everything up; and the cool thing is, anyone can create CloudFormation definitions and distribute them. This is called infrastructure as code and you can read a lot more about it in the AWS documentation.