Many times, we have a lot of cloud waste because we never shut down our services/EC2 instances. One of the trickiest cases to control is the Auto Scaling Groups.
Now, this tutorial that is based on Vicent's one, I'm going to help you automate this task using AWS EventBridge and Lambda functions.
It's important to highlight that you must create two Lambda functions:
- One for stopping that is going to have a 0 as the environment variables (
MAX_SIZE
andDESIRED_CAPACITY
). - One for starting that is going to have 1+ as the environment variables (
MAX_SIZE
andDESIRED_CAPACITY
).
Now, the steps:
Create new Lambda function and Start Event
- Open AWS Lambda in the console and click
Create a Lambda function
. - Choose
Author from Scratch
. - Give a name like
ScheduleASStart
. - For
Runtime
, selectPython 3.9
. - Click on
Add Trigger
. - Choose
EventBridge (CloudWatch Events)
. - Click on
Create a new rule
. - Enter a
Rule name
andRule 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 configure 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. - Click on
Add
.
Configure function
- On the
Configure function
page, enter aName
andDescription
for the function. - For
Code entry type
make sureEdit code inline
is 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 variables
add 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. e.g., 0
MAX_SIZE
- Maximum size of the Auto Scaling Group(s) when EC2 instances are started. e.g., 1
DESIRED_CAPACITY
- Desired capacity of the Auto Scaling Group(s) when EC2 instances are started. e.g., 1For
Handler
, make sure the value islambda_function.lambda_handler
.For
Role
, selectCreate a custom role
. An IAM wizard will open a new tab.For
IAM Role
, selectCreate a new IAM Role
.Enter a
Role Name
.Click on
View Policy Document
and 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 function
screen, make sure your new Role is selected underExisting role
.Click on
Next
andCreate Function
.
Create Stop Event
- Create a new function like the first section.
Configure the
Environment variables
:
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. e.g., 0
MAX_SIZE
- Maximum size of the Auto Scaling Group(s) when EC2 instances are started. e.g., 0
DESIRED_CAPACITY
- Desired capacity of the Auto Scaling Group(s) when EC2 instances are started. e.g., 0Click on Add Trigger.
Choose
EventBridge (CloudWatch Events)
.Click on
Create a new rule
.Enter a
Rule name
andRule 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.Click on
Add
.
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 the Sample event template
select Scheduled event
and click Save and test
.
Acknowledgement
This tutorial on Nick Todd's blog helped me setting up this tutorial.
Top comments (2)
How to do it for multiple asg with different min max and desired capacity
You will need to modify the lambda for that and create your custom script. Most likely you will need to pass JSON values and cast them instead of env variables.