Having multiple environments is important to build a continuous integration/deployment pipeline and be able to reproduce bugs in production with ease but this comes at price. In order to reduce cost of AWS infrastructure, instances which are running 24/7 unnecessarily (sandbox & staging environments) must be shut down outside of regular business hours.
The figure below describes an automated process to schedule, stop and start instances to help cutting costs. The solution is a perfect example of using Serverless computing.
Note: full code is available on my GitHub.
2 Lambda functions will be created, they will scan all environments looking for a specific tag. The tag we use is named ‘Environment’. Instances without an Environment tag will not be affected:
The StartEnvironment function will query the StartInstances method with the list of instance ids returned by the previous function:
Similarly, the StopEnvironment function will query the StopInstances method:
Finally, both functions will post a message to Slack channel for real-time notification:
Now our functions are defined, let’s build the deployment packages (zip files) using the following Bash script:
The functions require an IAM role to be able to interact with EC2. The StartEnvironment function has to be able to describe and start EC2 instances:
The StopEnvironment function has to be able to describe and stop EC2 instances:
Finally, create an IAM role for each function and attach the above policies:
The script will output the ARN for each IAM role:
Before jumping to deployment part, we need to create a Slack WebHook to be able to post messages to Slack channel:
Next, use the following script to deploy your functions to AWS Lambda (make sure to replace the IAM roles, Slack WebHook token & the target environment):
Once deployed, if you sign in to AWS Management Console, navigate to Lambda Console, you should see both functions has been deployed successfully:
To further automate the process of invoking the Lambda function at the right time. AWS CloudWatch Scheduled Events will be used.
Create a new CloudWatch rule with the below cron expression (It will be invoked everyday at 9 AM):
And another rule to stop the environment at 6 PM:
Note: All times are GMT time.
a — Stop Environment
b — Start Environment
The solution is easy to deploy and can help reduce operational costs.