Terraform module which allow to stop and start EC2 instances, RDS resources and AutoScaling Groups by a schedule with Lambda function.
- Terraform 0.12 code style
- AWS Lambda in a pure Node.js 12
- EC2 instances scheduling
- EC2 Spot instances scheduling
- RDS instances scheduling
- AutoScaling Group scheduling
- AWS CloudWatch logs for Lambda
- Multi AWS tags support
- Pagination for more than 50 items
- RDS clusters scheduling
- CloudWatch Alarm scheduling
Spot instances have slightly different running/stopping process on AWS, so we need consider in separately.
- Amazon EC2 Spot instances can now be stopped and started similar to On-Demand instances. This feature is only available for instances with an Amazon EBS volume as their root device.
- AWS can stop instance if it has been run with persistance request, otherwise we can only terminate it.
- AWS can't stop a Spot Instance if it is part of a fleet or launch group, Availability Zone group, or Spot block. You can only terminate them.
- The stop feature is available for persistent Spot requests and Spot Fleets with the maintain fleet option enabled. You will not be charged for instance usage while your instance is stopped.
Copy and paste into your Terraform configuration, insert the variables,
and run terraform init
:
module "infra-stop-nightly" {
source = "popovserhii/lambda-scheduler/aws"
name = "${terraform.workspace}-stop-infra"
aws_regions = ["eu-central-1"]
cloudwatch_schedule_expression = "cron(0 17 ? * MON-SUN *)" # UTC
schedule_action = "stop"
spot_schedule = true
ec2_schedule = true
rds_schedule = false
autoscaling_schedule = false
cloudwatch_alarm_schedule = false
resource_tags = [
{
Key = "ToStop"
Value = "true"
},
{
Key = "Environment"
Value = terraform.workspace
}
]
}
module "infra-start-daily" {
source = "popovserhii/lambda-scheduler/aws"
name = "${terraform.workspace}-stop-infra"
aws_regions = ["eu-central-1"]
cloudwatch_schedule_expression = "cron(0 07 ? * MON-FRI *)" # UTC
schedule_action = "start"
spot_schedule = true
ec2_schedule = true
rds_schedule = false
autoscaling_schedule = false
cloudwatch_alarm_schedule = false
resource_tags = [
{
Key = "ToStop"
Value = "true"
},
{
Key = "Environment"
Value = terraform.workspace
}
]
}
NOTE: All examples stop every day from Monday to Friday at 17:00 UTC and start every day from Monday to Friday at 07:00 UTC
- AutoScaling scheduler - Create lambda functions to suspend autoscaling group
with
ToStop = true
andTestTag = <random_value>
tags and terminate its EC2 instances. - Spot scheduler - Create lambda functions to stop Spot instance with
ToStop = true
andEnvironment = test
tags. - EC2 scheduler - Create lambda functions to stop EC2 with
ToStop = true
andEnvironment = test
tags. - EC2 Bastion scheduler - Create lambda functions to stop EC2 Bastion host with
ToStop = true
andEnvironment = test
tags. - RDS MariaDB scheduler - Create lambda functions to stop RDS MariaDB with
ToStop = true
tag.
Name | Description | Type | Default | Required |
---|---|---|---|---|
name | Define name to use for lambda function, cloudwatch event and iam role | string | n/a | yes |
custom_iam_role_arn | Custom IAM role arn for the scheduling lambda | string | null | no |
kms_key_arn | The ARN for the KMS encryption key. If this configuration is not provided when environment variables are in use, AWS Lambda uses a default service key | string | null | no |
aws_regions | A list of one or more aws regions where the lambda will be apply, default use the current region | list | null | no |
cloudwatch_schedule_expression | The scheduling expression | string | "cron(0 22 ? * MON-FRI *)" |
yes |
schedule_action | Define schedule action to apply on resources | string | "stop" |
yes |
autoscaling_schedule | Enable scheduling on autoscaling resources | string | "false" |
no |
spot_schedule | Enable scheduling on spot instance resources | string | "false" |
no |
ec2_schedule | Enable scheduling on EC2 instance resources | string | "false" |
no |
rds_schedule | Enable scheduling on RDS resources | string | "false" |
no |
cloudwatch_alarm_schedule | Enable scheduleding on cloudwatch alarm resources | string | "false" |
no |
resource_tags | Set the tags use for identify resources to stop or start | map | [{ ToStop = "true" }] | yes |
Name | Description |
---|---|
lambda_iam_role_arn | The ARN of the IAM role used by Lambda function |
lambda_iam_role_name | The name of the IAM role used by Lambda function |
scheduler_lambda_arn | The ARN of the Lambda function |
scheduler_lambda_name | The name of the Lambda function |
scheduler_lambda_invoke_arn | The ARN to be used for invoking Lambda function from API Gateway |
scheduler_lambda_function_last_modified | The date Lambda function was last modified |
scheduler_lambda_function_version | Latest published version of your Lambda function |
scheduler_log_group_name | The name of the scheduler log group |
scheduler_log_group_arn | The Amazon Resource Name (ARN) specifying the log group |
These instructions will get you a copy of the project up and running on your local machine for development and testing purposes.
Clone the source locally:
$ git clone https://github.com/popovserhii/terraform-aws-lambda-scheduler
$ cd terraform-aws-lambda-scheduler
If you're on Debian or Ubuntu or Mint, you'll need to install NodeJS version not less 13:
Use your package manager to install NPM and NodeJS.
$ curl -sL https://deb.nodesource.com/setup_13.x | sudo bash -
$ sudo apt-get install -y npm nodejs
Install project dependencies:
$ npm install
At that moment only Unit tests are implemented, so you can run the tests as much as you need without bother that some resources will be created on AWS.
Unit tests are using:
- Mocha as JavaScript test framework
- Sinon for test spies, stubs and mocks
- Chai as a BDD/TDD assertion library
- AWSomocks as mocks for Javascript AWS-SDK services
Run the tests with:
$ npm test
We use SemVer for versioning. For the versions available, see the tags on this repository.
This project is licensed under the MIT
There is a library which does almost the same, but its Lambda functions are written on Python. At the moment when I was searching for a Terraform module to stop and run my infrastructure, it didn't work correctly with Spot Instances, so there was a dilemma to write an issue and wait till the maintainer fix it, or implement it by myself. The result you can see in this repository.
As I know NodeJS it was easier for me to rewrite it and improve missing parts.
Many thanks to the author who implemented this on Python for inspiration.