In my previous post, I described how to get started with auto scaling on EC2 using Cloud Watch metrics to automatically scale.
Auto scaling on a recurring schedule is another method of scaling by setting a minimum and maximum of instances at a specified time. For example you can a set a maximum number of instances to run during business hours then reduce it for outside of business hours when there is less web traffic.
Another useful use of recurring schedule auto scaling use, is for processing one time jobs. You launch instances to run a script at a specified time, then when the job has completed, the instance terminates. This is the case I’m going to cover today.
Prerequisites
Install and configure the awscli as explained in this post.
We’ll be creating our auto scaling group within EC2 classic.
Since we’ll be using an user data script, there is no need to build your own AMI as you can install and configure packages in the script.
IAM Role
As the instance needs to be able to terminate itself, create an IAM instance profile to allow the instance to authenticate and use the CLI and execute the terminate instance command:
1 |
aws iam create-instance-profile --instance-profile-name ec2_terminate |
Note the iam ARN which is returned. We’ll need it later.
Next, put in a file (/tmp/role.json) the following json statement to allow access to the EC2 service:
1 2 3 4 5 6 7 8 9 10 |
{ "Statement": [{ "Action": "sts:AssumeRole", "Principal": { "Service": "ec2.amazonaws.com" }, "Effect": "Allow", "Sid": "" }] } |
Then attached it to the role creation:
1 2 |
aws iam create-role --role-name ec2_terminate --assume-role-policy-document file:///tmp/role.json |
Finally add the role to the instance profile:
1 2 |
aws iam add-role-to-instance-profile --instance-profile-name ec2_terminate --role-name ec2_terminate |
User data script
The user data script is passed on to the EC2 instance and executes when it boots the first time.
This is where you can install packages, execute your job then the instance terminates itself. The awscli package must be installed.
1 2 3 4 5 6 7 8 9 10 11 12 |
#!/bin/bash # install the CLI if it’s not already included in the AMI apt-get install python python-pip pip install awscli # add any jobs to run here # get the instance id INSTANCE_ID=`ec2metadata --instance-id` # terminate the instance - you must specify the region aws ec2 terminate-instances --region ap-southeast-2 --instance-ids $INSTANCE_ID |
ec2metadata is Ubuntu’s package which collects EC2 information on the running instance.
Launch Configuration
Create the launch configuration specifying the user data script previously created plus the AMI, ARN, ssh key, security group and instance type:
1 2 3 4 5 6 7 |
aws autoscaling create-launch-configuration --launch-configuration-name lc-recurring --image-id ami-978916ad --iam-instance-profile arn:aws:iam::xxxxxxxx:instance-profile/ec2_terminate --key-name xxxxxxxx --security-groups sg-xxxxxxxx --instance-type m1.small --user-data file:///tmp/user-data-script.sh |
Auto Scaling Group
Create the auto scaling group, note that there must be zero instances min and max as we’re not launching any instances immediately:
1 2 3 4 5 6 |
aws autoscaling create-auto-scaling-group --auto-scaling-group-name ag-recurring --launch-configuration-name lc-recurring --min-size 0 --max-size 0 --availability-zones ap-southeast-2a --tags "Key=Name,Value=recurring-instance" |
By default the auto scaling group will replace any unhealthy (terminated) instances, disable it:
1 2 |
aws autoscaling suspend-processes --auto-scaling-group-name ag-recurring --scaling-processes ReplaceUnhealthy |
Recurring Schedule
Now specify the schedule when to launch the instance(s) using the Unix contab recurrence format (it must be in UTC timezone).
This is the scheduled group action to launch one instance everyday at 1pm UTC time:
1 2 3 4 5 6 |
aws autoscaling put-scheduled-update-group-action --scheduled-action-name start --auto-scaling-group-name ag-recurring --min-size 1 --max-size 1 --desired-capacity 1 --recurrence "0 13 * * *" |
Then at 1pm UTC time, the instance will launch, run the user data script and finally self terminate !
Check the scaling activities with:
1 |
aws autoscaling describe-scaling-activities |
Even though the instance will self terminate when the job has finished, the auto scaling group will still show min-size and max-size 1, as a consequence it will not launch an instance at the next recurrence. So we must to reset the sizes to 0 whenever the job is likely to have finished by.
This scheduled action makes sure all instances are terminated and the auto scaling group reset, every day at midnight UTC time:
1 2 3 4 5 |
aws autoscaling put-scheduled-update-group-action --scheduled-action-name cleanup --auto-scaling-group-name ag-recurring --min-size 0 --max-size 0 --recurrence "0 0 * * *" |
Recurring Schedule + Cloud Watch metrics Auto Scaling
All the recurring schedule does is adjust the min and max size of the instances in the auto scaling group. You can combine scheduled actions with traditional auto scaling using Cloud Watch metrics !
Cleanup
Delete the auto scaling group and launch configuration:
1 2 |
aws autoscaling delete-auto-scaling-group --auto-scaling-group-name ag-recurring aws autoscaling delete-launch-configuration --launch-configuration-name lc-recurring |
Notes
The instance self terminate is optional, you could skip the IAM part and just issue a shutdown command in the user data script and wait for the cleanup recurring schedule to terminate the instance.
The recent addition of the Auto Scaling Management to the Console does not support defining recurring schedule auto scaling.
This might be an old post but I found it helpful anyway. I did find that to check the scheduled activities one should use
aws autoscaling describe-scheduled-actions
rather thanaws autoscaling describe-scaling-activities
.