CLI tool
aws-solutions/instance-scheduler-on-aws avatar
aws-solutions/instance-scheduler-on-aws

Instance Scheduler on AWS: a hub stack that starts and stops EC2 and RDS across accounts

A cross-account and cross-region solution that allows customers to automatically start and stop EC2 and RDS Instances

624 stars299 forksPythonApache-2.0

At a glance

What is it?
Instance Scheduler on AWS is an AWS Solutions reference implementation, written in Python and TypeScript with CDK, that stops idle EC2 and RDS instances and starts them again on schedule across accounts and regions. The architecture is a central hub plus remote stacks, which is also its main constraint.
Who is it for?
Instance Scheduler on AWS suits an operations team that already runs multiple AWS accounts, wants idle EC2 and RDS capacity stopped on a schedule, and can accept a central hub that other accounts trust, since cross-account scheduling only works once the remote stack is deployed with a matching namespace and the same UsingAWSOrganizations value as the hub.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem is idle capacity, not scheduling complexity

Instance Scheduler on AWS automates the starting and stopping of Amazon EC2 and Amazon RDS instances, and the reason to build it is stated plainly in the README: resources that sit unused still cost money, and leaving everything running at full utilization continuously wastes that spend. The scope is deliberately narrow. It covers EC2 and RDS, it works across accounts and across regions, and it does that through CloudFormation templates rather than through an agent you install on the instances themselves. That matters for the operating model. If your instances already exist and carry tags the scheduler understands, adding the solution changes when those instances run without touching the workloads on them. If your estate is single-account, the cross-account machinery is overhead, because the hub and remote stack split exists to serve organizations where no single account can see the others.

A hub stack and one remote stack per scheduled account

The architecture is visible in the repository layout, where source/instance-scheduler holds the CDK source code, source/app holds the AWS Lambda function code and source/cli holds the Instance Scheduler CLI source. The deployment model is a two-part one. You deploy a primary control stack, which the README calls the hub, and then deploy a remote stack for cross-account scheduling. The remote deployment requires the primary control stack to exist first, and it needs credentials switched to the remote account you want to schedule. Three parameters tie a remote stack back to the hub: the account id that contains the primary control stack, the same unique namespace that was given to the primary stack, and the same value set in the primary stack for whether AWS Organizations is in use. Getting any of the three wrong is the most likely reason a spoke fails to register with the hub, and the README is explicit that the namespace must match exactly.

Deploying the hub from source with the CDK

The source deployment route needs a cloned repository, AWS CLI v2, Node.JS 22 and docker. With those in place, the hub deploys with three commands, and the order matters because the bootstrap prepares the account for CDK deployment before the stack is synthesized and sent up.

sh
npm ci
npx cdk bootstrap
npx cdk deploy instance-scheduler-on-aws

The README is explicit about what this does and does not give you. The deploy uses all default configuration settings, so after it finishes you still have to update those settings to the values you want, and the documented way to do that is to select the deployed template in the CloudFormation console and click Update, then Use Current Template. The implementation guide is the reference for what each configuration parameter is for, which matters here because the defaults are placeholder values rather than a working configuration for your account. The remote stack follows the same pattern with extra parameters.

sh
npx cdk bootstrap
npx cdk deploy instance-scheduler-on-aws-remote --parameters InstanceSchedulerAccount={account-id} --parameters Namespace={namespace} --parameters UsingAWSOrganizations={useOrgs}

The placeholders are replaced with the hub account id, the same namespace given to the hub, and the same yes or no value used there.

One-Click deploy versus publishing your own S3 assets

There are two documented ways to get the templates into an account, and they differ in who controls the assets. The one-click route launches a CloudFormation stack from the templates AWS publishes, and the implementation guide carries the step-by-step instructions. The from-GitHub route exists for teams that want to modify the solution or control the artifacts. It mimics the one-click procedure but with assets you own, and it needs two kinds of S3 bucket: one global bucket accessed over HTTPS for the CloudFormation templates, and one regional bucket per region where you plan to deploy, named after the global bucket with the region appended. The README also asks that those buckets be encrypted and have public access disallowed. The build step is a shell script in the deployment folder.

sh
cd deployment
./build-s3-dist.sh <bucketname> instance-scheduler-on-aws <version>

It takes the bucket root name, the solution name and the version, and it produces global-s3-assets and regional-s3-assets folders that you then upload under the s3://<bucket-name>/<solution-name>/<version>/<asset> pattern. The version string is yours to choose, and the README suggests matching the GitHub version with a suffix of your own.

The npm scripts hide the parameter names you will actually use

package.json shows the shape of the project tooling, and it is projen driven: the build, compile, package, deploy, destroy and test scripts all delegate to projen. Two of them are worth reading closely because they are the real interface for day two operations. The deploy:hub script sources a .env file and then runs the CDK deploy for the instance-scheduler-on-aws stack with approval turned off, passing RetainDataAndLogs from the environment and Trace from a second variable. The destroy:hub script sources the same file and destroys that stack without a confirmation prompt, and deploy:spoke does the equivalent for the remote stack. The .env.example file is where those variables come from, with RETAIN_DATA_AND_LOGS defaulting to Disabled, ENABLE_DEBUG_LOGGING set to Yes, and HUB_ACCOUNT carrying a sample account id for the spoke template. The comment in that file is worth reading rather than skipping, because it notes the default for retaining data and logs is Enabled in the template while anyone driving the deploy from the command line probably wants it disabled.

What the scheduler cannot do for you

Several constraints come out of the documentation rather than being hidden. First, the solution covers EC2 and RDS only, so anything else that consumes money on a schedule, including storage and container services, is out of scope. Second, cross-account scheduling requires deploying a remote stack into every account, switching AWS credentials to each one in turn, which is manual work by design rather than a single organization-wide toggle. Third, the local build route is described for a linux client, so the from-GitHub path is not documented for Windows or macOS machines even though the CDK route itself is not tied to that script. Fourth, the CLI is optional and does not need to be published to the global bucket for the deploy to work, so a deployment without it is a supported configuration rather than a broken one. Finally, the README does not document any rollback path for a schedule that was applied incorrectly. Turning scheduling off and correcting the underlying configuration is the practical response.

Licence, releases and what an upgrade involves

The repository is licensed under Apache-2.0 and carries a NOTICE.txt alongside the LICENSE, which is the usual pairing for an AWS Solutions project that pulls in third party components. Maintenance looks steady from the outside: the last push was on 2026-10-15 and the three most recent releases are v3.2.12 on 2026-10-15, v3.2.11 on 2026-10-06 and v3.2.10 on 2026-09-15, so this is a project on a regular patch cadence rather than an occasional refresh. Upgrading is a deployment operation, not a dependency bump. Because the hub and the remote stacks are separate CloudFormation stacks that must agree on a namespace and on the organization setting, a version bump on the hub without a matching bump on every remote stack is the failure mode to plan for. The source tree also contains a CHANGELOG.md and an update-all-dependencies.sh script, so dependency maintenance is scripted even though the runtime upgrade still runs through the deployment templates.

Editorial conclusion

Instance Scheduler on AWS suits an operations team that already runs multiple AWS accounts, wants idle EC2 and RDS capacity stopped on a schedule, and can accept a central hub that other accounts trust, since cross-account scheduling only works once the remote stack is deployed with a matching namespace and the same UsingAWSOrganizations value as the hub. It does not suit a single-account team or anyone who needs per-instance scheduling decisions beyond the maintenance windows the solution supports, because the hub owns the schedule and the accounts under it follow. Before deploying, read the implementation guide for the configuration parameters, check that the maintenance window scheduler covers the resource tags you plan to use, and confirm which instance types are excluded from automatic stopping before you enable it with the deploy:hub npm script and the RetainDataAndLogs parameter.

Frequently asked questions

What does Instance Scheduler on AWS automate?

It automates the starting and stopping of Amazon EC2 and Amazon RDS instances across accounts and regions, so resources that are not in use can be stopped and started again when they are needed.

What is the difference between the hub stack and the remote stack?

The hub is the primary control stack that holds the schedule, and a remote stack must be deployed into each additional account you want to schedule. The remote deployment needs the hub's account id, the same namespace given to the hub, and the same UsingAWSOrganizations value.

How do I deploy Instance Scheduler on AWS from source?

You need a cloned repository, AWS CLI v2, Node.JS 22 and docker, then you run npm ci, npx cdk bootstrap and npx cdk deploy instance-scheduler-on-aws. The deployment uses default settings, so you then update the configuration from the CloudFormation console using Update and Use Current Template.

Can I deploy my own build of the solution to my own S3 buckets?

Yes. You need one global bucket for the templates and one regional bucket per deployment region, named after the global bucket, and they should be encrypted with public access disallowed. You build the assets with ./build-s3-dist.sh in the deployment folder and upload the global and regional asset folders yourself.

Is the Instance Scheduler CLI required for a deployment to work?

No. The scheduler-cli is optional and does not need to be published to the global bucket for the deployment to work.

Official sources

  1. aws-solutions/instance-scheduler-on-aws on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/aws-solutions-instance-scheduler-on-aws.svg)](https://hysenlabs.com/projects/aws-solutions-instance-scheduler-on-aws)

Was this useful?