The Instance Scheduler on AWS solution is an automated solution that schedules Amazon Elastic Compute Cloud (Amazon EC2) and Amazon Relational Database Service (Amazon RDS) instances. The solution enables customers to easily configure custom start and stop schedules for their instances, helping to reduce costs and ensure instances are running only when needed. Deployed centrally within an account, the orchestrator
You can find more information about the solution in the AWS Solutions Implementation Guide.
-
Cross-account instance scheduling : This solution includes a template that creates the AWS Identity and Access Management (IAM) roles necessary to start and stop instances in secondary accounts. For more information, refer to the Cross-account instance scheduling section.
-
Automated Tagging: Instance Scheduler on AWS can automatically add tags to all instances that it starts or stops. The solution also includes macros that allow you to add variable information to the tags.
-
Configure schedules or periods using Scheduler CLI: This solution includes a command line interface (CLI) that provides commands for configuring schedules and periods. The CLI allows customers to estimate cost savings for a given schedule. For more information, refer to the Scheduler CLI.
-
Manage schedules using Infrastructure as Code (IaC): This solution provides an AWS CloudFormation Custom Resource that you can use to manage schedules using Infrastructure as Code (IaC). For more information, refer to Manage Schedules Using Infrastructure as Code.
-
Integration with Systems Manager Maintenance Windows: For Amazon EC2 instances, Instance Scheduler on AWS can integrate with AWS Systems Manager maintenance windows, defined in the same Region as those instances, to start and stop them in accordance with the maintenance window.
-
Integration with Service Catalog AppRegistry and Application Manager, a capability of AWS Systems Manager: This solution includes a Service Catalog AppRegistry resource to register the solution's CloudFormation template and its underlying resources as an application in both Service Catalog AppRegistry and Application Manager. With this integration, you can centrally manage the solution's resources.
The following provides an example of how to use the module,
- Firstly we must deploy the orchestrator within the central account.
- Next we can use a stackset, or stack to deploy the resources to the target accounts (spokes).
- Ensure the resources in the account was tagged with the
var.scheduler_tag_nameand the value points to a known schedule definition.
You can use the following example to deploy the scheduler,
locals {
tags = {
"Environment" = "Development"
"Owner" = "Solutions"
"Product" = "LandingZone"
"Provisioner" = "Terraform"
"GitRepo" = "https://github.com/appvia/terraform-aws-instance-scheduler"
}
}
module "scheduler" {
source = "github.com/appvia/terraform-aws-instance-scheduler//modules/scheduler?ref=main"
enable_asg_scheduler = true
enable_cloudwatch_dashboard = false
enable_cloudwatch_debug_logging = false
enable_docdb_scheduler = true
enable_ec2_scheduler = true
enable_hub_account_scheduler = false
enable_neptune_scheduler = false
enable_organizations = true
enable_rds_cluster_scheduler = true
enable_rds_scheduler = true
enable_rds_snapshot = false
enable_scheduler = true
tags = local.tags
## The regions that the scheduler will manage resources in
scheduler_regions = ["eu-west-2"]
## The tag placed on the resources that the scheduler will manage
## the lifecycle for based on the schedules and periods defined
scheduler_tag_name = "Schedule"
## Is the interval in minutes that the scheduler will check for resources
## that need to be started or stopped
scheduler_frequency = 5
## The organizations id that are permitted to use the scheduler - you can
## this detail in the AWS Organizations console
scheduler_organizations_ids = ["o-7enwqkxxxx"]
}The spoke module can be used to deploy the resources to the target accounts, and thus enabling them to be managed by the scheduler. Once the spoke has been deployed, it will register the account with the scheduler and the resources will be managed based on the schedules and periods defined. Currently two modules are supported for the deployment, stackset or individual stack.
To deploy to multiple accounts, you can use the stackset module. The following example demonstrates how to deploy the spoke using var.enable_stackset;
module "stackset_spoke" {
source = "github.com/appvia/terraform-aws-instance-scheduler//modules/spoke?ref=main"
enable_organizations = true
enable_standalone = false
enable_stackset = true
region = "eu-west-2"
scheduler_account_id = "123456789012"
tags = local.tags
organizational_units = {
"infrastructure" = "ou-123456789012"
"development" = "ou-123456789013"
}
}To deploy to a single account, you can use the standalone module. The following example demonstrates how to deploy the spoke using var.enable_standalone;
module "stackset_spoke" {
source = "github.com/appvia/terraform-aws-instance-scheduler//modules/spoke?ref=main"
enable_organizations = true
enable_standalone = true
scheduler_account_id = "123456789012"
tags = local.tags
organizational_units = {
"infrastructure" = "ou-123456789012"
"development" = "ou-123456789013"
}
}The Instance Scheduler provides a python CLI to manage the schedules and periods. The following example demonstrates how to configure the schedules and periods using the config module, and define them as IaC. This definition would be place into the same codebase as the scheduler definition, as it uses the output from the module.
module "config" {
source = "github.com/appvia/terraform-aws-instance-scheduler//modules/spoke?ref=main"
dyanmodb_table_name = module.scheduler.scheduler_dynamodb_table
periods = {
"uk_working_hours" = {
description = "UK Working Hours"
start_time = "06:00"
end_time = "19:30"
weekdays = ["mon-fri"]
}
}
schedules = {
"uk_working_hours" = {
description = "Resources will run during the UK working hours, anything outside of this will be stopped"
periods = ["uk_working_hours"]
}
}
depends_on = [
module.scheduler
]
}For a complete operational understanding of the Instance Scheduler please refer to AWS Instance Scheduler implementation guide, but essentially for the resources under scope for scheduler, it will discovery those whom have the var.scheduler_tag_name tag, and use the value of this tag as a lookup in the schedules defined in the configuration. If will then take the appropriate action/s based on the schedule. For resources NOT tagged with the var.scheduler_tag_name, these will be ignored from the scheduling process all together.
While we have enforcement of tagging at the IAM boundary level, and service control policies, we found it difficult to enforce these across the board for various reasons, so we ended up adding a tagging module to help.
The following example demonstrates how to enforce tagging, using a set of lambda functions which on interval will discovery the resources in the account, filtering where configured, and tagging the rest with the appropriate schedule tags.
module "tagging" {
source = "../../"
## The tag name
scheduled_tag_name = "Schedule"
## The default tag value
scheduled_tag_value = "uk_office_hours"
## Cron for every 15 minutes
schedule = "rate(15 minutes)"
## Enable tagging for the following resources
enable_autoscaling = true
enable_ec2 = true
enable_rds = true
autoscaling = {
# Override the default schedule
schedule = "rate(1 hour)"
}
rds = {
# Override the default schedule
schedule = "rate(1 hour)"
}
}The current cloudformation templates provided by AWS do not come with tagging enabled on the resources. In order to injects tags into the all the resources provisioned via the solution we are using a Cloudformation Transform Macro. This is essentially a lambda called by the cloudformation service, passing the template and used to inject the tags.
You can enable the feature as such
module "scheduler" {
source = "../modules/scheduler"
...
enable_cloudformation_macro = true
tags = var.tags
}The terraform-docs utility is used to generate this README. Follow the below steps to update:
- Make changes to the
.terraform-docs.ymlfile - Fetch the
terraform-docsbinary (https://terraform-docs.io/user-guide/installation/) - Run
terraform-docs markdown table --output-file ${PWD}/README.md --output-mode inject .
No providers.
No inputs.
No outputs.
