If your EC2 instances in AWS are managed through Auto Scaling Groups, it is easy to schedule startup and shutdown of those instances, e.g. to save money.
This tutorial walks you through setting up an AWS Lambda function that is triggered by CloudWatch Events and automatically changes the min, max and desired instances in your Auto Scaling Group(s).
The idea is to toggle between 0 (stop) and a specifed min, max and desired amount of instances (start), so you only need a single Lambda function. The premise is that you do not touch these Auto Scaling Group settings manually, or you might make your EC2 instances nocturnal.
- Open AWS Lambda in the console and click
Create a Lambda function. - On the
Select blueprintpage, selectBlank function. - On the
Configure Triggerspage, click the grey square and selectCloudWatch Events. - From the
Ruledropdown, selectCreate a new rule. - Enter a
Rule nameandRule description. - For
Rule type, selectSchedule expression. - For
Schedule expression, enter a Cron expression to specify at which day(s) and time this event should trigger.
For now only specify the event to start servers (E.g. at the beginning of the weekday). We will confire the second event later in this tutorial.
E.g.cron(00 06 ? * MON-FRI *)fires every weekday (Monday to Friday) at 6:00 AM UTC. See this website for a handy Cron calculator. - Enable the
Enable triggercheckbox. - Click
Next.
- On the
Configure functionpage, enter aNameandDescriptionfor the function. - For
Runtime, selectPython 2.7. - For
Code entry typemake sureEdit code inlineis selected. - Delete the existing code and paste the following code into the code field:
import os
import boto3
client = boto3.client('autoscaling')
def get_env_variable(var_name):
msg = "Set the %s environment variable"
try:
return os.environ[var_name]
except KeyError:
error_msg = msg % var_name
def lambda_handler(event, context):
auto_scaling_groups = get_env_variable('NAMES').split()
for group in auto_scaling_groups:
if servers_need_to_be_started(group):
action = "Starting"
min_size = int(get_env_variable('MIN_SIZE'))
max_size = int(get_env_variable('MAX_SIZE'))
desired_capacity = int(get_env_variable('DESIRED_CAPACITY'))
else:
action = "Stopping"
min_size = 0
max_size = 0
desired_capacity = 0
print action + ": " + group
response = client.update_auto_scaling_group(
AutoScalingGroupName=group,
MinSize=min_size,
MaxSize=max_size,
DesiredCapacity=desired_capacity,
)
print response
def servers_need_to_be_started(group_name):
min_group_size = get_current_min_group_size(group_name)
if min_group_size == 0:
return True
else:
return False
def get_current_min_group_size(group_name):
response = client.describe_auto_scaling_groups(
AutoScalingGroupNames=[ group_name ],
)
return response["AutoScalingGroups"][0]["MinSize"]
-
For
Environment variablesadd the following:
NAMES- Space separated list of the Auto Scaling Groups you want to manage with this function
MIN_SIZE- Minimum size of the Auto Scaling Group(s) when EC2 instances are started
MAX_SIZE- Maximum size of the Auto Scaling Group(s) when EC2 instances are started
DESIRED_CAPACITY- Desired capacity of the Auto Scaling Group(s) when EC2 instances are started -
For
Handler, make sure the value islambda_function.lambda_handler. -
For
Role, selectCreate a custom role. An IAM wizard will open in a new tab. -
For
IAM Role, selectCreate a new IAM Role. -
Enter a
Role Name. -
Click on
View Policy Documentand clickEdit. -
A warning popup will appear. Click
Ok. -
Add the following statement right after the closing } of
"Resource": "arn:aws:logs:*:*:*" }
,
{
"Effect": "Allow",
"Action": "autoscaling:*",
"Resource": "*"
}
-
Click on
Allow. -
Back on the
Configure functionscreen, make sure your new Role is selected underExisting role. -
Click on
NextandCreate Function.
- To configure the second event (to stop your servers at the end of the weekday), on the
Triggerstab of your new Lambda function, click onAdd trigger. - In the
Add triggerpopup, from theRuledropdown, selectCreate a new rule. - Enter a
Rule nameandRule description. - For
Rule type, selectSchedule expression. - For
Schedule expression, enter a Cron expression to specify at which day(s) and time this event should trigger.
E.g.cron(00 20 ? * MON-FRI *)fires every weekday (Monday to Friday) at 20:00 PM UTC. See this website for a handy Cron calculator. - Enable the
Enable triggercheckbox.
That's it, all done!
You can test the function by hitting the Test button. The first time an Input test event popup will appear.
For Sample event template select Scheduled event and click Save and test.
This tutorial on Nick Todd's blog helped me setting up this tutorial.