Stops and starts EC2 and RDS instances on a schedule. This can enable cost savings by stopping resources when you know they are not being used, and starting instances automatically when they will be used.
A standard use case is to stop instances outside of normal business hours.
- Customizable schedules and support for timezones
- Opt-in model, allowing users to choose appropriate schedules when provisioning resources
- Cross-account instance scheduling
- CloudWatch metrics
Clone the repo, so you have access to the code and CloudFormation deployment templates:
$ cd /tmp
$ git clone git@github.com:awslabs/aws-instance-scheduler.git
Cloning into 'aws-instance-scheduler'...
remote: Enumerating objects: 669, done.
remote: Total 669 (delta 0), reused 0 (delta 0), pack-reused 669
Receiving objects: 100% (669/669), 701.51 KiB | 3.26 MiB/s, done.
Resolving deltas: 100% (182/182), done.
$ cd aws-instance-scheduler
Define some environment variables that we can use throughout the build and deploy steps:
$ export AWS_PROFILE="vmxeng-tools"
$ export AWS_DEFAULT_REGION="us-east-1"
$ export SOLUTIONS_BUCKET_PREFIX="vmx-aws-solutions"
$ export SOLUTIONS_BUCKET_NAME="$SOLUTIONS_BUCKET_PREFIX-$AWS_DEFAULT_REGION"
$ export SOLUTION_NAME="aws-instance-scheduler"
$ export SOLUTION_VERSION="$(cat source/code/version.txt)"
$ echo $SOLUTION_VERSION
v1.3.0
You need an s3 bucket to deploy the CloudFormation template:
$ aws s3api create-bucket --bucket "$SOLUTIONS_BUCKET_NAME"
{
"Location": "/vmx-aws-solutions"
}
Build s3 assets:
$ cd deployment
$ ./build-s3-dist.sh
Please provide the base source bucket name, trademark approved solution name and version where the lambda code will eventually reside.
For example: ./build-s3-dist.sh solutions trademarked-solution-name v1.0.0
$ ./build-s3-dist.sh $SOLUTIONS_BUCKET_PREFIX $SOLUTION_NAME $SOLUTION_VERSION
Note: The build output is confusing, but if you look at the code, the 1st argument is the bucket name, the 2nd is the solution name, and the 3rd is the version string. The template automatically appends the region name to the bucket name, so I only pass in the prefix.
Note: this failed at makefile, line 57 at zip -r $(zip) pytz
because there is no folder or file called pytz
. I commented out this line to get the build the succeed
This creates two new directories in the current deployment subdirectory:
global-s3-assets
- contains copies of the CloudFormation templates, and theregional-s3-assets
- contains lambda packages for the scheduler logic and cli
$ tree .
.
├── build-s3-dist.sh
├── global-s3-assets
│ ├── instance-scheduler-remote.template
│ └── instance-scheduler.template
├── instance-scheduler-remote.template
├── instance-scheduler.template
└── regional-s3-assets
├── instance-scheduler.zip
└── scheduler-cli.zip
Copy the assets to your s3 bucket:
$ export S3_DEST="s3://$SOLUTIONS_BUCKET_NAME/$SOLUTION_NAME/$SOLUTION_VERSION/"
$ aws s3 cp global-s3-assets $S3_DEST --recursive --acl public-read
upload: global-s3-assets/instance-scheduler-remote.template ...
upload: global-s3-assets/instance-scheduler.template ...
$ aws s3 cp regional-s3-assets $S3_DEST --recursive --acl public-read
upload: regional-s3-assets/scheduler-cli.zip ...
upload: regional-s3-assets/instance-scheduler.zip ...
Create parameters.json
With minimal required params:
[
{
"ParameterKey": "Regions",
"ParameterValue": "us-east-1"
},
{
"ParameterKey": "CrossAccountRoles",
"ParameterValue": ""
},
{
"ParameterKey": "StartedTags",
"ParameterValue": ""
},
{
"ParameterKey": "StoppedTags",
"ParameterValue": ""
}
]
Note: Parameters documented in Automated Deployment, page 19
$ export TEMPLATE_URL="https://$SOLUTIONS_BUCKET_NAME.s3.amazonaws.com/$SOLUTION_NAME/$SOLUTION_VERSION/instance-scheduler.template"
$ aws cloudformation create-stack \
--stack-name "InstanceScheduler" \
--template-url $TEMPLATE_URL \
--parameters "file://./parameters.json" \
--capabilities "CAPABILITY_IAM"
{
"StackId": "arn:aws:cloudformation:us-east-1:622230865285:stack/InstanceScheduler/cce66530-58a9-11ea-9232-120022ae60fd"
}
cd source/code/cli
python setup.py install
scheduler-cli --help
I was able to get it to work with pipenv:
cd source/code/cli
pipenv install .
pipenv shell
scheduler-cli --help
# describe periods
scheduler-cli describe-periods \
--stack "InstanceSchedulerConsole" \
--region "us-east-1"
# create period for israel office
scheduler-cli create-period \
--stack "InstanceSchedulerConsole" \
--region "us-east-1" \
--name "israel-office-hours" \
--description "Office Hours in Israel" \
--weekdays "sun-thu" \
--begintime "09:00" \
--endtime "17:00"
# describe schedules
scheduler-cli describe-schedules \
--stack "InstanceSchedulerConsole" \
--region "us-east-1"
# create us west office schedule
scheduler-cli create-schedule \
--stack "InstanceSchedulerConsole" \
--region "us-east-1" \
--name "office-hours-pst" \
--description "PST Office Hours" \
--timezone "US/Pacific" \
--periods "office-hours"
# create us east office schedule
scheduler-cli create-schedule \
--stack "InstanceSchedulerConsole" \
--region "us-east-1" \
--name "office-hours-est" \
--description "EST Office Hours" \
--timezone "US/Eastern" \
--periods "office-hours"
# create central european office schedule
scheduler-cli create-schedule \
--stack "InstanceSchedulerConsole" \
--region "us-east-1" \
--name "office-hours-cet" \
--description "CET Office Hours" \
--timezone "Europe/Berlin" \
--periods "office-hours"
Create an instance in the AWS console and tag with Schedule=office-hours-pst
Refer to documentation
Refer to documentation